Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

[Open Source] AndroidRuntimePermissions - manage runtime permissions "synchronously" on Android M+

Discussion in 'Assets and Asset Store' started by yasirkula, Apr 28, 2018.

  1. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    Please send me the full error message with full stacktrace.
     
    gaglabs likes this.
  2. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    I found the issue. It was placing the AndroidRuntimePermission folder inside Plugins. I just removed it and placed it in Asset Folder and it worked.
     
    yasirkula likes this.
  3. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    It works for me inside Plugins folder but happy to hear that this change somehow resolved the issue for you.
     
    gaglabs likes this.
  4. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    Yeah i'm not sure either. It just wouldn't find your script while inside Plugins. Odd thing lol.
     
  5. DanielDorDev

    DanielDorDev

    Joined:
    Dec 2, 2019
    Posts:
    4
    What is it differ from
    if (Permission.HasUserAuthorizedPermission(Permission.Camera) is false)
    {
    Permission.RequestUserPermission(Permission.Camera);
    }

    Thank you
     
  6. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    Unity's built-in Permission API is asynchronous and it didn't support permission callbacks up until a very recent Unity release, so there was no way to know whether or not the user had accepted the permission after the RequestUserPermission call.

    My permission plugin works synchronously, so you ask the permission at line 1, then you can execute your logic at line 2. No need to use callback functions.
     
  7. danUnity

    danUnity

    Joined:
    Apr 28, 2015
    Posts:
    229
    @yasirkula After implementing the asset, I have noticed that when a user denies Permission, the next time it does not return ShouldAsk.. It just returns Denied right away. Any reason why that might be?

    Here's the function I call every time I want to check permission:

    TriggerOutputEvent1 is when it's Granted (The execution continues )
    TriggerOutputEvent2 is when it's Denied ( I show a message informing the user to go to their settings by pressing OK)

    I would expect the ShouldAsk to be always called except if Never Ask Again is pressed by the user.

    Anything I'm doing wrong here?

    Code (CSharp):
    1.  
    2. private void CheckAndroidPermission(PermissionType permissionType, string requestID = "") {
    3.             AndroidRuntimePermissions.Permission result = AndroidRuntimePermissions.CheckPermission(PermissionAndroidTypes[(int)permissionType]);
    4.             if (result == AndroidRuntimePermissions.Permission.Granted) {
    5.                 TriggerOutputEvent1(permissionType, requestID);
    6.             } else if (result == AndroidRuntimePermissions.Permission.Denied) {
    7.                 TriggerOutputEvent2(permissionType, requestID);
    8.             } else if (result == AndroidRuntimePermissions.Permission.ShouldAsk) {
    9.                 result = AndroidRuntimePermissions.RequestPermission(PermissionAndroidTypes[(int)permissionType]);
    10.                 if (result == AndroidRuntimePermissions.Permission.Granted) {
    11.                     TriggerOutputEvent1(permissionType, requestID);
    12.                 } else if (result == AndroidRuntimePermissions.Permission.Denied) {
    13.                     TriggerOutputEvent2(permissionType, requestID);
    14.                 } else if (result == AndroidRuntimePermissions.Permission.ShouldAsk) {
    15.                     CheckAndRequestPermission(permissionType);
    16.                 }
    17.             }
    18.         }
    19.  
     
  8. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    Can't see anything wrong. It's an unexpected behaviour and I can't recall any reasons for it. What is your Android version?

    P.S. You can open app's Settings programmatically via OpenSettings function.
     
  9. danUnity

    danUnity

    Joined:
    Apr 28, 2015
    Posts:
    229
    My android version is 8.0.0 on the phone! Yeah, I could not figure out why if the user Denied the first time, it wouldn't just ask again the next time so I ended up reverting to the Unity Native way of handling permissions.

    Ah yes, I still use the OpenSettings function of your asset! I wish it was opening the Permission sub category of the settings directly though, now the user has to scroll down and find the Permission section. Not a big deal but I like to keep things simple for the user!

    Let me know if you find the issue there :)
     
  10. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    I've tested this code:
    Code (CSharp):
    1. AndroidRuntimePermissions.Permission result = AndroidRuntimePermissions.CheckPermission( "android.permission.WRITE_EXTERNAL_STORAGE" );
    2. if( result == AndroidRuntimePermissions.Permission.Granted )
    3. {
    4.     Debug.Log( "granted" );
    5. }
    6. else if( result == AndroidRuntimePermissions.Permission.Denied )
    7. {
    8.     Debug.Log( "denied" );
    9. }
    10. else if( result == AndroidRuntimePermissions.Permission.ShouldAsk )
    11. {
    12.     result = AndroidRuntimePermissions.RequestPermission( "android.permission.WRITE_EXTERNAL_STORAGE" );
    13.     Debug.Log( "should ask " + result );
    14. }
    As long as I don't click "Don't ask again", it outputs "should ask ShouldAsk" to logcat. When I allow the permission, it outputs "should ask Granted" to logcat. Can you give this one a try on an empty project? Just don't forget to set "Write Permission" to "External (SD Card)" in Player Settings.

    Android doesn't provide a method to open permission settings directly, hence opening app's settings is the best we can do :D
     
  11. marcusferron

    marcusferron

    Joined:
    Oct 22, 2018
    Posts:
    3
    Hello friends! I'm developing a game that needs permission for the microphone.
    I heard about the plugin, downloaded it, imported it into my project, but now I don't know
    even how to start (I'm a newbie). What code do I write? What is Androi.manifest? Can someone help me? I'll be very thankfull!
     
  12. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    The easiest way to add microphone permission would be to add a dummy
    Microphone.IsRecording(null);
    line to one of your scripts and let Unity automatically add the permission to manifest for you (if you are already using Microphone API, no need to add a dummy IsRecording call then).

    To request the permission at runtime:
    Code (CSharp):
    1. AndroidRuntimePermissions.Permission result = AndroidRuntimePermissions.RequestPermission( "android.permission.RECORD_AUDIO" );
    2. if( result == AndroidRuntimePermissions.Permission.Granted )
    3.     Debug.Log( "We have permission to record audio!" );
    4. else
    5.     Debug.Log( "We don't have permission: " + result );
     
  13. Utarastas

    Utarastas

    Joined:
    Jul 27, 2017
    Posts:
    11
    I ran into similar issue as you did, your comments provided to be very useful when debugging this. Im running Unity 2019.4.24f, with Android target of API 29. Initially, the pedometer API didnt work, it would simply not start as long as I was building for API level 29, I tested it with level 28, and it worked pretty well. Then changed the AndroidManifest (you need to enable custom android manifest in Player Settings/Publishing settings first) to this:

    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <manifest
    3.     xmlns:android="http://schemas.android.com/apk/res/android"
    4.     package="com.unity3d.player"
    5.     xmlns:tools="http://schemas.android.com/tools">
    6.     <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
    7.     <uses-feature android:name="android.hardware.sensor.accelerometer" />
    8.     <application>
    9.         <activity android:name="com.unity3d.player.UnityPlayerActivity"
    10.                   android:theme="@style/UnityThemeSelector">
    11.             <intent-filter>
    12.                 <action android:name="android.intent.action.MAIN" />
    13.                 <category android:name="android.intent.category.LAUNCHER" />
    14.             </intent-filter>
    15.             <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    16.         </activity>
    17.     </application>
    18. </manifest>
    In Unity, I would ask for the permission the same way you did:
    Code (CSharp):
    1.  
    2.  private void Awake()
    3.          {
    4.              AndroidRuntimePermissions.Permission result = AndroidRuntimePermissions.RequestPermission("android.permission.ACTIVITY_RECOGNITION");
    5.              if (result == AndroidRuntimePermissions.Permission.Granted)
    6.              {
    7.                  Debug.Log("We have permission to access the stepcounter");
    8.                 Debug.LogError("PERMISSION GRANTED");
    9.              }
    10.              else
    11.              {
    12.                  
    13.                  Debug.LogError("NO PERMISSION");
    14.            
    15.                  Debug.Log("Permission state: " + result); // No permission
    16.                  
    17.              }
    18.          }
    19.  
    At the time I was building using Mono scripting backend, the build would be successful, but it still wouldnt ask for permission. Then I changed scripting backend to IL2CPP, but then the build would fail with an IL2CPP error. I solved the error by deleting libPedometer.a (iOS library for this API, I imagine). Finally the build was successful, and the application asked for permission to use Activity data, and the pedometer would start tracking steps. Hopefully someone can find this useful
     
    yasirkula likes this.
  14. DLight

    DLight

    Joined:
    Oct 7, 2012
    Posts:
    15
    I want to access once the uart bridge controller, But every time I pluged in it ask again. This asset is solve the problem?
    thx
     
  15. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    This plugin asks permissions like Storage and Location on Android devices. I don't know about UART Bridge Controller. Are you also talking about such an Android permission?
     
  16. DLight

    DLight

    Joined:
    Oct 7, 2012
    Posts:
    15
    I connect a device via CP2102. And every USB plugin it ask toe allow UART Bridge controller.
     
  17. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    I don't think it can be resolved with my plugin. The permissions I'm talking about aren't asked again if the permission is granted.
     
  18. DLight

    DLight

    Joined:
    Oct 7, 2012
    Posts:
    15
    My problem is the constant re-asking when I plug in the USB again. It will good to be for this? Just ask once. Then I unpluge than plugin the usb don't ask?
     
  19. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    No it won't resolve your issue.
     
  20. DLight

    DLight

    Joined:
    Oct 7, 2012
    Posts:
    15
    I will search another way. Thx the respons
     
    yasirkula likes this.
  21. awcheng

    awcheng

    Joined:
    Apr 16, 2018
    Posts:
    1
    Hey Yasirkula! Thanks for the awesome package!

    I'm currently on Unity 2020.3.18f1 LTS, running on an Android phone with Android 11 (OnePlus 7 Pro).

    I'm having some issues where if I've denied a particular permission once before, but then gone into the app settings and then allowed permissions and restarted the app,
    AndroidRuntimePermissions.RequestPermission
    still always comes back with a result of 'denied'. Is this a case of the app caching the denied status forever if it has been selected once? Is there any way to get the permissions pop up to come back without uninstalling and re-installing the app? (or telling the user to delete cache/app data from settings)
     
  22. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    The permission is cached but it shouldn't cause this issue. Can you change this line so that it always returns Permission.ShouldAsk and see if it has any effect? Please reinstall the app from scratch while testing it.
     
  23. Ikaro88

    Ikaro88

    Joined:
    Jun 6, 2016
    Posts:
    280
    I installed your plugin

    But if I call
    AndroidRuntimePermissions the visual studio not recognize it....
     
  24. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    Please try Edit-Preferences-External Tools-Regenerate project files.
     
    Ikaro88 likes this.
  25. DeanerWiener

    DeanerWiener

    Joined:
    Oct 2, 2019
    Posts:
    1
    Hey there, I'm trying to access CPU usage and fan speed using this class in the android API https://developer.android.com/reference/android/os/HardwarePropertiesManager

    However this seems to require the DEVICE_POWER permission. I thought I would give this package a try, but for some reason calling

    AndroidRuntimePermissions.RequestPermission("android.permission.DEVICE_POWER");
    does not show any permission dialogue in the app, and always returns Denied.

    My manifest looks like this:
    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <!-- GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN-->
    3. <manifest
    4.     xmlns:android="http://schemas.android.com/apk/res/android"
    5.     package="com.unity3d.player"
    6.     xmlns:tools="http://schemas.android.com/tools">
    7.     <application>
    8.         <activity android:name="com.unity3d.player.UnityPlayerActivity"
    9.                   android:theme="@style/UnityThemeSelector">
    10.             <intent-filter>
    11.                 <action android:name="android.intent.action.MAIN" />
    12.                 <category android:name="android.intent.category.LAUNCHER" />
    13.             </intent-filter>
    14.             <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    15.         </activity>
    16.     </application>
    17.  
    18.     <permission android:name="android.permission.DEVICE_POWER"/>
    19.     <uses-permission android:name="android.permission.DEVICE_POWER"/>
    20. </manifest>
    21.  
     
  26. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
  27. Leuki

    Leuki

    Joined:
    Feb 27, 2014
    Posts:
    130
    Had the same issue. AndroidRuntimePermissions folder was in Plugins folder and AndroidRuntimePermission wasn't finding the reference because of it. Moving the folder to assets worked.
     
    yasirkula likes this.
  28. mkg2w

    mkg2w

    Joined:
    Aug 19, 2013
    Posts:
    49
    Hi With the change made last week (~11th July 2023), CheckPermission now returns a Boolean.
    How does one now distinguish between a Denied and a ShouldAsk ?
     
  29. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    @mkg2w For extensive discussion about this topic, you can check out the posts in the Discord channel. tl;dr Android has never returned an enum while checking for permission but we could work around it using an unofficial approach. This approach can now return incorrect values on newer Android versions if the permission is modified via Settings, so it's safer to follow Android's official approach and just return a bool.
     
    Last edited: Jul 20, 2023
  30. EndurScape

    EndurScape

    Joined:
    Jul 22, 2023
    Posts:
    1
    Please help me tell how to request runtime permission with script
     
  31. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
  32. fanstrain

    fanstrain

    Joined:
    Jan 2, 2021
    Posts:
    1
    i am using this plugin for showing post notification permission. its works in android 13 but not showing a permission in android 10, 11 and always return status denied. am i missing something?
     
  33. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,783
    @fanstrain IIRC, that permission was introduced on Android 12 or 13.