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

原文地址:http://blog.csdn.net/lovelyelfpop/article/details/38313021


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

navigator.camera.getPicture(function(uri){
	console.log(uri);//这里得到图片的uri
}, function(err){ console.log(err); }, {
    quality: 70,
    destinationType: navigator.camera.DestinationType.FILE_URI,
    sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY,
    saveToPhotoAlbum: true
});


返回的图片路径是这种:

安卓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。


解决的方法:

1、打开插件文件org.apache.cordova.camerasrcandroidCameraLauncher.java

在里面加入以下的代码:

/**
	 * Get a file path from a Uri. This will get the the path for Storage Access
	 * Framework Documents, as well as the _data field for the MediaStore and
	 * other file-based ContentProviders.
	 *
	 * @param context The context.
	 * @param uri The Uri to query.
	 * @author paulburke
	 */
	@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];
	            }

	            // TODO handle non-primary volumes
	        }
	        // 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()); }



2、然后找到以下的代码(processResultFromGallery方法):

if (this.targetHeight == -1 && this.targetWidth == -1 &&
        (destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation) {
    this.callbackContext.success(uri.toString());
}

改动成这样

if (this.targetHeight == -1 && this.targetWidth == -1 &&
        (destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation) {
    Context context = this.webView.getContext().getApplicationContext();
    this.callbackContext.success(getPath(context, uri));
}


3、找到以下代码processResultFromGallery方法):

else if (destType == FILE_URI || destType == NATIVE_URI) {
    // Did we modify the image?

if ( (this.targetHeight > 0 && this.targetWidth > 0) || (this.correctOrientation && this.orientationCorrected) ) { try { String modifiedPath = this.ouputModifiedBitmap(bitmap, uri); // The modified image is cached by the app in order to get around this and not have to delete you // application cache I'm adding the current system time to the end of the file url. this.callbackContext.success("file://" + modifiedPath + "?

" + System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); this.failPicture("Error retrieving image."); } } else { this.callbackContext.success(uri.toString()); } }


改动成这样(else部分)

else if (destType == FILE_URI || destType == NATIVE_URI) {
    // Did we modify the image?
    if ( (this.targetHeight > 0 && this.targetWidth > 0) ||
            (this.correctOrientation && this.orientationCorrected) ) {
        try {
            String modifiedPath = this.ouputModifiedBitmap(bitmap, uri);
            // The modified image is cached by the app in order to get around this and not have to delete you
            // application cache I'm adding the current system time to the end of the file url.
            this.callbackContext.success("file://" + modifiedPath + "?

" + System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); this.failPicture("Error retrieving image."); } } else { Context context = this.webView.getContext().getApplicationContext(); //这里 this.callbackContext.success(getPath(context, uri)); } }



4、记得在顶部导入包:

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.os.Build;
import android.provider.DocumentsContract;





欢迎增加Sencha Touch + Phonegap交流群

1群:194182999 (满)

2群:419834979

共同学习交流(博主QQ:479858761

原文地址:https://www.cnblogs.com/mengfanrong/p/5364224.html