Search code examples
androidunity-game-engineandroid-permissions

Unity + Android: How to ask for multiple permissions?


I'm working on a Unity (version 2019.1.11) project with target platform Android and I need to have the following permissions for my app to work:

android.permission.CAMERA
android.permission.RECORD_AUDIO
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_PHONE_STATE

The Unity documentation specifies this way to ask for Android permissions. My goal is to have an initial check for all required permissions during the start of the app, like this:

private void AskPermissions()
{
#if UNITY_ANDROID
    if (!Permission.HasUserAuthorizedPermission(Permission.Microphone))
    {
        Permission.RequestUserPermission(Permission.Microphone);
    }
    if (!Permission.HasUserAuthorizedPermission(Permission.Camera))
    {
        Permission.RequestUserPermission(Permission.Camera);
    }
    if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite))
    {
        Permission.RequestUserPermission(Permission.ExternalStorageWrite);
    }
    if (!Permission.HasUserAuthorizedPermission("android.permission.READ_PHONE_STATE"))
    {
        Permission.RequestUserPermission("android.permission.READ_PHONE_STATE");
    }
#endif
}

However, this does not work: The app only shows the dialog for the first permission that is not authorized and not for those not authorized that are being checked afterwards.

How can I ensure to always check for all permissions?


Solution

  • It seems that Permission.RequestUserPermission works somehow asynchronously and will not show a dialog when there's already a dialog shown - and therefore simply skips all other permissions after finding the first not authorized one.
    I could bypass the problem like this:

    private IEnumerator AskForPermissions()
    {
    #if UNITY_ANDROID
        List<bool> permissions = new List<bool>() { false, false, false, false };
        List<bool> permissionsAsked = new List<bool>() { false, false, false, false };
        List<Action> actions = new List<Action>()
        {
            new Action(() => {
                permissions[0] = Permission.HasUserAuthorizedPermission(Permission.Microphone);
                if (!permissions[0] && !permissionsAsked[0])
                {
                    Permission.RequestUserPermission(Permission.Microphone);
                    permissionsAsked[0] = true;
                    return;
                }
            }),
            new Action(() => {
                permissions[1] = Permission.HasUserAuthorizedPermission(Permission.Camera);
                if (!permissions[1] && !permissionsAsked[1])
                {
                    Permission.RequestUserPermission(Permission.Camera);
                    permissionsAsked[1] = true;
                    return;
                }
            }),
            new Action(() => {
                permissions[2] = Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite);
                if (!permissions[2] && !permissionsAsked[2])
                {
                    Permission.RequestUserPermission(Permission.ExternalStorageWrite);
                    permissionsAsked[2] = true;
                    return;
                }
            }),
            new Action(() => {
                permissions[3] = ermission.HasUserAuthorizedPermission("android.permission.READ_PHONE_STATE");
                if (!permissions[3] && !permissionsAsked[3])
                {
                    Permission.RequestUserPermission("android.permission.READ_PHONE_STATE");
                    permissionsAsked[3] = true;
                    return;
                }
            })
        };
        for(int i = 0; i < permissionsAsked.Count; )
        {
            actions[i].Invoke();
            if(permissions[i])
            {
                ++i;
            }
            yield return new WaitForEndOfFrame();
        }
    #endif
    }