使用相机插件拍摄新照片时,PhoneGap 应用程序崩溃
Posted
技术标签:
【中文标题】使用相机插件拍摄新照片时,PhoneGap 应用程序崩溃【英文标题】:PhoneGap App Crash when take a new photo with Camera Plugin 【发布时间】:2015-06-03 10:00:05 【问题描述】:我正在使用 cordova/phonegap 开发一个移动应用程序,并且我已经安装了相机插件。我可以打开相机并单击图像,但在该应用程序崩溃之后。这是崩溃日志:
java.lang.RuntimeException: Failure delivering result ResultInfowho=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。
求救!!!
【问题讨论】:
您的示例代码与Phonegap's
文档中的相同。它也类似于Cordova's
文档,唯一的区别是这一行:destinationType: Camera.DestinationType.FILE_URI, sourceType: Camera.pictureSource.CAMERA
在选项对象中。你试过那些吗?您使用的是哪个版本的 cordova 或 phonegap?
【参考方案1】:
尝试用这个替换你的 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);
【讨论】:
我在我的安卓设备上遇到了类似的问题,结果我的编码类型设置为 PNG。将其更改为 JPEG 为我解决了这个问题 @Mike Dailor:你救了我的命。我遇到了在 android 11 上运行的 ionic v1 应用程序的问题。您的配置解决了我的问题。你是最棒的。非常感谢。【参考方案2】:请更改您的目的地类型:
destinationType: destinationType.FILE_URI
到
destinationType: Camera.DestinationType.FILE_URI
如果您需要它作为 base64 编码图像,则将目标类型更改为:
destinationType: Camera.DestinationType.DATA_URL
还要确保您已在清单文件中添加写入外部存储权限。
【讨论】:
我需要文件中的图像而不是二进制字符串。 您是否更改了目的地类型?使用destinationType:Camera.DestinationType.FILE_URI,您将获得图像的文件位置。 也许你可以删除目标高度和目标宽度参数,试一试我的也是这样。【参考方案3】:插件将空指针传递给ExifInterface
导致异常,这在旧插件中不会发生。
尝试应用以下修复,您也可以报告设备品牌,型号和android版本吗?
https://issues.apache.org/jira/browse/CB-9446
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;
【讨论】:
以上是关于使用相机插件拍摄新照片时,PhoneGap 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
使用 Phonegap/Cordova 相机插件从相机或图库中选择照片