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(二)数据存储和访问 之文件
  2. Android(安卓)RadioButton背景图片和文字的相对位置
  3. 抽离Android原生控件的方法
  4. Android中高效的显示图片之一 ——加载大图
  5. 抽离Android原生控件的方法
  6. Android用户界面 UI组件--ImageView及其子类ImageButton,QuickCo
  7. 界面编程之基本界面组件(7)ImageView(图像视图)
  8. TextView使用完全讲解
  9. 华为android 10 手机恢复删除的图片,目前只能恢复小图。

随机推荐

  1. Android预定义样式
  2. Android(安卓)最火快速开发框架AndroidAn
  3. Mac 下完全卸载Android(安卓)Studio 和SD
  4. android 闪光灯控制
  5. android 常用api 接口签名验证
  6. android apache HTTP demo 互联网访问
  7. Android(安卓)横竖屏幕
  8. android sdk
  9. 【移动开发】Android中各种xml汇总
  10. 增加Android可用内存