Cordova Android app crashes with RecoverableSecurityException while capturing photo

1k Views Asked by At

Cordova android app crashing frequently while capturing photo using camera. The stacktrace from crashlytics is

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)

Most of the crashes happened in Samsung devices with Android 11 and 12.

The code for capturing the photo is

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

I have tried to resolve this by adding try catch inside the Camera plugin's CameraLauncher.java file as suggested here but camera is not opening after that

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();
}

}

Did anyone faced this issue? Any help would be really appreciated

Versions used are:-

  • Cordova: 10.0.0 ([email protected])
  • cordova-android: 10.1.1
  • cordova-plugin-camera: 6.0.0
  • Device: Samsung devices with Android 11 or 12
1

There are 1 best solutions below

1
Karl On

I have the same issue on an Android 10 Device (Armor_X8). Everything is up to date.

"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"

}