Cordova Android 应用在拍照时崩溃并显示 RecoverableSecurityException

3
Cordova安卓应用在使用相机拍照时经常崩溃。Crashlytics的堆栈跟踪如下:
Caused by android.app.RecoverableSecurityException: com.myapp.appname has no access to content://media/external/images/media/131613
   at android.app.RecoverableSecurityException$1.createFromParcel(RecoverableSecurityException.java:197)
   at android.app.RecoverableSecurityException$1.createFromParcel(RecoverableSecurityException.java:194)
   at android.os.Parcel.readParcelable(Parcel.java:3295)
   at android.os.Parcel.createExceptionOrNull(Parcel.java:2382)
   at android.os.Parcel.createException(Parcel.java:2371)
   at android.os.Parcel.readException(Parcel.java:2354)
   at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:190)
   at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
   at android.content.ContentProviderProxy.delete(ContentProviderNative.java:624)
   at android.content.ContentResolver.delete(ContentResolver.java:2386)
   at android.content.ContentResolver.delete(ContentResolver.java:2344)
   at org.apache.cordova.camera.CameraLauncher.checkForDuplicateImage(CameraLauncher.java:1234)
   at org.apache.cordova.camera.CameraLauncher.cleanup(CameraLauncher.java:1200)
   at org.apache.cordova.camera.CameraLauncher.processResultFromCamera(CameraLauncher.java:597)
   at org.apache.cordova.camera.CameraLauncher.onActivityResult(CameraLauncher.java:829)
   at org.apache.cordova.CordovaInterfaceImpl.onActivityResult(CordovaInterfaceImpl.java:160)
   at org.apache.cordova.CordovaActivity.onActivityResult(CordovaActivity.java:368)
   at android.app.Activity.dispatchActivityResult(Activity.java:8627)
   at android.app.ActivityThread.deliverResults(ActivityThread.java:5466)
   at android.app.ActivityThread.handleSendResult(ActivityThread.java:5514)
   at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
   at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
   at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2380)
   at android.os.Handler.dispatchMessage(Handler.java:106)
   at android.os.Looper.loop(Looper.java:257)
   at android.app.ActivityThread.main(ActivityThread.java:8335)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:626)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1032)

大多数崩溃发生在安装有Android 11和12的三星设备中。

捕获照片的代码是:

    navigator.camera.getPicture(onPhotoDataSuccess, onPhotoCaptureFail, {
        quality: 100,
        destinationType: Camera.DestinationType.FILE_URI,
        sourceType: 1,
        encodingType: 0,
        allowEdit: false,
        targetWidth: 1024,
        targetHeight: 768,
        correctOrientation: true
    });

我已经尝试通过在相机插件的CameraLauncher.java文件中添加try catch来解决这个问题,就像这里建议的那样,但之后相机仍然无法打开。

private void checkForDuplicateImage(int type) {
int diff = 1;
Uri contentStore = whichContentStore();
Cursor cursor = queryImgDB(contentStore);
int currentNumOfImages = cursor.getCount();

if (type == FILE_URI && this.saveToPhotoAlbum) {
  diff = 2;
}

// delete the duplicate file if the difference is 2 for file URI or 1 for Data URL
if ((currentNumOfImages - numPics) == diff) {
  cursor.moveToLast();
  int id = Integer.valueOf(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media._ID)));
  if (diff == 2) {
    id--;
  }
  Uri uri = Uri.parse(contentStore + "/" + id);
  ContentResolver contentResolver = this.cordova.getActivity().getContentResolver();

  try {
    contentResolver.delete(uri, null, null);
  } catch (SecurityException e) {
    if (this.manualMediaStoreCleanup && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {

      ArrayList<Uri> collection = new ArrayList<>();
      collection.add(uri);
      PendingIntent pendingIntent = MediaStore.createDeleteRequest(contentResolver, collection);
      try {
        this.cordova.getActivity().startIntentSenderForResult(pendingIntent.getIntentSender(),
          42, null, 0, 0,
          0, null);

      } catch (IntentSender.SendIntentException ex) {
        LOG.e(LOG_TAG, "Error starting deleteRequest intent");
      }

    } else if (this.manualMediaStoreCleanup && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

      //if exception is recoverable then again send delete request using intent
      if (e instanceof RecoverableSecurityException) {
        RecoverableSecurityException exception = (RecoverableSecurityException) e;
        PendingIntent pendingIntent = exception.getUserAction().getActionIntent();

        try {
          mediaStoreUri = uri;
         this.cordova.setActivityResultCallback(this);
          this.cordova.getActivity().startIntentSenderForResult(pendingIntent.getIntentSender(),
            RECOVERABLE_DELETE_REQUEST, null, 0, 0,
            0, null);
        } catch (IntentSender.SendIntentException ex) {
          LOG.e(LOG_TAG, "Error starting RecoverableSecurityException intent");
        }
      }
    } else {
      LOG.e(LOG_TAG, "Error during media store file deletion");    
    }

  }

  cursor.close();
}

有人遇到过这个问题吗?非常感谢任何帮助。

使用的版本如下:

  • Cordova: 10.0.0 (cordova-lib@10.1.0)
  • cordova-android: 10.1.1
  • cordova-plugin-camera: 6.0.0
  • 设备:搭载Android 11或12的三星设备
1个回答

0

我在一个Android 10设备(Armor_X8)上遇到了同样的问题。一切都是最新的。

"plugin_metadata": {
"cordova-plugin-app-version": "0.1.12",
"cordova-plugin-device": "2.0.3",
"cordova-plugin-geolocation": "4.1.0",
"es6-promise-plugin": "4.2.2",
"cordova-plugin-screen-orientation": "3.0.2",
"cordova-plugin-inappbrowser": "5.0.0",
"@red-mobile/cordova-plugin-barcodescanner": "9.0.7",
"cordova-plugin-network-information": "3.0.0",
"cordova-plugin-camera": "6.0.0"

}


我在Android 11和12操作系统上遇到了同样的问题,一些Cordova插件在最新的Android操作系统上无法正常工作。 - Chetan Ghadiya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接