[Phonegap+Sencha Touch] 移动开发29 安卓navigator.camera.getPicture得到图片的真实路径

phonegap的拍照插件选择图库中的图片,代码如下:

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. navigator.camera.getPicture(function(uri){  
  2.     console.log(uri);//这里得到图片的uri  
  3. }, function(err){ console.log(err); }, {  
  4.     quality: 70,  
  5.     destinationType: navigator.camera.DestinationType.FILE_URI,  
  6.     sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY,  
  7.     saveToPhotoAlbum: true  
  8. });  


返回的图片路径是这样的:

安卓4.4之前:content://media/external/images/media/62

安卓4.4:content://com.android.providers.media.documents/document/image:62


这种路径叫做Content URI,并不是图片的真实路径,真实路径应该是这样的:file:///storage/emulated/0/DCIM/Camera/1406773746740.jpg。


解决办法:

打开插件文件org.apache.cordova.camera\src\android\CameraLauncher.java

在里面添加下面的代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * Get a file path from a Uri. This will get the the path for Storage Access 
  3.      * Framework Documents, as well as the _data field for the MediaStore and 
  4.      * other file-based ContentProviders. 
  5.      * 
  6.      * @param context The context. 
  7.      * @param uri The Uri to query. 
  8.      * @author paulburke 
  9.      */  
  10.     @SuppressLint("NewApi")  
  11.     public static String getPath(final Context context, final Uri uri) {  
  12.   
  13.         final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;  
  14.   
  15.         // DocumentProvider  
  16.         if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {  
  17.             // ExternalStorageProvider  
  18.             if (isExternalStorageDocument(uri)) {  
  19.                 final String docId = DocumentsContract.getDocumentId(uri);  
  20.                 final String[] split = docId.split(":");  
  21.                 final String type = split[0];  
  22.   
  23.                 if ("primary".equalsIgnoreCase(type)) {  
  24.                     return Environment.getExternalStorageDirectory() + "/" + split[1];  
  25.                 }  
  26.   
  27.                 // TODO handle non-primary volumes  
  28.             }  
  29.             // DownloadsProvider  
  30.             else if (isDownloadsDocument(uri)) {  
  31.   
  32.                 final String id = DocumentsContract.getDocumentId(uri);  
  33.                 final Uri contentUri = ContentUris.withAppendedId(  
  34.                         Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));  
  35.   
  36.                 return getDataColumn(context, contentUri, nullnull);  
  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.   
  44.                 Uri contentUri = null;  
  45.                 if ("image".equals(type)) {  
  46.                     contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;  
  47.                 } else if ("video".equals(type)) {  
  48.                     contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;  
  49.                 } else if ("audio".equals(type)) {  
  50.                     contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;  
  51.                 }  
  52.   
  53.                 final String selection = "_id=?";  
  54.                 final String[] selectionArgs = new String[] {  
  55.                         split[1]  
  56.                 };  
  57.   
  58.                 return getDataColumn(context, contentUri, selection, selectionArgs);  
  59.             }  
  60.         }  
  61.         // MediaStore (and general)  
  62.         else if ("content".equalsIgnoreCase(uri.getScheme())) {  
  63.   
  64.             // Return the remote address  
  65.             if (isGooglePhotosUri(uri))  
  66.                 return uri.getLastPathSegment();  
  67.   
  68.             return getDataColumn(context, uri, nullnull);  
  69.         }  
  70.         // File  
  71.         else if ("file".equalsIgnoreCase(uri.getScheme())) {  
  72.             return uri.getPath();  
  73.         }  
  74.   
  75.         return null;  
  76.     }  
  77.   
  78.     /** 
  79.      * Get the value of the data column for this Uri. This is useful for 
  80.      * MediaStore Uris, and other file-based ContentProviders. 
  81.      * 
  82.      * @param context The context. 
  83.      * @param uri The Uri to query. 
  84.      * @param selection (Optional) Filter used in the query. 
  85.      * @param selectionArgs (Optional) Selection arguments used in the query. 
  86.      * @return The value of the _data column, which is typically a file path. 
  87.      */  
  88.     public static String getDataColumn(Context context, Uri uri, String selection,  
  89.             String[] selectionArgs) {  
  90.   
  91.         Cursor cursor = null;  
  92.         final String column = "_data";  
  93.         final String[] projection = {  
  94.                 column  
  95.         };  
  96.   
  97.         try {  
  98.             cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,  
  99.                     null);  
  100.             if (cursor != null && cursor.moveToFirst()) {  
  101.                 final int index = cursor.getColumnIndexOrThrow(column);  
  102.                 return cursor.getString(index);  
  103.             }  
  104.         } finally {  
  105.             if (cursor != null)  
  106.                 cursor.close();  
  107.         }  
  108.         return null;  
  109.     }  
  110.   
  111.   
  112.     /** 
  113.      * @param uri The Uri to check. 
  114.      * @return Whether the Uri authority is ExternalStorageProvider. 
  115.      */  
  116.     public static boolean isExternalStorageDocument(Uri uri) {  
  117.         return "com.android.externalstorage.documents".equals(uri.getAuthority());  
  118.     }  
  119.   
  120.     /** 
  121.      * @param uri The Uri to check. 
  122.      * @return Whether the Uri authority is DownloadsProvider. 
  123.      */  
  124.     public static boolean isDownloadsDocument(Uri uri) {  
  125.         return "com.android.providers.downloads.documents".equals(uri.getAuthority());  
  126.     }  
  127.   
  128.     /** 
  129.      * @param uri The Uri to check. 
  130.      * @return Whether the Uri authority is MediaProvider. 
  131.      */  
  132.     public static boolean isMediaDocument(Uri uri) {  
  133.         return "com.android.providers.media.documents".equals(uri.getAuthority());  
  134.     }  
  135.   
  136.     /** 
  137.      * @param uri The Uri to check. 
  138.      * @return Whether the Uri authority is Google Photos. 
  139.      */  
  140.     public static boolean isGooglePhotosUri(Uri uri) {  
  141.         return "com.google.android.apps.photos.content".equals(uri.getAuthority());  
  142.     }  

然后找到下面的代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. if (this.targetHeight == -1 && this.targetWidth == -1 &&  
  2.         (destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation) {  
  3.     this.callbackContext.success(uri.toString());  
  4. }  

修改成这样

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. if (this.targetHeight == -1 && this.targetWidth == -1 &&  
  2.         (destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation) {  
  3.     Context context = this.webView.getContext().getApplicationContext();  
  4.     this.callbackContext.success(getPath(context, uri));  
  5. }  


记得在顶部导入包:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import android.annotation.SuppressLint;  
  2. import android.content.ContentUris;  
  3. import android.content.Context;  
  4. import android.os.Build;  
  5. import android.provider.DocumentsContract;  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值