capacitor: bug: Camera cannot select picture from Redmi Gallery app
Bug Report
Capacitor Version
npx cap doctor
output:
Installed Dependencies:
@capacitor/ios not installed
@capacitor/core 1.2.1
@capacitor/cli 1.2.1
@capacitor/android 1.2.1
Affected Platform(s)
- Android
- iOS
- Electron
- Web
Current Behavior
Using the Camera plugin on Android Redmi phones, when a picture is selected in the Gallery app, this error is thrown: Unable to process image. It doesn’t manifest itself with other apps (e.g. File Manager) and also there was no problem with the Cordova plugin which we used before upgrading to Capacitor.
Expected Behavior
Users are able to use the default Gallery app to select their pictures on Redmi phones.
Sample Code or Sample Application Repo
This is the config we use:
const options: CameraOptions = { quality: 30, resultType: CameraResultType.Uri, allowEditing: false, source: CameraSource.Photos, };
Reproduction Steps
Configure the Camera plugin to return a Uri and use the option to select a picture from gallery instead of taking a new photo.
Other Technical Details
- Phone: Redmi 6A/Redmi Note 7
- Android version: 8.1/9
- MIUI version: 10.3.6/10.3.6
Other Information
I suspect the bug concerns other MIUI devices, such as Xiaomi phones. I managed to track down the problem to saveTemporaryImage method in Camera.java. contentUri.getlastPathSegment tries to select the filename and a copy of the file is created in the cacheDir.
However, contentUri from the Gallery app has this format: content://com.miui.gallery.open/raw/%2Fstorage%2Femulated%2F0%2FDCIM%2FCamera%2FIMG_20191013_191506.jpg
while the other apps return unescaped slashes in the path, e.g. content://com.mi.android.globalFileexplorer.myprovider/external_files/DCIM/Camera/IMG_20191013_191506.jpg
I created an easy solution for our app (using a random filename) but this is probably a symptom of a more serious issue and I don’t know what the proper fix would be. Is it enough to just unescape the path?
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 5
- Comments: 30 (4 by maintainers)
As no one from the Capacitor team has replied, I’ll at least give you a workaround.
patch-camera.js
in the project root folder with this content:As you can see, this fix is very fragile as it relies on the specific
node_modules
path and Java source code. This ensures that a timestamp is used for the file name instead of the broken name from the Gallery app.postinstall
script to yourpackage.json
to patch the Capacitor source code.This automatically runs the fix after
npm install
and works perfectly with @capacitor/android": “^1.2.1”. We haven’t updated to 1.3 yet.On Samsung 21 I get the error: (via logcat in android studio)
This happens when (as a user) I attempt to add an image from the stock gallery.
WORKS with camera
I encountered this issue on an old Samsung Galaxy J3, the problem persisted even after an upgrade to capacitor@3. I downgraded the capacitor back to v2, as I have a problem debug the native code of the plugins in v3, and found out the exception is thrown in code that corrects the orientation of the image.
Solution
By disabling rotation with
correctOrientation: false
I resolved my issue.Further investigation
I got a
from the
prepareBitmap
functionby digging deeper, it turned out, that the failing code was
imageUri.getPath()
, a quick search revealed a StackOverflow thread where this comment notesI’m a newbie in Android development, but it seems that the Samsung Gallery does not provide a regular file URI, thus the Camera plugin must use
ContentProvider
to handle the URI.Additional informations
I checked the capacitor v3 Camera plugin source code and it seems to me that it is exposed to the same issue by using
Uri.getPath()
, but I did not test it, as I have a problem debug the native code of capacitor v3. Also, during the debug of capacitor v2, I realized, that I completely miss the Gradle variablewhich might be necessary for the Camera plugin to work correctly, but on Capacitor v2, the Camera plugin worked even without this variable.
We’ve also had a few users also state that image uploading is not working across the Samsung device list only; Pixels seem to be unaffected by this. Not to repeat what @czabaj has said, but I’m also thinking it’s to do with Samsung’s photo gallery returning incorrectly, although the specific error i get is
/external/images/media/389: open failed: ENOENT (No such file or directory)
. As stated,correctOrientation: false
does solve the issue but leaves the returned image rotated 90 degrees anticlockwise. This has occurred after our apps migration to capacitor 3 and was not a problem on v2.As a temporary work around, you can turn the lines here in the plugin (android/capacitor-camera/src/main/java/com.capacitorjs.plugins.camera/ImageUtils) to the following:
and rebuilding should allow it to work for now.
This fix works for me with a Xiaomi. Does anyone knows if the Capacitor team is on it ?
Hello, I am facing this same problem with xiaomi. Our business really needs the camera and our customers are complaining. I think I will try this workaround, but is there any prediction of a definitive solution?