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

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

2016-11-15 21:59 246 查看
转载http://gundumw100.iteye.com/blog/2158345,非常感谢!

典型的使用场景就是要设置一个头像,头像需要从系统图库或者拍照获得,在android4.4之前,我用的代码没问题,但是今天使用android4.4的时候突然发现不灵了。baidu了一圈,终于解决了。 

下面是解决方案: 

Java代码  


private String[] items = new String[] { "图库","拍照" };  

        /* 头像名称 */  

        private static final String IMAGE_FILE_NAME = "face.jpg";  

        /* 请求码 */  

        private static final int IMAGE_REQUEST_CODE = 0;  

        private static final int SELECT_PIC_KITKAT = 3;  

        private static final int CAMERA_REQUEST_CODE = 1;  

        private static final int RESULT_REQUEST_CODE = 2;  

  

        private void showSettingFaceDialog() {  

  

            new AlertDialog.Builder(this)  

                    .setTitle("图片来源")  

                    .setCancelable(true)  

                    .setItems(items, new DialogInterface.OnClickListener() {  

  

                        @Override  

                        public void onClick(DialogInterface dialog, int which) {  

                            switch (which) {  

                            case 0:// Local Image  

                                Intent intent=new Intent(Intent.ACTION_GET_CONTENT);  

                                intent.addCategory(Intent.CATEGORY_OPENABLE);  

                                intent.setType("image/*");  

                                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {  

                                    startActivityForResult(intent,SELECT_PIC_KITKAT);  

                                } else {  

                                    startActivityForResult(intent,IMAGE_REQUEST_CODE);  

                                }  

                                break;  

                            case 1:// Take Picture  

                                Intent intentFromCapture = new Intent(  

                                        MediaStore.ACTION_IMAGE_CAPTURE);  

                                // 判断存储卡是否可以用,可用进行存储  

                                if (hasSdcard()) {  

                                    intentFromCapture.putExtra(  

                                            MediaStore.EXTRA_OUTPUT,  

                                            Uri.fromFile(new File(Environment  

                                                    .getExternalStorageDirectory(),  

                                                    IMAGE_FILE_NAME)));  

                                }  

                                startActivityForResult(intentFromCapture,  

                                        CAMERA_REQUEST_CODE);  

                                break;  

                            }  

                        }  

                    })  

                    .setNegativeButton("取消",  

                            new DialogInterface.OnClickListener() {  

  

                                @Override  

                                public void onClick(DialogInterface dialog,  

                                        int which) {  

                                    dialog.dismiss();  

                                }  

                            }).show();  

  

        }  

  

        @Override  

        protected void onActivityResult(int requestCode, int resultCode, Intent data) {  

            // 结果码不等于取消时候  

            if (resultCode != RESULT_CANCELED) {  

                switch (requestCode) {  

                case IMAGE_REQUEST_CODE:  

                    startPhotoZoom(data.getData());  

                    break;  

                case SELECT_PIC_KITKAT:  

                    startPhotoZoom(data.getData());  

                    break;  

                case CAMERA_REQUEST_CODE:  

                    if (hasSdcard()) {  

                        File tempFile = new File(Environment.getExternalStorageDirectory(),IMAGE_FILE_NAME);  

                        startPhotoZoom(Uri.fromFile(tempFile));  

                    } else {  

                        ToastUtils.showShort(context,"未找到存储卡,无法存储照片!");  

                    }  

  

                    break;  

                case RESULT_REQUEST_CODE:  

                    if (data != null) {  

                        setImageToView(data,iv_face);  

                    }  

                    break;  

                }  

            }  

            super.onActivityResult(requestCode, resultCode, data);  

        }  

  

        /**  

         * 裁剪图片方法实现  

         *   

         * @param uri  

         */  

        public void startPhotoZoom(Uri uri) {  

            if (uri == null) {  

                Log.i("tag", "The uri is not exist.");  

                return;  

            }  

              

            Intent intent = new Intent("com.android.camera.action.CROP");  

            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {  

                String url=getPath(context,uri);  

                intent.setDataAndType(Uri.fromFile(new File(url)), "image/*");  

            }else{  

                intent.setDataAndType(uri, "image/*");  

            }  

              

            // 设置裁剪  

            intent.putExtra("crop", "true");  

            // aspectX aspectY 是宽高的比例  

            intent.putExtra("aspectX", 1);  

            intent.putExtra("aspectY", 1);  

            // outputX outputY 是裁剪图片宽高  

            intent.putExtra("outputX", 200);  

            intent.putExtra("outputY", 200);  

            intent.putExtra("return-data", true);  

            startActivityForResult(intent, RESULT_REQUEST_CODE);  

        }  

          

        /**  

         * 保存裁剪之后的图片数据  

         *   

         * @param picdata  

         */  

        private void setImageToView(Intent data,ImageView imageView) {  

            Bundle extras = data.getExtras();  

            if (extras != null) {  

                Bitmap photo = extras.getParcelable("data");  

                Bitmap roundBitmap=ImageUtil.toRoundBitmap(photo);  

                imageView.setImageBitmap(roundBitmap);  

                saveBitmap(photo);  

            }  

        }  

  

        public void saveBitmap(Bitmap mBitmap) {  

            File f = new File(Environment.getExternalStorageDirectory(),IMAGE_FILE_NAME);  

            try {  

                f.createNewFile();  

                FileOutputStream fOut = null;  

                fOut = new FileOutputStream(f);  

                mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);  

                fOut.flush();  

                fOut.close();  

            } catch (FileNotFoundException e) {  

                e.printStackTrace();  

            } catch (IOException e) {  

                e.printStackTrace();  

            }  

        }  

          

          

        //以下是关键,原本uri返回的是file:///...来着的,android4.4返回的是content:///...  

        @SuppressLint("NewApi")  

        public static String getPath(final Context context, final Uri uri) {  

  

            final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;  

  

            // DocumentProvider  

            if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {  

                // ExternalStorageProvider  

                if (isExternalStorageDocument(uri)) {  

                    final String docId = DocumentsContract.getDocumentId(uri);  

                    final String[] split = docId.split(":");  

                    final String type = split[0];  

  

                    if ("primary".equalsIgnoreCase(type)) {  

                        return Environment.getExternalStorageDirectory() + "/" + split[1];  

                    }  

  

                }  

                // DownloadsProvider  

                else if (isDownloadsDocument(uri)) {  

                    final String id = DocumentsContract.getDocumentId(uri);  

                    final Uri contentUri = ContentUris.withAppendedId(  

                            Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));  

  

                    return getDataColumn(context, contentUri, null, null);  

                }  

                // MediaProvider  

                else if (isMediaDocument(uri)) {  

                    final String docId = DocumentsContract.getDocumentId(uri);  

                    final String[] split = docId.split(":");  

                    final String type = split[0];  

  

                    Uri contentUri = null;  

                    if ("image".equals(type)) {  

                        contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;  

                    } else if ("video".equals(type)) {  

                        contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;  

                    } else if ("audio".equals(type)) {  

                        contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;  

                    }  

  

                    final String selection = "_id=?";  

                    final String[] selectionArgs = new String[] {  

                            split[1]  

                    };  

  

                    return getDataColumn(context, contentUri, selection, selectionArgs);  

                }  

            }  

            // MediaStore (and general)  

            else if ("content".equalsIgnoreCase(uri.getScheme())) {  

                // Return the remote address  

                if (isGooglePhotosUri(uri))  

                    return uri.getLastPathSegment();  

  

                return getDataColumn(context, uri, null, null);  

            }  

            // File  

            else if ("file".equalsIgnoreCase(uri.getScheme())) {  

                return uri.getPath();  

            }  

  

            return null;  

        }  

  

        /** 

         * Get the value of the data column for this Uri. This is useful for 

         * MediaStore Uris, and other file-based ContentProviders. 

         * 

         * @param context The context. 

         * @param uri The Uri to query. 

         * @param selection (Optional) Filter used in the query. 

         * @param selectionArgs (Optional) Selection arguments used in the query. 

         * @return The value of the _data column, which is typically a file path. 

         */  

        public static String getDataColumn(Context context, Uri uri, String selection,  

                String[] selectionArgs) {  

  

            Cursor cursor = null;  

            final String column = "_data";  

            final String[] projection = {  

                    column  

            };  

  

            try {  

                cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,  

                        null);  

                if (cursor != null && cursor.moveToFirst()) {  

                    final int index = cursor.getColumnIndexOrThrow(column);  

                    return cursor.getString(index);  

                }  

            } finally {  

                if (cursor != null)  

                    cursor.close();  

            }  

            return null;  

        }  

  

  

        /** 

         * @param uri The Uri to check. 

         * @return Whether the Uri authority is ExternalStorageProvider. 

         */  

        public static boolean isExternalStorageDocument(Uri uri) {  

            return "com.android.externalstorage.documents".equals(uri.getAuthority());  

        }  

  

        /** 

         * @param uri The Uri to check. 

         * @return Whether the Uri authority is DownloadsProvider. 

         */  

        public static boolean isDownloadsDocument(Uri uri) {  

            return "com.android.providers.downloads.documents".equals(uri.getAuthority());  

        }  

  

        /** 

         * @param uri The Uri to check. 

         * @return Whether the Uri authority is MediaProvider. 

         */  

        public static boolean isMediaDocument(Uri uri) {  

            return "com.android.providers.media.documents".equals(uri.getAuthority());  

        }  

  

        /** 

         * @param uri The Uri to check. 

         * @return Whether the Uri authority is Google Photos. 

         */  

        public static boolean isGooglePhotosUri(Uri uri) {  

            return "com.google.android.apps.photos.content".equals(uri.getAuthority());  

        }  

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

如果要获得剪裁的图片保存路径,然后上传,我这边是这样处理的(这里每个人的写法不一样): 
但只要获得filePath就可以根据自己的需求处理了 

Java代码  


private void uploadFace(){  

        File file = new File(Environment.getExternalStorageDirectory(),IMAGE_FILE_NAME);  

        String filePath=file.getAbsolutePath();  

          

        Log.i("tag", "filePath="+filePath);  

        HttpHelper.uploadFileWithConcatUrl(context,HttpHelper.UPDATE_USER_ICON,App.user.getUser_session_key() ,filePath ,new HttpHelper.OnFileUploadListener(){  

  

                @Override  

                public void onFileUploadSuccess(String orignUrl, String midImgUrl,  

                        String smallImgUrl) {  

                    // TODO Auto-generated method stub  

                      

                    App.user.setHead_icon(orignUrl);  

                      

                    saveUser();  

                }  

                   

        });  

    }  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐