从图库选择图片的方式大家都不陌生:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);//ACTION_OPEN_DOCUMENT
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/jpeg");
startActivityForResult(intent, SELECT_PIC);
自从Android4.4系统出来之后,从图库选择图片的界面跟4.4之前不一样了,如果继续使用这种方式会出现图片路径找不到的错误,后来发现,4.4以上图库选择图片的时候返回的Uri的格式和4.4之前的不大一样,
content:
//com.android.providers.media.documents/document/image:3951
content:
//media/external/images/media/3951
从最近文档中选择的图片是个缓存,里面并没有图片的真实路径,因此在从图库选择图片的时候要分别进行处理:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);//ACTION_OPEN_DOCUMENT
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/jpeg");
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
startActivityForResult(intent, SELECT_PIC_KITKAT);
} else {
startActivityForResult(intent, SELECT_PIC_NORMAL);
}
在OnActivityResult方法中根据返回的参数分别进行处理:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
selectBitmap = null;
String picturePath = null;
//4.4以下的情况
if (requestCode == SELECT_PIC_NORMAL && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
if (selectedImage != null) {
String uriStr = selectedImage.toString();
String path = uriStr.substring(10, uriStr.length());
if (path.startsWith("com.sec.android.gallery3d")) {
Log.e("It's auto backup pic path:", selectedImage.toString());
}
}
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = mContext.getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
picturePath = cursor.getString(columnIndex);
cursor.close();
} else if (requestCode == SELECT_PIC_KITKAT && resultCode == RESULT_OK && null != data) {
//4.4系统以上情况 获取图片的真实路径
picturePath = getPath(mContext, data.getData());
} else {
CropImageActivity.this.finish();
}
try {
selectBitmap = BitmapFactory.decodeFile(picturePath);
if (!selectBitmap.equals(null))
cropImageView.setImageBitmap(selectBitmap);
else
{
Toast.makeText(CropImageActivity.this, "图片加载失败", Toast.LENGTH_SHORT).show();
MainActivity.this.finish();
}
} catch (Exception e) {
MainActivity.this.finish();
}
}
URI处理:
/**
* 4.4系统以上图库选择图片 返回路径处理
*
* @param context
* @param uri
* @return
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
*/
public static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
这样就能使用4.4选择图片的效果又不会出错啦。