Android 4.4前后版本读取图库图片方式的变化

本文讲述Android 4.4(KitKat)前后访问图库以及访问后通过图片路径读取图片的变化

Android 4.4(KitKat)以前:

访问图库(方法一):
1      /**2      * Access the gallery to pick up an image. 3      */4      private   void  startPickPhotoActivity() {5         Intent intent =  new  Intent(Intent. ACTION_GET_CONTENT );6         intent.setType( "image/*" ); // Or 'image/ jpeg '7         startActivityForResult(intent,  RESULT_PICK_PHOTO_NORMAL );8     }

访问图库(方法二):

1      /**2      * Access the gallery to pick up an image. 3      */4      private   void  startPickPhotoActivity() {5         Intent intent =  new  Intent(Intent. ACTION_GET_CONTENT );6         intent.setType( "image/*" ); // Or 'image/ jpeg '7         Intent wrapperIntent = Intent. createChooser (intent,  null );8         startActivityForResult(wrapperIntent,  RESULT_PICK_PHOTO_NORMAL );9      }

获取文件路径&读取图片:
 1     @Override 2     protected void onActivityResult(int requestCode, int resultCode, Intent data) { 3         if (requestCode == RESULT_PICK_PHOTO_NORMAL) { 4             if (resultCode == RESULT_OK && data != null) { 5                 mFileName = DemoUtils.getDataColumn(getApplicationContext(), 6                         data.getData(), null, null); 7                 mColorBitmap = DemoUtils.getBitmap(mFileName); 8  9                 mImage.setImageBitmap(mColorBitmap);10             }11         }12     }13 14     public static final Bitmap getBitmap(String fileName) {15         Bitmap bitmap = null;16         try {17             Options options = new Options();18             options.inJustDecodeBounds = true;19             BitmapFactory.decodeFile(fileName, options);20             options.inSampleSize = Math.max(1, (int) Math.ceil(Math.max(21                     (double) options.outWidth / 1024f,22                     (double) options.outHeight / 1024f)));23             options.inJustDecodeBounds = false;24             bitmap = BitmapFactory.decodeFile(fileName, options);25         } catch (OutOfMemoryError error) {26             error.printStackTrace();27         }28 29         return bitmap;30     }31 32     /**33      * Get the value of the data column for this Uri . This is useful for34      * MediaStore Uris , and other file - based ContentProviders.35      * 36      * @param context37      *            The context.38      * @param uri39      *            The Uri to query.40      * @param selection41      *            (Optional) Filter used in the query.42      * @param selectionArgs43      *            (Optional) Selection arguments used in the query.44      * @return The value of the _data column, which is typically a file path.45      */46     public static String getDataColumn(Context context, Uri uri,47             String selection, String[] selectionArgs) {48         Cursor cursor = null;49         final String column = MediaColumns.DATA;50         final String[] projection = { column };51         try {52             cursor = context.getContentResolver().query(uri, projection,53                     selection, selectionArgs, null);54             if (cursor != null && cursor.moveToFirst()) {55                 final int index = cursor.getColumnIndexOrThrow(column);56                 return cursor.getString(index);57             }58         } finally {59             if (cursor != null)60                 cursor.close();61         }62         return null;63     }

Android 4.4(KitKat)及以后:

访问图库(方法一):同上方法一 访问图库(方法二):同上方法二 访问图库(方法三):
1      /**2      * Access the gallery to pick up an image. 3      */4      @TargetApi (Build.VERSION_CODES. KITKAT )5      private   void  startPickPhotoActivity() {6         Intent intent =  new  Intent(Intent. ACTION_OPEN_DOCUMENT );7         intent.setType( "image/*" ); // Or 'image/ jpeg '8         startActivityForResult(intent,  RESULT_PICK_PHOTO_NORMAL );9     }

获取文件路径&读取图片:
  1     @Override  2     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  3         if (requestCode == RESULT_PICK_PHOTO_KITKAT) {  4             if (resultCode == RESULT_OK && data != null) {  5                 mFileName = DemoUtils.getPath(getApplicationContext(),  6                         data.getData());  7                 mColorBitmap = DemoUtils.getBitmap(mFileName);  8   9                 mImage.setImageBitmap(mColorBitmap); 10             } 11         } 12     } 13  14     @TargetApi(Build.VERSION_CODES.KITKAT) 15     public static String getPath(final Context context, final Uri uri) { 16         final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; 17         // DocumentProvider 18         if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { 19             // ExternalStorageProvider 20             if (isExternalStorageDocument(uri)) { 21                 final String docId = DocumentsContract.getDocumentId(uri); 22                 final String[] split = docId.split(":"); 23                 final String type = split[0]; 24                 if ("primary".equalsIgnoreCase(type)) { 25                     return Environment.getExternalStorageDirectory() + "/" 26                             + split[1]; 27                 } 28                 // TODO handle non-primary volumes 29             } 30             // DownloadsProvider 31             else if (isDownloadsDocument(uri)) { 32                 final String id = DocumentsContract.getDocumentId(uri); 33                 final Uri contentUri = ContentUris.withAppendedId( 34                         Uri.parse("content://downloads/public_downloads"), 35                         Long.valueOf(id)); 36                 return getDataColumn(context, contentUri, null, null); 37             } 38             // MediaProvider 39             else if (isMediaDocument(uri)) { 40                 final String docId = DocumentsContract.getDocumentId(uri); 41                 final String[] split = docId.split(":"); 42                 final String type = split[0]; 43                 Uri contentUri = null; 44                 if ("image".equals(type)) { 45                     contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 46                 } else if ("video".equals(type)) { 47                     contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 48                 } else if ("audio".equals(type)) { 49                     contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 50                 } 51                 final String selection = MediaColumns._ID + "=?"; 52                 final String[] selectionArgs = new String[] { split[1] }; 53                 return getDataColumn(context, contentUri, selection, 54                         selectionArgs); 55             } 56         } 57         // MediaStore (and general) 58         else if ("content".equalsIgnoreCase(uri.getScheme())) { 59             // Return the remote address 60             if (isGooglePhotosUri(uri)) 61                 return uri.getLastPathSegment(); 62             return getDataColumn(context, uri, null, null); 63         } 64         // File 65         else if ("file".equalsIgnoreCase(uri.getScheme())) { 66             return uri.getPath(); 67         } 68         return null; 69     } 70  71     /** 72      * Get the value of the data column for this Uri . This is useful for 73      * MediaStore Uris , and other file - based ContentProviders. 74      *  75      * @param context 76      *            The context. 77      * @param uri 78      *            The Uri to query. 79      * @param selection 80      *            (Optional) Filter used in the query. 81      * @param selectionArgs 82      *            (Optional) Selection arguments used in the query. 83      * @return The value of the _data column, which is typically a file path. 84      */ 85     public static String getDataColumn(Context context, Uri uri, 86             String selection, String[] selectionArgs) { 87         Cursor cursor = null; 88         final String column = MediaColumns.DATA; 89         final String[] projection = { column }; 90         try { 91             cursor = context.getContentResolver().query(uri, projection, 92                     selection, selectionArgs, null); 93             if (cursor != null && cursor.moveToFirst()) { 94                 final int index = cursor.getColumnIndexOrThrow(column); 95                 return cursor.getString(index); 96             } 97         } finally { 98             if (cursor != null) 99                 cursor.close();100         }101         return null;102     }103 104     /**105      * @param uri106      *            The Uri to check.107      * @return Whether the Uri authority is ExternalStorageProvider.108      */109     public static boolean isExternalStorageDocument(Uri uri) {110         return "com.android.externalstorage.documents".equals(uri111                 .getAuthority());112     }113 114     /**115      * @param uri116      *            The Uri to check.117      * @return Whether the Uri authority is DownloadsProvider.118      */119     public static boolean isDownloadsDocument(Uri uri) {120         return "com.android.providers.downloads.documents".equals(uri121                 .getAuthority());122     }123 124     /**125      * @param uri126      *            The Uri to check.127      * @return Whether the Uri authority is MediaProvider.128      */129     public static boolean isMediaDocument(Uri uri) {130         return "com.android.providers.media.documents".equals(uri131                 .getAuthority());132     }133 134     /**135      * @param uri136      *            The Uri to check.137      * @return Whether the Uri authority is Google Photos.138      */139     public static boolean isGooglePhotosUri(Uri uri) {140         return "com.google.android.apps.photos.content".equals(uri141                 .getAuthority());142     }

为什么会不一样呢?

Android 4.4(含)开始,通过方式访问图库后,返回的Uri如下(访问“最近”):
1 Uri is:         content://com.android.providers.media.documents/document/image%3A188382 Uri.getPath is :/document/image:188383 对应的图片真实路径:/storage/emulated/0/Pictures/Screenshots/Screenshot_2014-09-22-21-40-53.png

不但如此,对于不同类型图库,返回的Uri形式并不相同(访问普通相册):

1 Uri is:         content://media/external/images/media/188222 Uri.getPath is :/external/images/media/188223 对应的图片真实路径:/storage/emulated/0/Download/20130224235013.jpg

而4.4之前返回的Uri只存在一种形式,如下:

1 Uri is:         content://media/external/images/media/140462 Uri.getPath is :/external/images/media/140463 对应的图片真实路径:/storage/emulated/0/DCIM/Camera/20130224235013.jpg

因此,在Android 4.4或更高版本设备上,通过简单的getDataColumn(Context, Uri, null, null)进行图片数据库已经不能满足所有需求,因此在获取图片真实路径的时候需要根据不同类型区分对待。

更多相关文章

  1. Android RadioButton背景图片和文字的相对位置
  2. Android中高效的显示图片之一 ——加载大图
  3. 华为android 10 手机恢复删除的图片,目前只能恢复小图。
  4. 设置提示信息,输入值类型,输入框引入图片,设置输入框的形状
  5. eclipse android开发环境 bug CDT包含路径名无法修改(JNI开发使用
  6. Android获取存储设备挂载路径
  7. 从Android读取Unity assets下的图片并保存为Bitmap格式
  8. 开机动画(闪动的ANDROID字样的动画图片)
  9. Android实现局部图片滑动指引效果

随机推荐

  1. Android学习笔记——网络技术
  2. AndroidKotLin系列--Android(安卓)Studio
  3. Android--SQLite数据库应用技巧分享
  4. Android(安卓)应用跳转到指定QQ临时聊天
  5. Android(安卓)各种杀脑细胞的问题集合
  6. Android(安卓)传统蓝牙配对连接断开 附de
  7. Android默认输入法语言的修改以及Setting
  8. android 中的 ViewFlipper 的简单使用
  9. Android(安卓)自定义时间轴
  10. :用i-jetty把web项目发布到Android手机上