yasirkula/UnityNativeCamera

Camera permission is always Denied after updating plugin from legacy version

novavision opened this issue · 12 comments

Description of the bug

NativeCamera.CheckPermission always returns Denied in both cases:

  1. before even asking the permission
  2. after the permission is granted and app has a camera cotnrol

Reproduction steps

  1. install legacy plugin using .unitypackage
  2. follow the steps adding entries to AndroidManifest.xml
  3. build apk
  4. remove NativeCamera from Assets/Plugins directory
  5. install latest plugin version addint git url to manifest.json
  6. build apk - bug appears

On iOS devices everything works fine.

  • Unity version: 2021.3.17
  • Platform: Android
  • Device: Xiaomi K20Pro
  • How did you download the plugin: GitHub

Additional info

I did a clean project test and plugin camera permission worked fine there on the same Android device. I checked the AndroidManifest and compared it to my real project AndroidManifest - I found there tags which had to be removed (as I understood from the documentation). Somehow it was cached even aftere removing the plugin.
I removed Library and Temp folders and reimported project. These entries has gone and AndroidManifest looks almost the same as in the clean project. However the bug still exists.

Have no idea what's wrong there.

If you had imported the plugin to your actual project a while ago, could you update it to the latest version? Note that you no longer need to modify the AndroidManifest in any way.

@yasirkula that's exactly what I described above...

  1. old legacy version didnt work even with AndroidManifest modification
  2. latest version doesn't work after importing plugin after legacy version removed. Library reimport also didn't help.

UPDATED

I just extracted the final manifest.xml from the build and still see these entries in it:

<activity
            android:theme="@ref/0x7f0e0113"
            android:name="com.yasirkula.unity.NativeShareCustomShareDialogActivity" />

        <provider
            android:name="com.yasirkula.unity.NativeShareContentProvider"
            android:exported="false"
            android:authorities="com.nanotec.koala.NativeShareContentProvider"
            android:grantUriPermissions="true" />
-----------
-----------
-----------
            <provider
            android:name="com.yasirkula.unity.NativeCameraContentProvider"
            android:exported="false"
            android:authorities="com.nanotec.koala.NativeCameraContentProvider"
            android:grantUriPermissions="true" />

The "com.yasirkula.unity.NativeCameraContentProvider" entry must exist there yeah. It doesn't say anywhere that it shouldn't exist. Instead, you should check which of the READ_EXTERNAL_STORAGE, CAMERA (optional) and WRITE_EXTERNAL_STORAGE permissions are declared there (final manifest).

I just followed the FAQ recommendation adding WRITE_EXTERNAL_STORAGE
Checked final manifest and
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
exist there. However I still always got Denied response

Just a note - I need the camera access only for AR Core feature using ARFoundation in Unity. I don't need to save anything to the storage or write from the storage.

I also treid to add READ_EXTERNAL_STORAGE, no effect.
But, the intersting thing that if I go to app native settings and manually enabled storage permission, the camera permission request shows the actual state....
But, I never see the storage runtime permission request dialog, and as I said I dont need that storage permission at all

NativeCamera also asks for storage permission on Android 12 or earlier because camera apps may save the image to the gallery rather than the path we've provided (it's Android ecosystem, we dare not question it...). That path can't be accessed without storage permission.

Perhaps the storage permission dialog had shown up before installing NativeCamera (don't know which plugin added it beforehand) and you've selected "Deny-Don't ask again" while rejecting it. Then, after installing NativeCamera, the permission dialog isn't asked because "Don't ask again" was selected in a previous session. If that's indeed the case, then uninstalling and then reinstalling the app should resolve the issue.

That's not that case for sure because I already reinstalled the app tons of time.
Also, I see that clean project where permission request shows proper value has no Camera permission in app settings, only Storage permission

And another note - I tried to check the permission status usign Unity method
Android.Permission.RequestUserPermission and it shows me proper value

The Camera permission is asked only if it's manually declared in AndroidManifest. That's an optional permission so it won't be asked if it's missing.

Can you replace this line as follows: AJC.CallStatic( "RequestPermission", Context, nativeCallback, isPicturePermission, (int) Permission.ShouldAsk );

I removed plugin from package manager (because I couldnt edit NativeCamera.cs) and imported it using unity package.
After the changes:

  1. before permission request the check permission returns Denied, not ShouldAsk as it happens on iOS
  2. At least after granting the permission it shows Granted.

Anyway, the worst here is that asking for camera permission I see 2 dialogs:

  1. Allow aoo to take pictures and record video?
  2. Allow app to access photos and media on your device?
    As I understood that's becasue the reason you described above, however, using my own implementation based on UnityEngine.Android.Permission API it asks ONLY for 1 permission.

Hmm, then I really don't know why it returns Denied on your project but not on a new project 😞

NativeCamera asks both Gallery and Camera access. Unless you do the same with Unity's permission API, you'll only see the permission that you're asking.

ArrayList<String> permissions = new ArrayList<String>( 3 );
if( NativeCameraUtils.IsPermissionDefinedInManifest( getActivity(), Manifest.permission.CAMERA ) )
permissions.add( Manifest.permission.CAMERA );
if( Build.VERSION.SDK_INT < 30 )
permissions.add( Manifest.permission.WRITE_EXTERNAL_STORAGE );
if( Build.VERSION.SDK_INT < 33 || getActivity().getApplicationInfo().targetSdkVersion < 33 )
permissions.add( Manifest.permission.READ_EXTERNAL_STORAGE );
else
{
boolean isPicturePermission = getArguments().getBoolean( PICTURE_PERMISSION_ID );
if( isPicturePermission )
permissions.add( "android.permission.READ_MEDIA_IMAGES" );
else
permissions.add( "android.permission.READ_MEDIA_VIDEO" );
}
String[] permissionsArray = new String[permissions.size()];
permissions.toArray( permissionsArray );
requestPermissions( permissionsArray, PERMISSIONS_REQUEST_CODE );

I assume AR Foundation (AR Core) somehow may affect it, but in my case I disable ARSession on Awake and enable it only after permission granted. This prevents AR foudnation request that camera permission automatically and lets me control it.

Anyway, seems it's not the best option to use this plugin for my case - 2 requests instead of 1 is not what I need for sure.

Thanks for the support

And thank you for trying to debug this issue and providing all the useful information 🙂