Android(安卓)4.4从图库选择图片,获取图片路径并裁剪
转至http://blog.csdn.net/tempersitu/article/details/20557383
最近在做一个从图库选择图片或拍照,然后裁剪的功能.本来是没问题的,一直在用
[java] view plain copy- Intentintent=newIntent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
的方式来做,是调用系统图库来做,但是发现如果有图片是同步到google相册的话,图库里面能看到一个auto backup的目录,点进去选图片的话是无法获取到图片的路径的.因为那些图片根本就不存在于手机上.然后看到无论是百度贴吧,Instagram,或者还有些会选取图片做修改的app,都是用一个很漂亮的图片选择器(4.4以上,4.3的还是用系统旧的图库).
而这个图片选择器可以屏蔽掉那个auto backup的目录.所以就开始打算用这个图片选择器来选图片了.
这个方法就是
- Intentintent=newIntent(Intent.ACTION_GET_CONTENT);//ACTION_OPEN_DOCUMENT
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- intent.setType("image/jpeg");
- if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT){
- startActivityForResult(intent,SELECT_PIC_KITKAT);
- }else{
- startActivityForResult(intent,SELECT_PIC);
- }
为什么要分开不同版本呢?其实在4.3或以下可以直接用ACTION_GET_CONTENT的,在4.4或以上,官方建议用ACTION_OPEN_DOCUMENT,但其实都不算太大区别,区别是他们返回的Uri,那个才叫大区别.这就是困扰了我一整天的问题所在了.
4.3或以下,选了图片之后,根据Uri来做处理,很多帖子都有了,我就不详细说了.主要是4.4,如果使用上面pick的原生方法来选图,返回的uri还是正常的,但如果用ACTION_GET_CONTENT的方法,返回的uri跟4.3是完全不一样的,4.3返回的是带文件路径的,而4.4返回的却是content://com.android.providers.media.documents/document/image:3951这样的,没有路径,只有图片编号的uri.这就导致接下来无法根据图片路径来裁剪的步骤了.
还好找了很多方法,包括加权限啊什么的,中间还试过用一些方法,自己的app没崩溃,倒是让系统图库崩溃了,引发了java.lang.SecurityException.
[java] view plain copy- Causedby:java.lang.SecurityException:PermissionDenial:openingprovidercom.android.providers.media.MediaDocumentsProviderfromProcessRecord{437b5d889494:com.google.android.gallery3d/u0a20}(pid=9494,uid=10020)requiresandroid.permission.MANAGE_DOCUMENTSorandroid.permission.MANAGE_DOCUMENTS
看来4.4的系统还是有些bug.重点来了,4.4得到的uri,需要以下方法来获取文件的路径
- publicstaticStringgetPath(finalContextcontext,finalUriuri){
- finalbooleanisKitKat=Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT;
- //DocumentProvider
- if(isKitKat&&DocumentsContract.isDocumentUri(context,uri)){
- //ExternalStorageProvider
- if(isExternalStorageDocument(uri)){
- finalStringdocId=DocumentsContract.getDocumentId(uri);
- finalString[]split=docId.split(":");
- finalStringtype=split[0];
- if("primary".equalsIgnoreCase(type)){
- returnEnvironment.getExternalStorageDirectory()+"/"+split[1];
- }
- //TODOhandlenon-primaryvolumes
- }
- //DownloadsProvider
- elseif(isDownloadsDocument(uri)){
- finalStringid=DocumentsContract.getDocumentId(uri);
- finalUricontentUri=ContentUris.withAppendedId(
- Uri.parse("content://downloads/public_downloads"),Long.valueOf(id));
- returngetDataColumn(context,contentUri,null,null);
- }
- //MediaProvider
- elseif(isMediaDocument(uri)){
- finalStringdocId=DocumentsContract.getDocumentId(uri);
- finalString[]split=docId.split(":");
- finalStringtype=split[0];
- UricontentUri=null;
- if("image".equals(type)){
- contentUri=MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
- }elseif("video".equals(type)){
- contentUri=MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
- }elseif("audio".equals(type)){
- contentUri=MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
- }
- finalStringselection="_id=?";
- finalString[]selectionArgs=newString[]{
- split[1]
- };
- returngetDataColumn(context,contentUri,selection,selectionArgs);
- }
- }
- //MediaStore(andgeneral)
- elseif("content".equalsIgnoreCase(uri.getScheme())){
- //Returntheremoteaddress
- if(isGooglePhotosUri(uri))
- returnuri.getLastPathSegment();
- returngetDataColumn(context,uri,null,null);
- }
- //File
- elseif("file".equalsIgnoreCase(uri.getScheme())){
- returnuri.getPath();
- }
- returnnull;
- }
- /**
- *GetthevalueofthedatacolumnforthisUri.Thisisusefulfor
- *MediaStoreUris,andotherfile-basedContentProviders.
- *
- *@paramcontextThecontext.
- *@paramuriTheUritoquery.
- *@paramselection(Optional)Filterusedinthequery.
- *@paramselectionArgs(Optional)Selectionargumentsusedinthequery.
- *@returnThevalueofthe_datacolumn,whichistypicallyafilepath.
- */
- publicstaticStringgetDataColumn(Contextcontext,Uriuri,Stringselection,
- String[]selectionArgs){
- Cursorcursor=null;
- finalStringcolumn="_data";
- finalString[]projection={
- column
- };
- try{
- cursor=context.getContentResolver().query(uri,projection,selection,selectionArgs,
- null);
- if(cursor!=null&&cursor.moveToFirst()){
- finalintindex=cursor.getColumnIndexOrThrow(column);
- returncursor.getString(index);
- }
- }finally{
- if(cursor!=null)
- cursor.close();
- }
- returnnull;
- }
- /**
- *@paramuriTheUritocheck.
- *@returnWhethertheUriauthorityisExternalStorageProvider.
- */
- publicstaticbooleanisExternalStorageDocument(Uriuri){
- return"com.android.externalstorage.documents".equals(uri.getAuthority());
- }
- /**
- *@paramuriTheUritocheck.
- *@returnWhethertheUriauthorityisDownloadsProvider.
- */
- publicstaticbooleanisDownloadsDocument(Uriuri){
- return"com.android.providers.downloads.documents".equals(uri.getAuthority());
- }
- /**
- *@paramuriTheUritocheck.
- *@returnWhethertheUriauthorityisMediaProvider.
- */
- publicstaticbooleanisMediaDocument(Uriuri){
- return"com.android.providers.media.documents".equals(uri.getAuthority());
- }
- /**
- *@paramuriTheUritocheck.
- *@returnWhethertheUriauthorityisGooglePhotos.
- */
- publicstaticbooleanisGooglePhotosUri(Uriuri){
- return"com.google.android.apps.photos.content".equals(uri.getAuthority());
- }
这样,就可以在4.4上用漂亮的图片选择器,选到我们想要的文件,又不会出问题了.
昨天发现了个bug,如果在4.4上面不用"图片"来选,用"图库"来选,就会无法读取到图片路径,所以只需要加个判断,如果是用旧方式来选,就用旧方式来读,就是如果
DocumentsContract.isDocumentUri(context, uri) 返回false的话,就用旧的方式
- publicstaticStringselectImage(Contextcontext,Intentdata){
- UriselectedImage=data.getData();
- //Log.e(TAG,selectedImage.toString());
- if(selectedImage!=null){
- StringuriStr=selectedImage.toString();
- Stringpath=uriStr.substring(10,uriStr.length());
- if(path.startsWith("com.sec.android.gallery3d")){
- Log.e(TAG,"It'sautobackuppicpath:"+selectedImage.toString());
- returnnull;
- }
- }
- String[]filePathColumn={MediaStore.Images.Media.DATA};
- Cursorcursor=context.getContentResolver().query(selectedImage,filePathColumn,null,null,null);
- cursor.moveToFirst();
- intcolumnIndex=cursor.getColumnIndex(filePathColumn[0]);
- StringpicturePath=cursor.getString(columnIndex);
- cursor.close();
- returnpicturePath;
- }
这样就OK的了
更多相关文章
- Android实现图片单点旋转缩放保存-仿百度魔图
- build/envsetup.sh简记
- Android(安卓)易忘部分
- android获取本地图片或拍照图片
- Android学习札记47:TextView显示Html类解析的网页和图片及自定义
- Android(安卓)图像系列: 图片的压缩
- Android(安卓)实现简单的画画版一
- Android(安卓)选择图片、上传图片之ImagePicker
- MonkeyRunner进坑——errors importing other modules