ionic-team / capacitor-plugins

Official plugins for Capacitor ⚡️
486 stars 564 forks source link

Camera plugin 6.0 pickImages limit=1 ignored on Android 13+ #2119

Open mertyldrr opened 1 month ago

mertyldrr commented 1 month ago

Bug Report

Plugin(s)

@capacitor/camera

Capacitor Version

  @capacitor/cli: 6.0.0
  @capacitor/core: 6.0.0
  @capacitor/android: 6.0.0
  @capacitor/ios: 6.0.0

Platform(s)

Android 13+

Current Behavior

When calling pickImages() limit parameter is ignored if provided as limit: 1 on Android 13+.

Expected Behavior

Should consider provided limit

Code Reproduction

    const result: GalleryPhotos = await Camera.pickImages({
      limit: 1,
      presentationStyle: 'popover',
      quality: 85,
      width: 1394,
      height: 1859
    });
Ionitron commented 1 month ago

This issue needs more information before it can be addressed. In particular, the reporter needs to provide a minimal sample app that demonstrates the issue. If no sample app is provided within 15 days, the issue will be closed.

Please see the Contributing Guide for how to create a Sample App.

Thanks! Ionitron 💙

LuisWolf-Snapaddy commented 4 weeks ago

I also checked the behavior here in the camera plugin and currently the limit is ignored if it's set to 1. Setting it to 2 or greater works fine.

Talking to @mertyldrr it seems to crash when this logic is adjusted to >= 1 because PickMultipleVisualMedia needs the limit to be set to greater than one. I think the best case would be to use PickVisualMedia specifically if the limit is set to 1.


FYI: I also found here that pickImages always calls openPhotos with multiple set to true. Maybe one can also adjust this to extract the limit already at this stage of the call.

ryaa commented 5 days ago

The problem is that PickMultipleVisualMedia do not support maxItems = 1 and the app will crash with the below error, if 1 is provided as the argument to ActivityResultContracts.PickMultipleVisualMedia constructor

Caused by: java.lang.IllegalArgumentException: Max items must be higher than 1
                                                                                                        at androidx.activity.result.contract.ActivityResultContracts$PickMultipleVisualMedia.<init>(ActivityResultContracts.kt:879)
                                                                                                        at com.capacitorjs.plugins.camera.CameraPlugin.getContractForCall(CameraPlugin.java:340)
                                                                                                        at com.capacitorjs.plugins.camera.CameraPlugin.openPhotos(CameraPlugin.java:351)
                                                                                                        at com.capacitorjs.plugins.camera.CameraPlugin.pickImages(CameraPlugin.java:137)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method) 
                                                                                                        at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:138) 
                                                                                                        at com.getcapacitor.Bridge.lambda$callPluginMethod$0(Bridge.java:816) 
                                                                                                        at com.getcapacitor.Bridge.$r8$lambda$FNYM7cvgeBk0k8YXQH7M96Mrf-c(Unknown Source:0) 
                                                                                                        at com.getcapacitor.Bridge$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) 
                                                                                                        at android.os.Handler.handleCallback(Handler.java:958) 
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99) 
                                                                                                        at android.os.Looper.loopOnce(Looper.java:230) 
                                                                                                        at android.os.Looper.loop(Looper.java:319) 
                                                                                                        at android.os.HandlerThread.run(HandlerThread.java:67) 

~~I think that this should be at least reflected in the camera plugin documentation for the limit option of GalleryImageOptions section (see https://capacitorjs.com/docs/apis/camera#galleryimageoptions) or the required fix applied to the camera plugin as @LuisWolf-Snapaddy suggests. Please also see 4. PickMultipleVisualMedia do not support maxItems = 1 section here~~

UPDATE: Reviewing the camera plugin docs and source code more I think that no changes are required in the plugin source code. If the app intends to force selecting only single photo (limit == 1) it should use getPhoto camera plugin method (see https://capacitorjs.com/docs/apis/camera#getphoto) with the appropriate options. However I think, that to avoid any potential confusion the pickImages method docs (see https://capacitorjs.com/docs/apis/camera#galleryimageoptions) needs to be updated to mention that this method is intended to allow selecting 2+...unlimited photos and limit value of 0 or 1 are the same and means unlimited number of selection. For the single selection getPhoto should be used as pickImages with limit value 1 means unlimited selection.