在android開發中, 在一些編輯個人信息的時候,經常會有頭像這么一個東西,就兩個方面,調用系統相機拍照,調用系統圖庫獲取圖片.但是往往會遇到各種問題:
1.oom
2.圖片方向不對
3.activity result 的時候data == null
4.調用圖庫的時候沒找到軟件
嘿嘿..開代碼:
首先是調用系統拍照,和圖庫的代碼
package com.chzh.fitter.util;
import java.io.File;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.widget.Toast;
//在onActivityResult方法中根據requestCode和resultCode來獲取當前拍照的圖片地址。
//注意:這里有個問題,在有些機型當中(如SamsungI939、note2等)遇見了當拍照並存儲之后,intent當中得到的data為空:
/**
* data = null 的情況主要是由於拍照的時候橫屏了,導致重新create, 普通的解決方法可以在sharedpreference里面保存拍照文件的路徑(onSaveInstance保存),
* 在onRestoreSaveInstance里面在獲取出來.
* 最簡單的可以用fileUtil 里面的一個靜態變量保存起來..
* */
public class CameraUtil {
private static final String IMAGE_TYPE = "image/*";
private Context mContext;
public CameraUtil(Context context) {
mContext = context;
}
/**
* 打開照相機
* @param activity 當前的activity
* @param requestCode 拍照成功時activity forResult 的時候的requestCode
* @param photoFile 拍照完畢時,圖片保存的位置
*/
public void openCamera(Activity activity, int requestCode, File photoFile) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
activity.startActivityForResult(intent, requestCode);
}
/**
* 本地照片調用
* @param activity
* @param requestCode
*/
public void openPhotos(Activity activity, int requestCode) {
if (openPhotosNormal(activity, requestCode) && openPhotosBrowser(activity, requestCode) && openPhotosFinally());
}
/**
* PopupMenu打開本地相冊.
*/
private boolean openPhotosNormal(Activity activity, int actResultCode) {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
IMAGE_TYPE);
try {
activity.startActivityForResult(intent, actResultCode);
} catch (android.content.ActivityNotFoundException e) {
return true;
}
return false;
}
/**
* 打開其他的一文件瀏覽器,如果沒有本地相冊的話
*/
private boolean openPhotosBrowser(Activity activity, int requestCode) {
Toast.makeText(mContext, "沒有相冊軟件,運行文件瀏覽器", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT"
intent.setType(IMAGE_TYPE); // 查看類型 String IMAGE_UNSPECIFIED =
// "image/*";
Intent wrapperIntent = Intent.createChooser(intent, null);
try {
activity.startActivityForResult(wrapperIntent, requestCode);
} catch (android.content.ActivityNotFoundException e1) {
return true;
}
return false;
}
/**
* 這個是找不到相關的圖片瀏覽器,或者相冊
*/
private boolean openPhotosFinally() {
Toast.makeText(mContext, "您的系統沒有文件瀏覽器或則相冊支持,請安裝!", Toast.LENGTH_LONG).show();
return false;
}
/**
* 獲取從本地圖庫返回來的時候的URI解析出來的文件路徑
* @return
*/
public static String getPhotoPathByLocalUri(Context context, Intent data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
return picturePath;
}
}
接下來是解決oom的
package com.chzh.fitter.util;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.ExifInterface;
import android.net.Uri;
import android.util.Log;
import android.widget.ImageView;
import com.androidquery.util.AQUtility;
/**
* @author jarrahwu
*
*/
public class ImageUtil {
/**
* Utility method for downsampling images.
*
* @param path
* the file path
* @param data
* if file path is null, provide the image data directly
* @param target
* the target dimension
* @param isWidth
* use width as target, otherwise use the higher value of height
* or width
* @param round
* corner radius
* @return the resized image
*/
public static Bitmap getResizedImage(String path, byte[] data, int target,
boolean isWidth, int round) {
Options options = null;
if (target > 0) {
Options info = new Options();
info.inJustDecodeBounds = true;
//設置這兩個屬性可以減少內存損耗
info.inInputShareable = true;
info.inPurgeable = true;
decode(path, data, info);
int dim = info.outWidth;
if (!isWidth)
dim = Math.max(dim, info.outHeight);
int ssize = sampleSize(dim, target);
options = new Options();
options.inSampleSize = ssize;
}
Bitmap bm = null;
try {
bm = decode(path, data, options);
} catch (OutOfMemoryError e) {
L.red(e.toString());
e.printStackTrace();
}
if (round > 0) {
bm = getRoundedCornerBitmap(bm, round);
}
return bm;
}
private static Bitmap decode(String path, byte[] data,
BitmapFactory.Options options) {
Bitmap result = null;
if (path != null) {
result = decodeFile(path, options);
} else if (data != null) {
// AQUtility.debug("decoding byte[]");
result = BitmapFactory.decodeByteArray(data, 0, data.length,
options);
}
if (result == null && options != null && !options.inJustDecodeBounds) {
AQUtility.debug("decode image failed", path);
}
return result;
}
private static Bitmap decodeFile(String path, BitmapFactory.Options options) {
Bitmap result = null;
if (options == null) {
options = new Options();
}
options.inInputShareable = true;
options.inPurgeable = true;
FileInputStream fis = null;
try {
fis = new FileInputStream(path);
FileDescriptor fd = fis.getFD();
// AQUtility.debug("decoding file");
// AQUtility.time("decode file");
result = BitmapFactory.decodeFileDescriptor(fd, null, options);
// AQUtility.timeEnd("decode file", 0);
} catch (IOException e) {
Log.error("TAG",e.toString())
} finally {
fis.close()
}
return result;
}
private static int sampleSize(int width, int target) {
int result = 1;
for (int i = 0; i < 10; i++) {
if (width < target * 2) {
break;
}
width = width / 2;
result = result * 2;
}
return result;
}
/**
* 獲取圓角的bitmap
* @param bitmap
* @param pixels
* @return
*/
private static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
/**
* auto fix the imageOrientation
* @param bm source
* @param iv imageView if set invloke it's setImageBitmap() otherwise do nothing
* @param uri image Uri if null user path
* @param path image path if null use uri
*/
public static Bitmap autoFixOrientation(Bitmap bm, ImageView iv, Uri uri,String path) {
int deg = 0;
try {
ExifInterface exif = null;
if (uri == null) {
exif = new ExifInterface(path);
}
else if (path == null) {
exif = new ExifInterface(uri.getPath());
}
if (exif == null) {
Log.error("TAG","exif is null check your uri or path");
return bm;
}
String rotate = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int rotateValue = Integer.parseInt(rotate);
System.out.println("orientetion : " + rotateValue);
switch (rotateValue) {
case ExifInterface.ORIENTATION_ROTATE_90:
deg = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
deg = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
deg = 270;
break;
default:
deg = 0;
break;
}
} catch (Exception ee) {
Log.d("catch img error", "return");
if(iv != null)
iv.setImageBitmap(bm);
return bm;
}
Matrix m = new Matrix();
m.preRotate(deg);
bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true);
//bm = Compress(bm, 75);
if(iv != null)
iv.setImageBitmap(bm);
return bm;
}
}
如果想要代碼Demo的話,可以留言.有什么坑爹的地方,多多拍磚..over.
