cordova-plugin-camera
cordova-plugin-camera copied to clipboard
Android 13 : Camera/Gallery doesn't open
Bug Report
Msg: cannot open camera: 20
Problem
Camera doesn't open, Gallery doesn't open, for Android 13 emulator Pointing API 33 of Android in the build.gradle
What is expected to happen?
Camera should open, Gallery should open
What does actually happen?
Nothing, display a bug message : Msg: cannot open camera: 20
E/Capacitor/Browser: Error binding to custom tabs service
Command or Code
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.DATA_URL,
sourceType: this.camera.PictureSourceType.SAVEDPHOTOALBUM,
correctOrientation: true,
allowEdit: false,
targetHeight: 1280,
targetWidth: 1280,
};
this.camera.getPicture(options).then()....
Environment, Platform, Device
Ionic, Android 13
Workarounds
Use API 32
In my case picking an image from Library works, but taking an image with whichever options gives the error Illegal Argument Exception
Also occurs on Android 12 devices:
- Xiaomi POCO X3 Pro | MIUI 13.0.1 | Android 12
- Pixel 6 | Android 12
- Pixel 6 Pro | Android 12
Edit: Select from Library works, but when the image is picked, the callback also gives the error Illegal Argument Exception
Confirmed on pure cordova app
Cordova android v11.0.0 cordova camera plugin v6.0.0
Build Tools / Target SDK 33 on Android 13 emulator
Error code 20 is produced to the JS console
Native logcat:
07-16 00:23:38.096 575 914 V UserSystemPackageInstaller: dumpPackageWhitelistProblems(): using mode ENFORCE|IMPLICIT_WHITELIST|IMPLICIT_WHITELIST_SYSTEM
07-16 00:23:38.113 575 914 I ActivityTaskManager: START u0 {act=android.content.pm.action.REQUEST_PERMISSIONS pkg=com.google.android.permissioncontroller cmp=com.google.android.permissioncontroller/com.android.permissioncontroller.permission.ui.GrantPermissionsActivity (has extras)} from uid 10157
07-16 00:23:38.120 6334 6334 D CordovaActivity: Paused the activity.
07-16 00:23:38.121 575 917 W ActivityTaskManager: Tried to set launchTime (0) < mLastActivityLaunchTime (352665)
07-16 00:23:38.125 575 594 D OomAdjuster: Not killing cached processes
07-16 00:23:38.142 575 917 D CoreBackPreview: Window{e737f07 u0 com.google.android.permissioncontroller/com.android.permissioncontroller.permission.ui.GrantPermissionsActivity}: Setting back callback OnBackInvokedCallbackInfo{mCallback=android.window.IOnBackInvokedCallback$Stub$Proxy@c13665d, mPriority=0}
07-16 00:23:38.150 402 446 D goldfish-address-space: claimShared: Ask to claim region [0x3f683d000 0x3f6e40000]
07-16 00:23:38.160 6334 6334 D CordovaActivity: Resumed the activity.
07-16 00:23:38.161 6334 6334 I chromium: [INFO:CONSOLE(1)] "20", source: (1)
07-16 00:23:38.173 575 917 D CoreBackPreview: Window{e737f07 u0 com.google.android.permissioncontroller/com.android.permissioncontroller.permission.ui.GrantPermissionsActivity}: Setting back callback null
07-16 00:23:38.173 575 3087 W InputManager-JNI: Input channel object 'e737f07 com.google.android.permissioncontroller/com.android.permissioncontroller.permission.ui.GrantPermissionsActivity (client)' was disposed without first being removed with the input manager!
07-16 00:23:38.189 7107 7107 I GoogleInputMethodService: GoogleInputMethodService.onFinishInput():3204
07-16 00:23:38.190 7107 7107 I GoogleInputMethodService: GoogleInputMethodService.updateDeviceLockedStatus():2100 checkRepeatedly = false, unlocked = true
07-16 00:23:38.190 7107 7107 I GoogleInputMethodService: GoogleInputMethodService.onStartInput():1903 onStartInput(EditorInfo{inputType=0x0(NULL) imeOptions=0x12000000 privateImeOptions=null actionName=UNSPECIFIED actionLabel=null actionId=0 initialSelStart=-1 initialSelEnd=-1 initialCapsMode=0x0 hintText=null label=null packageName=io.cordova.hellocordovagh797 fieldId=100 fieldName=null extras=null}, false)
07-16 00:23:38.190 7107 7107 I GoogleInputMethodService: GoogleInputMethodService.updateDeviceLockedStatus():2100 checkRepeatedly = true, unlocked = true
At a glance, it appears something to do with handling permissions has changed in Android 13, as error code 20
is a Permission Error Code...
https://github.com/apache/cordova-plugin-camera/blob/4608f8ef8027a5c7130a3479c2d37a5e391c70e8/src/android/CameraLauncher.java#L100
I've also tested against build tools / target SDK 32 on an Android 13 emulator which appears to work fine. So this appears to be exclusively an API 33 issue.
Can we have an update on this bug please? I think Android 13 is gonna be released soon
breautek
I tried adding the permissions as said in the Android doc https://developer.android.com/about/versions/13/behavior-changes-13
Like this :
<manifest ...>
<!-- Required only if your app targets Android 13. -->
<!-- Declare one or more the following permissions only if your app needs
to access data that's protected by them. -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- Required to maintain app compatibility. -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<application ...>
...
</application>
</manifest>
But it didn't change. "Cannot open camera : 20" , "Cannot open gallery : 20"
After investigating, the error comes from this method on CameraLauncher.java file :
public void onRequestPermissionResult(int requestCode, String[] permissions,
int[] grantResults) {
for (int r : grantResults) {
System.out.println("PHOTO DEBUG - " + r);
/* if (r == PackageManager.PERMISSION_DENIED) {
this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, PERMISSION_DENIED_ERROR));
System.out.println("PHOTO DEBUG - " + r);
return;
}
*/
}
switch (requestCode) {
case TAKE_PIC_SEC:
takePicture(this.destType, this.encodingType);
break;
case SAVE_TO_ALBUM_SEC:
this.getImage(this.srcType, this.destType);
break;
}
}
If I comment this section about comparing value of r and PackageManager.PERMISSION_DENIED value, camera and gallery work good. It means we are always getting -1 value even if we allow permissions. I'm not Android Expert but i try to get explanations, how to fix this permission section
Is there any work to actually fix this issue? The solution above me doesn't seem that fitting since it can crash the application if the user declines to give access to the camera/gallery. Is there a reason why all the grantResults
are -1
for android 13?
hello.. any update for this issue.
Hi all, is there any information on this issue and if/when it's planned to be fixed? Regards
This pull request is related : https://github.com/apache/cordova-plugin-camera/pull/814
I am hoping for this bug to be fixed too. It is producing strange results where the gallery refuses to open on Android 33 Emulator, but works fine on my Pixel 7 with Android 13.
Is there a reason why all the
grantResults
are-1
for android 13?
Because Google changed permission requirements with Android 13
https://developer.android.com/about/versions/13/behavior-changes-13?hl=en
Before Android 13 the permission requested was READ_EXTERNAL_STORAGE
With Android 13 and higher (SDK version >= 33) this permission was divided in three: Images, Video and Audio. For this plugin we just need images, thus with Android 13 and higher we will need to request READ_MEDIA_IMAGES
It should be noted this just happens for new installations
if your app was previously granted the READ_EXTERNAL_STORAGE permission, then any requested READ_MEDIA_* permissions are granted automatically when upgrading
@breautek I was digging into the repo and READ_EXTERNAL_STORAGE
just pops up in /src/android/CameraLauncher.java
. I guess we should have some sort of global switch that replaces READ_EXTERNAL_STORAGE
by READ_MEDIA_IMAGES
when faced with Android 13 or higher (SDK version >= 33). This will be backwards compatible because, as said if READ_EXTERNAL_STORAGE
was already granted in Android 12 or lower and user upgraded to Android 13, READ_MEDIA_IMAGES
is granted automatically.
@Houdhey now I have no access to my test PC, but instead of commenting that portion of code, can you kindly just make another test? Can you try to replace all the READ_EXTERNAL_STORAGE
entries by READ_MEDIA_IMAGES
in /src/android/CameraLauncher.java
and see if it works in a new installation in Android 13? Pleeease ;)
Hello @jfoclpf
Yes, there is a similar Pull Request doing this : https://github.com/apache/cordova-plugin-camera/pull/814/files
Now the problem is fixed, I can't reproduce the bug.
Thank you for your investigation @jfoclpf , and thanks to all investigators. I can close
@Houdhey but did you solve the problem with that PR or by commenting the code as you've shown above?
Commenting the code is not sufficient, so the PR solved it, that's the hack i was using actually but i should've make a PR
Just to clarify, I should install plugin like this
cordova plugin add https://github.com/apache/cordova-plugin-camera.git#pull/814
Just temporarily obviously, till it is integrated and deployed into NPM repository
Actually, at the time I opened this bug, I was using this plugin with Capacitor 2.0 (I don't know if they totally replaced Cordova). So my installation process was : npm install@ionic-native/camera && npm install cordova-plugin-camera
Now, I don't work anymore on this project, so I created a new Ionic Project, and installed same versions that was bugging at the time. With this : npm install@ionic-native/[email protected] && npm install [email protected] And with this new project, Camera is working. But it uses Capacitor 4
I couldn't update Capacitor in my project, in the time I opened this bug. So if you still have this bug, I recommend you to upgrade latest version of Capacitor.
If you need more help, we can see this in a private conversation
Hi ,
I tried to use the PR but i still can't build 🤔
I got this error :
This is my setup :
Hi , I tried to use the PR but i still can't build 🤔 I got this error :
This is my setup :
![]()
![]()
Show your full AndroidManifest.xml file
@Houdhey @keva91 this issue was already discussed on the PR. It is due to manifest merge conflicts with other plugins using WRITE_EXTERNAL_STORAGE permission without setting android:maxSdkVersion="32" in their manifest.
As discussed on the PR #814 , the android:maxSdkVersion="32" constraint should be removed from the PR as it would create issues for most people.
Also, from my tests, #814 PR has also another issue with DATA_URI output.
I forked this PR to solve both issues here : https://github.com/felicienfrancois/cordova-plugin-camera
@felicienfrancois
I tried your fork and yes i can build now but i still get the error '20' on android 13 phone.
@keva91 read this comment
Try using PR #814 as you did before and try to guess which plugin is creating the conflict, the one which uses WRITE_EXTERNAL_STORAGE
without setting android:maxSdkVersion
Can you show us your list of plugins?
@keva91 thank you for your feedback, I have not submitted my fork as a PR yet because it deserve tests and adjustment on the required permissions at runtime, depending on case. I personaly use it with success, in DATA_URI mode.
Can you tell me what parameters do you use ? Which mode ? DATA_URI ? FILE ? Taking photo or picking from library ?
Also, you can try thoose different versions :
-
READ_MEDIA_IMAGES Always requested (Same as PR #814 )
https://github.com/felicienfrancois/cordova-plugin-camera#f53d3cb2ef5add8f7ba37503c4a10fc8e1337600
-
READ_MEDIA_IMAGES Never requested (The one I use)
https://github.com/felicienfrancois/cordova-plugin-camera#e6e49b85b59263fc5782e835160d01a8932e3690
-
READ_MEDIA_IMAGES requested only when picking from library (Head, i.e. the one you tried)
https://github.com/felicienfrancois/cordova-plugin-camera#efcd9190d98130d815b442b96e0c69fe17637908
As far as I understand, the READ_MEDIA_IMAGES should not be requested as it may not be granted (even refused without prompt in my case) and it is not necessary, at least in my case. But maybe it is needed when using FILE mode
@keva91 read this comment
Try using PR #814 as you did before and try to guess which plugin is creating the conflict, the one which uses
WRITE_EXTERNAL_STORAGE
without settingandroid:maxSdkVersion
Can you show us your list of plugins?
@keva91 thank you for your feedback, I have not submitted my fork as a PR yet because it deserve tests and adjustment on the required permissions at runtime, depending on case. I personaly use it with success, in DATA_URI mode.
Can you tell me what parameters do you use ? Which mode ? DATA_URI ? FILE ? Taking photo or picking from library ?
Also, you can try thoose different versions :
- READ_MEDIA_IMAGES Always requested (Same as PR Android 13 support #814 )
https://github.com/felicienfrancois/cordova-plugin-camera#f53d3cb2ef5add8f7ba37503c4a10fc8e1337600
- READ_MEDIA_IMAGES Never requested (The one I use)
https://github.com/felicienfrancois/cordova-plugin-camera#e6e49b85b59263fc5782e835160d01a8932e3690
- READ_MEDIA_IMAGES requested only when picking from library (Head, i.e. the one you tried)
https://github.com/felicienfrancois/cordova-plugin-camera#efcd9190d98130d815b442b96e0c69fe17637908
As far as I understand, the READ_MEDIA_IMAGES should not be requested as it may not be granted (even refused without prompt in my case) and it is not necessary, at least in my case. But maybe it is needed when using FILE mode
I use FILE_URI with few parameters when i try to take a photo :
@felicienfrancois I'll try those different versions thank you 😉
Also, you can try thoose different versions :
- READ_MEDIA_IMAGES Always requested (Same as PR Android 13 support #814 )
https://github.com/felicienfrancois/cordova-plugin-camera#f53d3cb2ef5add8f7ba37503c4a10fc8e1337600
android 13: ❌ android 11: ✅ android 10: ✅
- READ_MEDIA_IMAGES Never requested (The one I use)
https://github.com/felicienfrancois/cordova-plugin-camera#e6e49b85b59263fc5782e835160d01a8932e3690
android 13: ✅ android 11: ✅ android 10: ✅
- READ_MEDIA_IMAGES requested only when picking from library (Head, i.e. the one you tried)
https://github.com/felicienfrancois/cordova-plugin-camera#efcd9190d98130d815b442b96e0c69fe17637908
android 13: ❌ android 11: ✅ android 10: ✅
So the one you're using is working for me as well
@keva91 ok, thank you. So PR #814 has definitelly an issue with READ_MEDIA_IMAGES.
According to android doc this permission is required when accessing images on external storage or created by other apps so there may still be cases where it is needed.
I just made another change on my fork (adding READ_MEDIA_IMAGES to manifest), if you want to test it:
https://github.com/felicienfrancois/cordova-plugin-camera#7d66143ed55d817676c10a460c66938519d4b85b
@keva91 ok, thank you. So PR #814 has definitelly an issue with READ_MEDIA_IMAGES. According to android doc this permission is required when accessing images on external storage or created by other apps so there may still be cases where it is needed. I just made another change on my fork (adding READ_MEDIA_IMAGES to manifest), if you want to test it:
https://github.com/felicienfrancois/cordova-plugin-camera#7d66143ed55d817676c10a460c66938519d4b85b
It works too. And it also prompt for permissions which is better i think :)
@felicienfrancois regarding your repo and user permissions, should't your add min and max sdk versions to avoid excessive user permissions requests ? That is:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" android:minSdkVersion="33" />
I see @felicienfrancois , I tested now, although correct my suggestions they are more likely to create conflicts with other plugins as @keva91 experienced. I tested your repo and it works, thanks