4.4之后的版本从相册中获取图片显示到Imageview上的实现
安卓4.4以后,从相册中获取图片返回的Uri发生了改变,所以要针对不同的情况进行适配了。
1.打开相册的代码块
/**
* 打开相册
*/
public void openAbulm() {
Intent intent = new Intent("android.intent.action.GET_CONTENT");
intent.setType("image/*");
startActivityForResult(intent, CHOOSE_PHOTO);
}
属于隐式意图打开,由于我们需要从相册中获取选择的照片,所以这里要使用startActivityForResult(intent, CHOOSE_PHOTO)这个方法。
之后我们在MainActivity中重写
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case CHOOSE_PHOTO:
if (resultCode ==RESULT_OK) {
String path = getPath(getApplicationContext(), data.getData());
bitmap = getBitmap(path);
iv.setImageBitmap(bitmap);
}
break;
default:
break;
}
根据返回码的不同来确定执行哪一段逻辑。
由于有些照片的尺寸过大,如果不压缩处理,就会造成内存溢出。
/**
* 获取小尺寸的照片
* @param filePath 压缩照片的路径
* @return 返回压缩处理后的照片
*/
public static Bitmap getBitmap(String filePath) {
Bitmap bitmap = null;
Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
options.inSampleSize = Math.max(1, (int) Math.ceil(Math.max(
(double) options.outWidth / 1024f,
(double) options.outHeight / 1024f)));
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(filePath, options);
return bitmap;
}
接下来就是最关键的部分代码,对于返回不同的Uri进行解析:
@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;
// 文件提供
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// 外部存储设备提供
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
}
// 下载文件提供
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);
}
// 媒体提供
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 = MediaColumns._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.
*
* @param context
* The context.
* @param uri
* The Uri to query.
* @param selection
* (Optional) Filter used in the query.
* @param selectionArgs
* (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
public static String getDataColumn(Context context, Uri uri,
String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = MediaColumns.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());
}
在使用这段代码前,请在Eclipse中在project.properties文件中将API改为19以上否则会报错。
最后记得加上权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
最后效果如下图:
我们可以看到成功的将图片显示到了imageview上面去了。
因为之前笔者在写这方面相关应用的时候,也遇到了这样子的问题,后来在网上搜集资料,找到了前辈的写的代码,然后就把这些写了过来,大家一起学习。
最后是demo打包下载的地址:
http://download.csdn.net/detail/jw804022023/9674133