我开发了一个带有cordova / phonegap的移动应用程序,并且我已经安装了Camera插件。我可以打开相机并单击图像,但在该应用程序崩溃后。这是崩溃日志:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=34, result=-1, data=null} to activity {com.phonegap.helloworld/com.phonegap.helloworld.CordovaApp}: java.lang.IllegalArgumentException: filename cannot be null
E/AndroidRuntime(22226): at android.app.ActivityThread.deliverResults(ActivityThread.java:3510)
E/AndroidRuntime(22226): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3553)
E/AndroidRuntime(22226): at android.app.ActivityThread.access$1200(ActivityThread.java:165)
E/AndroidRuntime(22226): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1374)
E/AndroidRuntime(22226): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(22226): at android.os.Looper.loop(Looper.java:176)
E/AndroidRuntime(22226): at android.app.ActivityThread.main(ActivityThread.java:5455)
E/AndroidRuntime(22226): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(22226): at java.lang.reflect.Method.invoke(Method.java:525)
E/AndroidRuntime(22226): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
E/AndroidRuntime(22226): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
E/AndroidRuntime(22226): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(22226): Caused by: java.lang.IllegalArgumentException: filename cannot be null
E/AndroidRuntime(22226): at android.media.ExifInterface.<init>(ExifInterface.java:121)
E/AndroidRuntime(22226): at org.apache.cordova.camera.ExifHelper.createOutFile(ExifHelper.java:66)
E/AndroidRuntime(22226): at org.apache.cordova.camera.CameraLauncher.processResultFromCamera(CameraLauncher.java:430)
E/AndroidRuntime(22226): at org.apache.cordova.camera.CameraLauncher.onActivityResult(CameraLauncher.java:610)
E/AndroidRuntime(22226): at org.apache.cordova.CordovaActivity.onActivityResult(CordovaActivity.java:784)
E/AndroidRuntime(22226): at android.app.Activity.dispatchActivityResult(Activity.java:5563)
E/AndroidRuntime(22226): at android.app.ActivityThread.deliverResults(ActivityThread.java:3506)
E/AndroidRuntime(22226): ... 11 more
我用来打开相机的代码是:
var pictureSource; // picture source
var destinationType; // sets the format of returned value
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
// alert("ready-----")
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
}
function capturePhoto() {
alert(navigator.camera);
navigator.camera.getPicture(onPhotoDataSuccess, onFail, {
quality: 20,
destinationType: destinationType.FILE_URI,
targetWidth: 200,
targetHeight: 200,
saveToPhotoAlbum: true,
sourceType: pictureSource.CAMERA
});
}
function onPhotoDataSuccess(imageURI) {
// alert("success--");
var smallImage = document.getElementById('smallImage');
smallImage.style.display = 'block';
smallImage.src = imageURI;
// smallImage.src = "data:image/jpeg;base64," + imageData;
}
function onFail(message) {
alert('Failed because: ' + message);
}
该错误已记录在Apache Cordova。
帮助!!!
答案 0 :(得分:2)
尝试用这个替换你的capturePhoto()函数(这是我自己的应用程序的代码):
function capturePhoto() {
var options = {
quality: 75,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
mediaType: Camera.MediaType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 200,
targetHeight: 200,
saveToPhotoAlbum: true
};
navigator.camera.getPicture(onPhotoDataSuccess, onFail, options);
}
答案 1 :(得分:1)
请更改您的目的地类型:
destinationType: destinationType.FILE_URI
到
destinationType: Camera.DestinationType.FILE_URI
如果您需要它作为base64编码图像,则将目标类型更改为:
destinationType: Camera.DestinationType.DATA_URL
还要确保已在清单文件中添加了写入外部存储权限。
答案 2 :(得分:0)
该插件正在向ExifInterface
传递一个空指针,导致异常,这在旧版插件中并没有发生。
尝试应用以下修复程序,您也可以报告设备品牌,型号和Android版本吗?
diff --git a/src/android/ExifHelper.java b/src/android/ExifHelper.java
index 5160a2f..0af0fcd 100644
--- a/src/android/ExifHelper.java
+++ b/src/android/ExifHelper.java
@@ -53,7 +53,11 @@ public class ExifHelper {
* @throws IOException
*/
public void createInFile(String filePath) throws IOException {
- this.inFile = new ExifInterface(filePath);
+ if (filePath != null) {
+ this.inFile = new ExifInterface(filePath);
+ } else {
+ throw new IOException("null pointer passed to createInFile");
+ }
}
/**
@@ -63,7 +67,11 @@ public class ExifHelper {
* @throws IOException
*/
public void createOutFile(String filePath) throws IOException {
- this.outFile = new ExifInterface(filePath);
+ if (filePath != null) {
+ this.outFile = new ExifInterface(filePath);
+ } else {
+ throw new IOException("null pointer passed to createOutFile");
+ }
}
/**
diff --git a/src/android/FileHelper.java b/src/android/FileHelper.java
index 59f890e..cd4b6ef 100644
--- a/src/android/FileHelper.java
+++ b/src/android/FileHelper.java
@@ -33,6 +33,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
+import android.util.Log;
public class FileHelper {
private static final String LOG_TAG = "FileUtils";
@@ -54,9 +55,12 @@ public class FileHelper {
realPath = FileHelper.getRealPathFromURI_BelowAPI11(cordova.getActivity(), uri);
// SDK >= 11 && SDK < 19
- else if (Build.VERSION.SDK_INT < 19)
+ else if (Build.VERSION.SDK_INT < 19) {
realPath = FileHelper.getRealPathFromURI_API11to18(cordova.getActivity(), uri);
-
+ if (realPath == null) {
+ realPath = getRealPathFallback(uri.toString(), cordova);
+ }
+ }
// SDK > 19 (Android 4.4)
else
realPath = FileHelper.getRealPathFromURI_API19(cordova.getActivity(), uri);
@@ -126,6 +130,47 @@ public class FileHelper {
return result;
}
+ /**
+ * Returns the real path of the given URI string.
+ * If the given URI string represents a content:// URI, the real path is retrieved from the media store.
+ *
+ * @param uriString the URI string of the audio/image/video
+ * @param cordova the current application context
+ * @return the full path to the file
+ */
+ @SuppressWarnings("deprecation")
+ public static String getRealPathFallback(String uriString, CordovaInterface cordova) {
+ String realPath = null;
+ try {
+ if (uriString.startsWith("content://")) {
+ String[] proj = { _DATA };
+ Cursor cursor = cordova.getActivity().managedQuery(Uri.parse(uriString), proj, null, null, null);
+ int column_index = cursor.getColumnIndexOrThrow(_DATA);
+ cursor.moveToFirst();
+ realPath = cursor.getString(column_index);
+ Log.d(LOG_TAG, "getRealPath managedQuery success uri " + uriString + " realpath " + realPath);
+ if (realPath == null) {
+ Log.e(LOG_TAG, "getRealPath Could get real path for URI string " + uriString);
+ }
+ } else if (uriString.startsWith("file://")) {
+ realPath = uriString.substring(7);
+ Log.d(LOG_TAG, "getRealPath file:// " + uriString + " realpath " + realPath);
+ if (realPath.startsWith("/android_asset/")) {
+ Log.e(LOG_TAG, "getRealPath Cannot get real path for URI string " + uriString + " because it is a file:///android_asset/ URI.");
+ realPath = null;
+ }
+ } else {
+ realPath = uriString;
+ }
+ } catch (Exception e) {
+ Log.d(LOG_TAG, "getRealPath using uristring could not find real path, uriString: " + uriString + " message: " + e.getMessage());
+ realPath = uriString;
+ }
+
+ return realPath;
+ }
+
+
public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
String result = null;