Android permissions resolve immediately

I want to use the camera. For this I need a permission to the camera.
I’m using ionic 6 with android API 29.
Here I see the note about Android 26 and above that resolve permissions immediately, but I didn’t find all over the web even one single example of how to do it.
I tried a lot of options but all failed. The permission is not really called and I can’t use the camera.
Any help will be very appreciated.
This is my code for now:

this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.CAMERA).then(res => {
      this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.CAMERA).then( per => {
        console.log(per);
      })
    })
this.camera.getPicture({
      sourceType: this.camera.PictureSourceType.CAMERA,
      destinationType: this.camera.DestinationType.FILE_URI
    })
    .then((res) => 
    {
      this.imgURL = res;
    })
    .catch(e => 
    {
      console.log(e);
    })

Before anything else, ensure problems persist when using released and supported versions. I think Ionic 6 is barely out of alpha.

Are you sure? This is the default version I get when I download ionic.
This is the specific version:

> ionic --version                 
6.13.1

  ─────────────────────────────────────────────────

     Ionic CLI update available: 6.13.1 → 6.16.3   
          Run npm i -g @ionic/cli to update        

  ─────────────────────────────────────────────────

That is your CLI, not your framework version.

Check your package.json or paste the output from ionic info

Ohh sorry.
Here is it:

> ionic info

Ionic:

   Ionic CLI                     : 6.13.1 
   Ionic Framework               : @ionic/angular 5.5.4
   @angular-devkit/build-angular : 0.1102.5
   @angular-devkit/schematics    : 11.2.5
   @angular/cli                  : 11.2.5
   @ionic/angular-toolkit        : 3.1.1

Cordova:

   Cordova CLI       : 10.0.0
   Cordova Platforms : 6.0.0, android 9.1.0, browser
   Cordova Plugins   : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 5.0.0, (and 10 other plugins)

Utility:

   cordova-res : 0.15.3
   native-run  : 1.4.0

System:

   Android SDK Tools : 26.1.1 
   NodeJS            : v14.16.1 
   npm               : 6.14.12
   OS                : Windows 10

I tried to move to capacitor.
I use this code to access the camera:

takePicture()
  {
    const takePicture = async () => {
      const image = await Camera.getPhoto({
        quality: 90,
        allowEditing: true,
        resultType: CameraResultType.Uri
      });
    
      // image.webPath will contain a path that can be set as an image src.
      // You can access the original file using image.path, which can be
      // passed to the Filesystem API to read the raw data of the image,
      // if desired (or pass resultType: CameraResultType.Base64 to getPhoto)
      var imageUrl = image.webPath;
    
      // Can be set to the src of an image now
      //imageElement.src = imageUrl;
    };
  }

I have breakpoint on the first line of the function, but I never get into the second line (getPhoto). I tried on 2 devices.
What can be the root cause of such behaviour?
Anti-virus? It seems like something in the whole system.

This is probably going to end up being a very silly post, which you can feel free to completely ignore.

But I read your code the same way the debugger apparently does: that takePicture doesn’t actually do anything. It assigns a function to a variable that is then never to be heard from again.

I would recommend (temporarily, at least) banning use of the following keywords in your code:

  • async
  • await
  • const
  • var

The first two because they obscure the actual code that is being executed, which can make debugging problems like this much harder than it has to be. The second two because they are frankly simply insane: they don’t do what you think they do, and what they do do is pretty much useless.

Any time you are tempted to use const, try substituting readonly. If that’s not a contextual fit, replace it with a function that returns an object reference that is never reused. Any time you’re tempted to use var, use let instead.

If you’re still reading, I’m not out of preachy annoying advice yet.

Declare return types for every function you write. If any function ever gets any information from an asynchronous source (takePicture qualifies here), then make the first word of its body be return.

If you follow that advice, TypeScript will protect you from bugs like the one you seem to have here. You have to think about what takePicture returns, and since it needs to derive from a future, that has to be a future (either a Promise or Observable).

You will end up with something that looks like this:

takePicture(): Promise<string> {
  return Camera.getPhoto({...})
    .then(image => image.webPath);
}

No async, no await, no const, no var, no unexecuted functions, and it should be clear at a glance what callers of takePicture can expect to get, both as documentation and rules the build tools can enforce.

I really love your silly posts, they are just simple and brilliant!
Thank you very much, with your good explanation I succeed to make it work!

1 Like