Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 848
Benjamin Zach Avatar asked Nov 06 '19 11:11

Benjamin Zach


1 Answers

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
}
like image 125
Benjamin Zach Avatar answered Oct 18 '22 00:10

Benjamin Zach