您的位置:首页 > 移动开发 > Android开发

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

2016-06-12 16:22 633 查看
本文讲述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)进行图片数据库已经不能满足所有需求,因此在获取图片真实路径的时候需要根据不同类型区分对待。

 

其实,有一种更为Simple&Lazy的方式,就是通过数据库查询时指定图片id,更为精确的查询图片。

1 // TODO 从Uri中读取图片id,如:/document/image/18838,   /external/images/media/14046
2 // String id = ...
3 // ......
4
5 String selection = MediaColumns._ID + " = ?";
6 String[] selectionArgs = new String{ id };
7
8 Uri queryUri = "content://media/external/images/media";
9 String fileName = getDataColumns(context, queryUri, selection, selectionArgs );


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 摘录 学习