华为的系统执行如下代码从图库中获取图片会报错.
navigator.camera.getPicture(function(imageURI){ alert(imageURI); resolveLocalFileSystemURL(imageURI, function(entry) { alert('cdvfile URI: ' + entry.toInternalURL()); document.querySelector("#aa").src = entry.toInternalURL();//将图片在html img中显示出来 }); }, function(message){ } , { quality: 50, destinationType: Camera.DestinationType.FILE_URI , sourceType:Camera.PictureSourceType.SAVEDPHOTOALBUM }
经过排查发现华为默认的图片浏览返回的是 "com.android.providers.media.documents"
所以要修改 cordova-plugin-camera 插件中的 CameraLauncher.java 文件
增加:
public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } /** * Applies all needed transformation to the image received from the gallery. * * @param destType In which form should we return the image * @param intent An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). */ private void processResultFromGallery(int destType, Intent intent) { Uri uri = intent.getData(); if (uri == null) { if (croppedUri != null) { uri = croppedUri; } else { this.failPicture("null data from photo library"); return; } } int rotate = 0; // If you ask for video or all media type you will automatically get back a file URI // and there will be no attempt to resize any returned data if (this.mediaType != PICTURE) { this.callbackContext.success(uri.toString()); } else { // This is a special case to just return the path as no scaling, // rotating, nor compressing needs to be done if (this.targetHeight == -1 && this.targetWidth == -1 && (destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation) { if(isMediaDocument(uri)){ String realPath = FileHelper.getRealPath(uri, this.cordova); this.callbackContext.success("file://" + realPath); }else{ this.callbackContext.success(uri.toString()); } } else { String uriString = uri.toString(); // Get the path to the image. Makes loading so much easier. String mimeType = FileHelper.getMimeType(uriString, this.cordova); // If we don't have a valid image so quit. if (!("image/jpeg".equalsIgnoreCase(mimeType) || "image/png".equalsIgnoreCase(mimeType))) { Log.d(LOG_TAG, "I either have a null image path or bitmap"); this.failPicture("Unable to retrieve path to picture!"); return; } Bitmap bitmap = null; try { bitmap = getScaledBitmap(uriString); } catch (IOException e) { e.printStackTrace(); } if (bitmap == null) { Log.d(LOG_TAG, "I either have a null image path or bitmap"); this.failPicture("Unable to create bitmap!"); return; } if (this.correctOrientation) { rotate = getImageOrientation(uri); if (rotate != 0) { Matrix matrix = new Matrix(); matrix.setRotate(rotate); try { bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); this.orientationCorrected = true; } catch (OutOfMemoryError oom) { this.orientationCorrected = false; } } } // If sending base64 image back if (destType == DATA_URL) { this.processPicture(bitmap); } // If sending filename back 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()); } } if (bitmap != null) { bitmap.recycle(); bitmap = null; } System.gc(); } } }