android4.4从系统图库无法加载图片的问题

转载 2015年07月09日 14:52:01
典型的使用场景就是要设置一个头像,头像需要从系统图库或者拍照获得,在android4.4之前,我用的代码没问题,但是今天使用android4.4的时候突然发现不灵了。baidu了一圈,终于解决了。 
下面是解决方案: 
Java代码  收藏代码
  1. private String[] items = new String[] { "图库","拍照" };  
  2.         /* 头像名称 */  
  3.         private static final String IMAGE_FILE_NAME = "face.jpg";  
  4.         /* 请求码 */  
  5.         private static final int IMAGE_REQUEST_CODE = 0;  
  6.         private static final int SELECT_PIC_KITKAT = 3;  
  7.         private static final int CAMERA_REQUEST_CODE = 1;  
  8.         private static final int RESULT_REQUEST_CODE = 2;  
  9.   
  10.         private void showSettingFaceDialog() {  
  11.   
  12.             new AlertDialog.Builder(this)  
  13.                     .setTitle("图片来源")  
  14.                     .setCancelable(true)  
  15.                     .setItems(items, new DialogInterface.OnClickListener() {  
  16.   
  17.                         @Override  
  18.                         public void onClick(DialogInterface dialog, int which) {  
  19.                             switch (which) {  
  20.                             case 0:// Local Image  
  21.                                 Intent intent=new Intent(Intent.ACTION_GET_CONTENT);  
  22.                                 intent.addCategory(Intent.CATEGORY_OPENABLE);  
  23.                                 intent.setType("image/*");  
  24.                                 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {  
  25.                                     startActivityForResult(intent,SELECT_PIC_KITKAT);  
  26.                                 } else {  
  27.                                     startActivityForResult(intent,IMAGE_REQUEST_CODE);  
  28.                                 }  
  29.                                 break;  
  30.                             case 1:// Take Picture  
  31.                                 Intent intentFromCapture = new Intent(  
  32.                                         MediaStore.ACTION_IMAGE_CAPTURE);  
  33.                                 // 判断存储卡是否可以用,可用进行存储  
  34.                                 if (hasSdcard()) {  
  35.                                     intentFromCapture.putExtra(  
  36.                                             MediaStore.EXTRA_OUTPUT,  
  37.                                             Uri.fromFile(new File(Environment  
  38.                                                     .getExternalStorageDirectory(),  
  39.                                                     IMAGE_FILE_NAME)));  
  40.                                 }  
  41.                                 startActivityForResult(intentFromCapture,  
  42.                                         CAMERA_REQUEST_CODE);  
  43.                                 break;  
  44.                             }  
  45.                         }  
  46.                     })  
  47.                     .setNegativeButton("取消",  
  48.                             new DialogInterface.OnClickListener() {  
  49.   
  50.                                 @Override  
  51.                                 public void onClick(DialogInterface dialog,  
  52.                                         int which) {  
  53.                                     dialog.dismiss();  
  54.                                 }  
  55.                             }).show();  
  56.   
  57.         }  
  58.   
  59.         @Override  
  60.         protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  61.             // 结果码不等于取消时候  
  62.             if (resultCode != RESULT_CANCELED) {  
  63.                 switch (requestCode) {  
  64.                 case IMAGE_REQUEST_CODE:  
  65.                     startPhotoZoom(data.getData());  
  66.                     break;  
  67.                 case SELECT_PIC_KITKAT:  
  68.                     startPhotoZoom(data.getData());  
  69.                     break;  
  70.                 case CAMERA_REQUEST_CODE:  
  71.                     if (hasSdcard()) {  
  72.                         File tempFile = new File(Environment.getExternalStorageDirectory(),IMAGE_FILE_NAME);  
  73.                         startPhotoZoom(Uri.fromFile(tempFile));  
  74.                     } else {  
  75.                         ToastUtils.showShort(context,"未找到存储卡,无法存储照片!");  
  76.                     }  
  77.   
  78.                     break;  
  79.                 case RESULT_REQUEST_CODE:  
  80.                     if (data != null) {  
  81.                         setImageToView(data,iv_face);  
  82.                     }  
  83.                     break;  
  84.                 }  
  85.             }  
  86.             super.onActivityResult(requestCode, resultCode, data);  
  87.         }  
  88.   
  89.         /**  
  90.          * 裁剪图片方法实现  
  91.          *   
  92.          * @param uri  
  93.          */  
  94.         public void startPhotoZoom(Uri uri) {  
  95.             if (uri == null) {  
  96.                 Log.i("tag""The uri is not exist.");  
  97.                 return;  
  98.             }  
  99.               
  100.             Intent intent = new Intent("com.android.camera.action.CROP");  
  101.             if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {  
  102.                 String url=getPath(context,uri);  
  103.                 intent.setDataAndType(Uri.fromFile(new File(url)), "image/*");  
  104.             }else{  
  105.                 intent.setDataAndType(uri, "image/*");  
  106.             }  
  107.               
  108.             // 设置裁剪  
  109.             intent.putExtra("crop""true");  
  110.             // aspectX aspectY 是宽高的比例  
  111.             intent.putExtra("aspectX"1);  
  112.             intent.putExtra("aspectY"1);  
  113.             // outputX outputY 是裁剪图片宽高  
  114.             intent.putExtra("outputX"200);  
  115.             intent.putExtra("outputY"200);  
  116.             intent.putExtra("return-data"true);  
  117.             startActivityForResult(intent, RESULT_REQUEST_CODE);  
  118.         }  
  119.           
  120.         /**  
  121.          * 保存裁剪之后的图片数据  
  122.          *   
  123.          * @param picdata  
  124.          */  
  125.         private void setImageToView(Intent data,ImageView imageView) {  
  126.             Bundle extras = data.getExtras();  
  127.             if (extras != null) {  
  128.                 Bitmap photo = extras.getParcelable("data");  
  129.                 Bitmap roundBitmap=ImageUtil.toRoundBitmap(photo);  
  130.                 imageView.setImageBitmap(roundBitmap);  
  131.                 saveBitmap(photo);  
  132.             }  
  133.         }  
  134.   
  135.         public void saveBitmap(Bitmap mBitmap) {  
  136.             File f = new File(Environment.getExternalStorageDirectory(),IMAGE_FILE_NAME);  
  137.             try {  
  138.                 f.createNewFile();  
  139.                 FileOutputStream fOut = null;  
  140.                 fOut = new FileOutputStream(f);  
  141.                 mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);  
  142.                 fOut.flush();  
  143.                 fOut.close();  
  144.             } catch (FileNotFoundException e) {  
  145.                 e.printStackTrace();  
  146.             } catch (IOException e) {  
  147.                 e.printStackTrace();  
  148.             }  
  149.         }  
  150.           
  151.           
  152.         //以下是关键,原本uri返回的是file:///...来着的,android4.4返回的是content:///...  
  153.         @SuppressLint("NewApi")  
  154.         public static String getPath(final Context context, final Uri uri) {  
  155.   
  156.             final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;  
  157.   
  158.             // DocumentProvider  
  159.             if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {  
  160.                 // ExternalStorageProvider  
  161.                 if (isExternalStorageDocument(uri)) {  
  162.                     final String docId = DocumentsContract.getDocumentId(uri);  
  163.                     final String[] split = docId.split(":");  
  164.                     final String type = split[0];  
  165.   
  166.                     if ("primary".equalsIgnoreCase(type)) {  
  167.                         return Environment.getExternalStorageDirectory() + "/" + split[1];  
  168.                     }  
  169.   
  170.                 }  
  171.                 // DownloadsProvider  
  172.                 else if (isDownloadsDocument(uri)) {  
  173.                     final String id = DocumentsContract.getDocumentId(uri);  
  174.                     final Uri contentUri = ContentUris.withAppendedId(  
  175.                             Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));  
  176.   
  177.                     return getDataColumn(context, contentUri, nullnull);  
  178.                 }  
  179.                 // MediaProvider  
  180.                 else if (isMediaDocument(uri)) {  
  181.                     final String docId = DocumentsContract.getDocumentId(uri);  
  182.                     final String[] split = docId.split(":");  
  183.                     final String type = split[0];  
  184.   
  185.                     Uri contentUri = null;  
  186.                     if ("image".equals(type)) {  
  187.                         contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;  
  188.                     } else if ("video".equals(type)) {  
  189.                         contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;  
  190.                     } else if ("audio".equals(type)) {  
  191.                         contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;  
  192.                     }  
  193.   
  194.                     final String selection = "_id=?";  
  195.                     final String[] selectionArgs = new String[] {  
  196.                             split[1]  
  197.                     };  
  198.   
  199.                     return getDataColumn(context, contentUri, selection, selectionArgs);  
  200.                 }  
  201.             }  
  202.             // MediaStore (and general)  
  203.             else if ("content".equalsIgnoreCase(uri.getScheme())) {  
  204.                 // Return the remote address  
  205.                 if (isGooglePhotosUri(uri))  
  206.                     return uri.getLastPathSegment();  
  207.   
  208.                 return getDataColumn(context, uri, nullnull);  
  209.             }  
  210.             // File  
  211.             else if ("file".equalsIgnoreCase(uri.getScheme())) {  
  212.                 return uri.getPath();  
  213.             }  
  214.   
  215.             return null;  
  216.         }  
  217.   
  218.         /** 
  219.          * Get the value of the data column for this Uri. This is useful for 
  220.          * MediaStore Uris, and other file-based ContentProviders. 
  221.          * 
  222.          * @param context The context. 
  223.          * @param uri The Uri to query. 
  224.          * @param selection (Optional) Filter used in the query. 
  225.          * @param selectionArgs (Optional) Selection arguments used in the query. 
  226.          * @return The value of the _data column, which is typically a file path. 
  227.          */  
  228.         public static String getDataColumn(Context context, Uri uri, String selection,  
  229.                 String[] selectionArgs) {  
  230.   
  231.             Cursor cursor = null;  
  232.             final String column = "_data";  
  233.             final String[] projection = {  
  234.                     column  
  235.             };  
  236.   
  237.             try {  
  238.                 cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,  
  239.                         null);  
  240.                 if (cursor != null && cursor.moveToFirst()) {  
  241.                     final int index = cursor.getColumnIndexOrThrow(column);  
  242.                     return cursor.getString(index);  
  243.                 }  
  244.             } finally {  
  245.                 if (cursor != null)  
  246.                     cursor.close();  
  247.             }  
  248.             return null;  
  249.         }  
  250.   
  251.   
  252.         /** 
  253.          * @param uri The Uri to check. 
  254.          * @return Whether the Uri authority is ExternalStorageProvider. 
  255.          */  
  256.         public static boolean isExternalStorageDocument(Uri uri) {  
  257.             return "com.android.externalstorage.documents".equals(uri.getAuthority());  
  258.         }  
  259.   
  260.         /** 
  261.          * @param uri The Uri to check. 
  262.          * @return Whether the Uri authority is DownloadsProvider. 
  263.          */  
  264.         public static boolean isDownloadsDocument(Uri uri) {  
  265.             return "com.android.providers.downloads.documents".equals(uri.getAuthority());  
  266.         }  
  267.   
  268.         /** 
  269.          * @param uri The Uri to check. 
  270.          * @return Whether the Uri authority is MediaProvider. 
  271.          */  
  272.         public static boolean isMediaDocument(Uri uri) {  
  273.             return "com.android.providers.media.documents".equals(uri.getAuthority());  
  274.         }  
  275.   
  276.         /** 
  277.          * @param uri The Uri to check. 
  278.          * @return Whether the Uri authority is Google Photos. 
  279.          */  
  280.         public static boolean isGooglePhotosUri(Uri uri) {  
  281.             return "com.google.android.apps.photos.content".equals(uri.getAuthority());  
  282.         }  


最后只需要在需要的地方调用showSettingFaceDialog()就可以了。 

如果要获得剪裁的图片保存路径,然后上传,我这边是这样处理的(这里每个人的写法不一样): 
但只要获得filePath就可以根据自己的需求处理了 
Java代码  收藏代码
  1. private void uploadFace(){  
  2.         File file = new File(Environment.getExternalStorageDirectory(),IMAGE_FILE_NAME);  
  3.         String filePath=file.getAbsolutePath();  
  4.           
  5.         Log.i("tag""filePath="+filePath);  
  6.         HttpHelper.uploadFileWithConcatUrl(context,HttpHelper.UPDATE_USER_ICON,App.user.getUser_session_key() ,filePath ,new HttpHelper.OnFileUploadListener(){  
  7.   
  8.                 @Override  
  9.                 public void onFileUploadSuccess(String orignUrl, String midImgUrl,  
  10.                         String smallImgUrl) {  
  11.                     // TODO Auto-generated method stub  
  12.                       
  13.                     App.user.setHead_icon(orignUrl);  
  14.                       
  15.                     saveUser();  
  16.                 }  
  17.                    
  18.         });  
  19.     }  

相关文章推荐

解决Android 4.4 系统图库选择图片问题

从图库选择图片的方式大家都不陌生:         Intent intent = new Intent(Intent.ACTION_GET_CONTENT);//ACTION_OPEN_DOCUM...

解决Android4.4及以上系统获取系统图片失败的问题,例如华为手机,调系统图库的时候就出现异常

本来我是想转载的,但是忘记原帖在哪了,但是按照下面的方法确实解决了这个棘手的问题,不墨迹,直接上代码:     @Override     protected void onActivityRes...

Android 4.4从图库选择图片并裁剪,由于系统版本不同导致Uri的bug的简单解决方式

做过Android换头像的都知道如何使用系统的方法选图片或者拍照换头像。有几个intent可以使用: 拍照: new Intent(MediaStore.ACTION_IMAGE...

Android4.4 ContentResolver查询图片无效 及 图库删除 增加图片后,ContentResolver不更新的问题解决

问题背景: 参考链接 做了一个图片浏览,用ContentResolver扫描图库照片,且严格按照时间拍摄顺序排好序显示在listview里。如下图所示:遇到的问题是在4.2的手机上能正常显示,但是新增...

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

这个问题是人才中心项目中遇到的关于头像换取的问题,android 4.4版本前后 图片获取本地图库的方法发生一些变化,这里记录下来方便自己查看...

Android保存图片到系统图库及常见问题解决

今天要做一个保存图片到系统图库的功能,自身能力较浅,所以只能搜索了但发现网上的方法有几处bug,所以自己总结一下防止以后忘掉也想和大家分享一下. 首页网上保存图片并插入系统图库的方法: // 首...

Android 4.4前后版本读取图库图片和拍照完美解决方案

4.3或以下,选了图片之后,根据Uri来做处理,很多帖子都有了,我就不详细说了.主要是4.4,如果使用上面pick的原生方法来选图,返回的uri还是正常的,但如果用ACTION_GET_CONTENT...
  • ZBJDSBJ
  • ZBJDSBJ
  • 2015年01月04日 10:27
  • 17572

Android4.4以上从图库选择图片返回的路径不正确解决方法

android 4.4系统以前,选择图片,获取图片路径代码如下: 1 2 3 4 5 //访问图库 Intent inte...

Android 4.4前后版本读取图库图片和拍照完美解决方案

2015-01-04 10:27 4.3或以下,选了图片之后,根据Uri来做处理,很多帖子都有了,我就不详细说了.主要是4.4,如果使用上面pick的原生方法来选图,返回的uri还是正常的,但如...
  • dj0379
  • dj0379
  • 2015年12月04日 14:08
  • 1919
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android4.4从系统图库无法加载图片的问题
举报原因:
原因补充:

(最多只允许输入30个字)