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

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 for

34      * MediaStore Uris , and other file - based ContentProviders.

35      * 

36      * @param context

37      *            The context.

38      * @param uri

39      *            The Uri to query.

40      * @param selection

41      *            (Optional) Filter used in the query.

42      * @param selectionArgs

43      *            (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 uri

106      *            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(uri

111                 .getAuthority());

112     }

113 

114     /**

115      * @param uri

116      *            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(uri

121                 .getAuthority());

122     }

123 

124     /**

125      * @param uri

126      *            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(uri

131                 .getAuthority());

132     }

133 

134     /**

135      * @param uri

136      *            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(uri

141                 .getAuthority());

142     }

 

为什么会不一样呢?

Android 4.4(含)开始,通过方式访问图库后,返回的Uri如下(访问“最近”):
1 Uri is:         content://com.android.providers.media.documents/document/image%3A18838

2 Uri.getPath is :/document/image:18838

3 对应的图片真实路径:/storage/emulated/0/Pictures/Screenshots/Screenshot_2014-09-22-21-40-53.png

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

1 Uri is:         content://media/external/images/media/18822

2 Uri.getPath is :/external/images/media/18822

3 对应的图片真实路径:/storage/emulated/0/Download/20130224235013.jpg

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

1 Uri is:         content://media/external/images/media/14046

2 Uri.getPath is :/external/images/media/14046

3 对应的图片真实路径:/storage/emulated/0/DCIM/Camera/20130224235013.jpg

 

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

你可能感兴趣的:(android)