Search Unity

Avoid asking for a milion permissions when app is installed

Discussion in 'Android' started by nsmith1024, Jan 21, 2020.

  1. nsmith1024

    nsmith1024

    Joined:
    Mar 18, 2014
    Posts:
    870
    Hello,

    I have an Unity app that uses the camera and microphone and some other stuff.

    However 99% of the time the user never has to use the microphone or camera unless they use a specific part of the app.

    Right now as soon as they install the app they get bombarded with all these permission requests, i assume because they are listed in the manifest, even though the program code isnt asking for permission at that time.

    All these permission request will turn most people off and they may just uninstall the app because it thinks why is it asking for all these permissions when im not using camera and microphone, they will think its a spy, virus, or spam app or something like that.

    Is there a way not to ask the user for permission until the user tries using that part of the app which requires asking for permission?

    For example if the user tries to use the part of the app that requires using the microphone, then the program will ask for permission at that time. the user will feel much better about that since they were the one who initiated that action, rather than getting bombarded with permission requests at the beginning.

    But because the permissions are in the manifest, the Android OS is asking for permission by itself without my program code doing it.

    Does anybody know how to ask for permission only when its needed by the program? It seems once permission is in the manifest Android asks for it during installation automatically.
     
  2. JuliusM

    JuliusM

    Unity Technologies

    Joined:
    Apr 17, 2013
    Posts:
    835
    Take a look at this page https://docs.unity3d.com/Manual/android-RequestingPermissions.html in short, you can add "unityplayer.SkipPermissionsDialog" meta-data to your Android manifest to not request permissions right when the app was launched and then you can use "Permission.HasUserAuthorizedPermission" and "Permission.RequestUserPermission" methods to check if the permission was already granted and to request the permission.
     
  3. nsmith1024

    nsmith1024

    Joined:
    Mar 18, 2014
    Posts:
    870
    I tried that but still the same, it immediately ask for permission to access photos and media files without my code asking for any permission or trying to use any of it. Heres my manifest

    <uses-feature android:name="android.hardware.camera" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="unityplayer.SkipPermissionsDialog"/>
    <uses-permission android:name="android.permission.FLASHLIGHT"/>
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     
  4. JuliusM

    JuliusM

    Unity Technologies

    Joined:
    Apr 17, 2013
    Posts:
    835
    That's incorrect. You have put it in the <manifest> element, but it has to be placed in either the <applicatoin> or <activity> elements. Also it has to be <meta-data> element, not <uses-permission>. So it should look something like this
    Code (CSharp):
    1. <manifest ... >
    2.   <application>
    3.     <meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />
    4.   </application>
    5.   <uses-feature android:name="android.hardware.camera" />
    6.   <uses-permission android:name="android.permission.INTERNET" />
    7.   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    8.   <uses-permission android:name="android.permission.FLASHLIGHT"/>
    9.   <uses-permission android:name="android.permission.CAMERA" />
    10.   <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    11.   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    12. </manifest>
     
  5. nsmith1024

    nsmith1024

    Joined:
    Mar 18, 2014
    Posts:
    870
    Thanks for the advice, i put it in the <application> section like you suggest, it does work in suppressing asking for permissions when the app installs and starts, but then the app doesnt work properly after that.

    By adding that one line my scene doesnt load after that. It just gets stuck, removing that line cures it. Here is the code

    Code (CSharp):
    1.        
    2.             GlobalData.assetBundle = null;
    3.             GlobalData.localAssetBundle = null;
    4.             GlobalData.loadedBundleScene = "main_7";
    5.             AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(GlobalData.loadedBundleScene, LoadSceneMode.Additive);
    6.             asyncLoad.allowSceneActivation = false;
    7.             Debug.Log("local scene downloading start...."+asyncLoad.isDone);
    8.             while (!asyncLoad.isDone) {
    9.                 if (asyncLoad.progress >= 0.9f) {
    10.                     asyncLoad.allowSceneActivation = true;
    11.                     Debug.Log("second phase decoding...");
    12.                 }
    13.                 Debug.Log("local load tick..." + asyncLoad.progress + " isDone="+asyncLoad.isDone);
    14.                 yield return null;
    15.                 yield return new WaitForSeconds(0.04f);
    16.             }
    17.             Debug.Log("async load local scene loop done:"+asyncLoad.isDone);
    18.             SceneManager.SetActiveScene(SceneManager.GetSceneByName(GlobalData.loadedBundleScene));
    19.             GlobalData.staticSceneLoaded = true;
    20.             Debug.Log("local load done...");
    So im in one scene (base scene), and trying to load another scene (the real game scene) on top of that.

    When I add the unityplayer.SkipPermissionsDialog to the <application> section to suppress asking for permission, the code above gets stuck in the loop above loading the scene, and never exists.

    It gets to where it says "second phase decoding" then prints out one last "local load tick" message" and stops after that.

    Removing that line from the manifest and it works normally. Dont know whats causing it except that line in the manifest, adding that one line causes the problem, removing that one line removes the problem.
     
  6. JuliusM

    JuliusM

    Unity Technologies

    Joined:
    Apr 17, 2013
    Posts:
    835
    Do you split application binary (https://docs.unity3d.com/Manual/android-OBBsupport.html) ? if so, the application probably needs a granted read external storage permission to be able to read OBB file (and to load the second scene from it). That will not work with SkipPermissionsDialog since the permission will not get granted. You have two options. Either don't split application binary or upgrade your project to at least Unity 2018LTS where runtime permissions are handled better and don't have to be requested at the start of the app. There Unity requests permissions at the moment when they are needed (when using Unity APIs), so you wouldn't even need to add SkipPermissionsDialog to your manifest.
     
  7. levilais

    levilais

    Joined:
    Jul 19, 2018
    Posts:
    8
    Can this be done for iOS
     
  8. highland87

    highland87

    Joined:
    Aug 12, 2015
    Posts:
    14
    @JuliusM Please share how to do this on iOS. Thank you!
     
  9. highland87

    highland87

    Joined:
    Aug 12, 2015
    Posts:
    14
    Dear JuliusM, please share how to do this on iOS, thank you!
     
  10. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,963
    iOS doesn't pop the permissions until you request for it (with a exception for internet permission which started showing recently). So check where actually the permission is being requested and only request it when you need it.

    On Android, until the introduction of Runtime permissions (from Android 6.0 I suppose), system used to request all the permissions at the start of the app. Later with the introduction of runtime permissions, display of it can be controlled similar to iOS.

    To avoid breaking builds while the migration happens (from non runtime to runtime permissions on Android), Unity came up(it's an intelligent workaround to not break the builds) with the idea of SkipPermissionsDialog meta data property which automatically fires permissions at start of the app. To avoid this behaviour and request as per your requirement, you can modify the SkipPermissionsDialog property.
     
    highland87 likes this.
  11. highland87

    highland87

    Joined:
    Aug 12, 2015
    Posts:
    14
    Dear Voxel-Busters, thank you so much for the information. A my own mistake makes the app request permission at launch. Thanks for your help!
     
    Voxel-Busters likes this.