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
    关于作者:爱摄影,爱旅行,爱自由,爱生活,更要爱自己。活在当下,也在为未来打拼!
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

  • 相关阅读:
    Azkaban的使用
    Azkaban安装
    Kafka 启动失败,报错Corrupt index found以及org.apache.kafka.common.protocol.types.SchemaException: Error reading field 'version': java.nio.BufferUnderflowException
    Kafka 消费者设置分区策略及原理
    Kafka利用Java API自定义生产者,消费者,拦截器,分区器等组件
    zookeeper群起总是有那么几个节点起不来的问题解决
    flume 启动agent报No appenders could be found for logger的解决
    Flume 的监控方式
    Flume 自定义 组件
    Source r1 has been removed due to an error during configuration java.lang.IllegalArgumentException: Required parameter bind must exist and may not be null & 端口无法连接
  • 原文地址:https://www.cnblogs.com/monodin/p/3993873.html
Copyright © 2011-2022 走看看