zoukankan      html  css  js  c++  java
  • 【原创】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)进行图片数据库已经不能满足所有需求,因此在获取图片真实路径的时候需要根据不同类型区分对待。
     

    作者:Nodin
    出处:http://www.cnblogs.com/monodin
    个人博客网站:http://www.coderself.com
    关于作者:爱摄影,爱旅行,爱自由,爱生活,更要爱自己。活在当下,也在为未来打拼!
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

  • 相关阅读:
    1000F.One Ocurrence(可持久化线段树+思维)
    P2184.贪婪大陆(思维+树状数组)
    438D.The Child and Sequence(线段树+取模性质)
    P2894 [USACO08FEB]Hotel G(线段树维护区间子串)
    620E New Year Tree(线段树维护状压)
    P6492 [COCI2010-2011#6] STEP(线段树维护最长子串)
    242E.XOR on segment(线段树维护区间异或)
    1527D.MEX Tree(树上分类讨论+容斥)
    解决for循环中写异步函数,异步函数中输出下标一样问题
    vue拦截器
  • 原文地址:https://www.cnblogs.com/monodin/p/3993873.html
Copyright © 2011-2022 走看看