cordova-plugin-camera: App crashes with RecoverableSecurityException after URI resolves to content://media/

Bug Report

Problem

App crashes when using Timestamp app to take a picture.

What is expected to happen?

App should inform that the URI is not accessible by app, not crash.

I have tried converting the “content://media/<path>” into a “file://<path>” without succes.

I verified all permissions and the function works fine when using device’s camera.

What does actually happen?

App is killed by OS…

Log from adb logcat

10-20 23:27:29.354 13405 13405 E AndroidRuntime: FATAL EXCEPTION: main
10-20 23:27:29.354 13405 13405 E AndroidRuntime: Process: io.gits.form, PID: 13405
10-20 23:27:29.354 13405 13405 E AndroidRuntime: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=34, result=-1, data=null} to activity {io.gits.form/io.gits.form.MainActivity}: android.app.RecoverableSecurityException: io.gits.form has no access to content://media/external/images/media/6625
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.app.ActivityThread.deliverResults(ActivityThread.java:5097)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.app.ActivityThread.handleSendResult(ActivityThread.java:5138)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2147)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:107)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:237)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:7814)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: Caused by: android.app.RecoverableSecurityException: io.gits.form has no access to content://media/external/images/media/6625
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.app.RecoverableSecurityException$1.createFromParcel(RecoverableSecurityException.java:197)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.app.RecoverableSecurityException$1.createFromParcel(RecoverableSecurityException.java:194)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.os.Parcel.readParcelable(Parcel.java:2990)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.os.Parcel.createException(Parcel.java:2083)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.os.Parcel.readException(Parcel.java:2056)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:188)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.content.ContentProviderProxy.delete(ContentProviderNative.java:553)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.content.ContentResolver.delete(ContentResolver.java:1956)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at org.apache.cordova.camera.CameraLauncher.checkForDuplicateImage(CameraLauncher.java:1234)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at org.apache.cordova.camera.CameraLauncher.cleanup(CameraLauncher.java:1200)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at org.apache.cordova.camera.CameraLauncher.processResultFromCamera(CameraLauncher.java:601)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at org.apache.cordova.camera.CameraLauncher.onActivityResult(CameraLauncher.java:806)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at org.apache.cordova.CordovaInterfaceImpl.onActivityResult(CordovaInterfaceImpl.java:159)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at org.apache.cordova.CordovaActivity.onActivityResult(CordovaActivity.java:361)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.app.Activity.dispatchActivityResult(Activity.java:8292)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	at android.app.ActivityThread.deliverResults(ActivityThread.java:5090)
10-20 23:27:29.354 13405 13405 E AndroidRuntime: 	... 11 more
10-20 23:27:29.365 22238 22238 D ActivityThread: setConscryptValidator
10-20 23:27:29.366 22238 22238 D ActivityThread: setConscryptValidator - put
10-20 23:27:29.369  4678  6839 I ActivityManager: DSS OFF for com.samsung.android.bixby.service
10-20 23:27:29.386  4243  7458 I CameraService: onUidStateChanged: uid=10024, procState=4

Information

Command or Code

takePicture(fieldId){
    console.log("Taking picture...");
    this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.CAMERA).then( 
      response => {
        console.log("Permission status:", response);
        console.log("Resolving file path...");
        this.camera.getPicture().then( uriPath => {
          this.fileCordova.resolveLocalFilesystemUrl(uriPath).then( resultPath => {
            console.log(resultPath);
          }).catch(error => console.log(error));
      }, err => {console.log(err)})
  }, err => {console.log(err)}
  )
}

Environment, Platform, Device

Bug occurs on different Android 9+ devices.

Version information

ionic info Ionic:

Ionic CLI : 5.4.9 (/usr/local/lib/node_modules/ionic) Ionic Framework : @ionic/angular 5.0.0 @angular-devkit/build-angular : 0.803.24 @angular-devkit/schematics : 8.3.25 @angular/cli : 8.3.25 @ionic/angular-toolkit : 2.1.2

Cordova:

Cordova CLI : 9.0.0 (cordova-lib@9.0.1) Cordova Platforms : android 7.1.0, browser 6.0.0 Cordova Plugins : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 4.1.3, (and 15 other plugins)

Utility:

cordova-res : not installed native-run : 1.2.1 (update available: 1.2.2)

System:

NodeJS : v14.2.0 (/home/gerardo/.nvm/versions/node/v14.2.0/bin/node) npm : 6.14.4 OS : Linux 5.4

Checklist

  • I searched for existing GitHub issues
  • I updated all Cordova tooling to most recent version
  • I included all the necessary information above

I’m trying to retrieve plugin callback as mentioned in : https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html#upgrading (Last section)

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 5
  • Comments: 31 (5 by maintainers)

Commits related to this issue

Most upvoted comments

If you’re targeting android target 30, I’ll downgrade for the time being. There are breaking changes in the android filesystem APIs that Cordova doesn’t currently support. You can downgrade the target API via android-targetSdkVersion preference.

If you’re targeting android target 29, then I’d either downgrade to API 28* using the preference noted above or try the master branch of cordova-plugin-file (for testing purposes).

  • Note: If you’re building a new app, Google won’t allow you to publish an app build with API 28. If you’re updating an existing app, Google will allow API 28 until November, which is creeping up fast.

Hi @PabbleDabble Would you consider creating a fork or a pull request with your changes on the original cordova-plugin-camera repository? This could really help others in the community.

Thanks for your contribution!

https://github.com/PabbleDabble/cordova-plugin-camera

Here’s the steps I took after forking master from this main

$ git clone https://github.com/PabbleDabble/cordova-plugin-camera.git
$ cd cordova-plugin-camera
$ git remote add a12-fork https://github.com/dongourdet/cordova-plugin-camera
$ git remote add a13-fork https://github.com/jalios/cordova-plugin-camera
$ git fetch --all

# just a fast-forward
$ git cherry-pick a13-fork/master

# second pick had to resolve conflicts (just whitespace / confirm)
$ git cherry-pick a12-fork/master
$ git status
$ git push

For the record, I think the A12 cherry-pick is still probably not perfect as it asks for permission to delete the temp file after capture each time which is not great (but better than a crash).

Here’s where I found comments / notes to why I did what I did… Link to A12 issue - https://github.com/apache/cordova-plugin-camera/issues/679 Link to A13 issue - https://github.com/apache/cordova-plugin-camera/issues/826#issuecomment-1610030014

@breautek Do you know when we will have any informations about this Android 11 problem and Cordova? Is someone working on this?

Afaik, no one is allocating time on API 30 FS problems. We need to figure out how to incorporate the MediaStore APIs for API 30.

MediaStore API is significantly different than the raw file system APIs so it may be out of scope for the file plugin itself. Someone needs to analyse this problem in great detail to understand the full scope of the problem (i.e: it obviously it affects the file system usage, but does it also affect this camera plugin? file transfer plugin? media-capture plugin? etc…). Based on this ticket, the answer to each of those questions is probably a “yes”. Help is wanted for this.

With API 29, you’ll need https://github.com/apache/cordova-plugin-file/pull/417/files which the cordova-plugin-file has, but is not released yet.

So if you can add the android:requestLegacyExternalStorage flag using the cordova-custom-config plugin, then that could be a workaround for the time being.

The android:requestLegacyExternalStorage is only introduced in API 29 and will be ignored in API 30, forcing app developers to actually use the new FS system that android has.

@breautek We have a user experiencing these crashes, and gave them a .apk of our app with the code in proposed 6.01 patch or rather to be precise we installed this version of the plugin https://github.com/dongourdet/cordova-plugin-camera/commit/fa9570399b11af0547fd4ed77892f4c35d383d33

This fixed the issue for our user… Is there a timeline for getting this fix out in the wild in the official plugin?

Thank you very much. It’s almost the same as the changes I implemented. But I still don’t understand why, even though I work with the image as a blob (last option), it keeps trying to access content://media/external/images/media/ and generating android.app.RecoverableSecurityException. On Android 10 devices, the application crashes; however, on version 13, it generates the error but doesn’t close the app.

Just a little update: I’m not sure how relevant this is, but our customer says the patched camera plugin works with their Galaxy tablet but not their Lenovo ones. The Galaxy uses the com.sec.android.app.camera camera package, while the Lenovo uses the com.mediatek.camera package. I’m not too familiar with how Android works, but it sounds like there’s some incompatibility between the Mediatek camera software and either Android 11+ or this plugin, that causes it to ask for permission with every photo they take.

@JeffBerman I only did a quick test so this could be happening, not sure. We just send build to QA, I’ll ask our Android 12 user to test again and update asap.

I did the same as @PabbleDabble and sent our app to a customer who experiences the crashing issue on their tablet. It resolved the crash, but they state that every time they take a photo it asks for permission to modify the picture. I’m still waiting to hear back from them on the exact message they see.

Is anyone experiencing this? I don’t see what could make Android ask for permission every single time a photo is taken. Thanks!

the last Time i published , the Ionic APK to play store , I Got this warning :

From May 5, you will need to tell us why your app requires extended storage access We have detected the requestLegacyExternalStorage flag in the manifest file of one or more of your app’s app bundles or APKs. Developers whose apps are running on Android 11 or later should make use of siled storage space so that users can better control access to their device’s storage space. As of May 5, to offer your app on Android 11 or later, you will need to follow one of the procedures below: Update your application to follow best practices that are more respectful of confidentiality, for example thanks to the Storage Access Framework or Media Store APIs Update your application to declare permission to access all files (MANAGE_EXTERNAL_STORAGE) in the manifest file, and complete the permission to access all files statement in the Play Console from May 5th Remove permission to access all files in your app For apps targeting Android 11, the requestLegacyExternalStorage flag will be ignored. You must use the All Files Access permission to maintain extended access. Apps that ask for permission to access all files when they are not allowed to do so will be removed from Google Play, and you will not be able to update them.

In my Case , I commented the code line that crash the Plugin in a fork branch (https://github.com/interstellerS/cordova-plugin-camera/commit/884ff37f9ef68d40ca464a70b0e39b4adfde4f4b ) , Then both the image capture and save to gallery worked just Fine!

I wonder if the entrerpise version of this plugin has a fix for this .