При удалении приложения PhoneGap при съемке новой фотографии с помощью плагина камеры

Я разрабатываю мобильное приложение с cordova/phonegap, и я установил плагин камеры. Я могу открыть камеру и щелкнуть изображение, но после этого произойдет сбой приложения. вот журнал сбоев:

    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.

Help!!!

Ответ 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);
}

Ответ 2

измените тип адресата:

destinationType: destinationType.FILE_URI

к

destinationType: Camera.DestinationType.FILE_URI

если вы потребовали его в качестве изображения с кодировкой base64, затем измените тип назначения как:

destinationType: Camera.DestinationType.DATA_URL

также убедитесь, что вы добавили разрешение на запись в хранилище в файл манифеста.

Ответ 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;