#if UNITY_ANDROID using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Android; namespace RenderHeads.Media.AVProVideo { public class RequestPermissions : MonoBehaviour { private IEnumerator Start() { switch (HasUserAuthorisation()) { case AuthorisationStatus.Authorised: // All good, nothing to do break; case AuthorisationStatus.Unavailable: // Unavailable break; case AuthorisationStatus.Denied: // User has denied, change output path Debug.LogWarning("User has denied"); break; case AuthorisationStatus.NotDetermined: // Need to ask permission yield return RequestUserAuthorisation(); // Nested switch, everbodies favourite switch (HasUserAuthorisation()) { case AuthorisationStatus.Authorised: // All good, nothing to do break; case AuthorisationStatus.Denied: // User has denied access, change output path Debug.LogWarning("User has denied access"); break; case AuthorisationStatus.NotDetermined: // We were unable to request access for some reason, check the logs for any error information Debug.LogWarning("Authorisation to access is still undetermined"); break; } break; } } public enum AuthorisationStatus { Unavailable = -1, NotDetermined, Denied, Authorised }; private static bool _hasRequestedAuthorisation = false; private static AuthorisationStatus _authorisationStatus = AuthorisationStatus.NotDetermined; private static string AndroidPermissionReadMediaVideo = "android.permission.READ_MEDIA_VIDEO"; private static int _androidSdkLevel = -1; private static int GetAndroidSDKLevel() { if (_androidSdkLevel == -1) { var clazz = AndroidJNI.FindClass("android/os/Build$VERSION"); var fieldID = AndroidJNI.GetStaticFieldID(clazz, "SDK_INT", "I"); _androidSdkLevel = AndroidJNI.GetStaticIntField(clazz, fieldID); } return _androidSdkLevel; } public static AuthorisationStatus HasUserAuthorisation() { if (_authorisationStatus == AuthorisationStatus.NotDetermined) { bool authorised = Permission.HasUserAuthorizedPermission(AndroidPermissionReadMediaVideo); if (authorised) { _authorisationStatus = AuthorisationStatus.Authorised; _hasRequestedAuthorisation = true; } else if (_hasRequestedAuthorisation) { _authorisationStatus = AuthorisationStatus.Denied; } } Debug.Log($"HasUserAuthorisation - {_authorisationStatus}"); return _authorisationStatus; } #if UNITY_2020_2_OR_NEWER private static bool _waitingForAuthorisation = true; private class WaitForAuthorisation : CustomYieldInstruction { public override bool keepWaiting { get { return _waitingForAuthorisation; } } } public static CustomYieldInstruction RequestUserAuthorisation() { if (_authorisationStatus == AuthorisationStatus.Authorised) { // Already authorised return null; } if (_hasRequestedAuthorisation && _authorisationStatus == AuthorisationStatus.Denied) { // Already been denied, nothing to do return null; } PermissionCallbacks callbacks = new PermissionCallbacks(); callbacks.PermissionDenied += (permission) => { _authorisationStatus = AuthorisationStatus.Denied; _hasRequestedAuthorisation = false; _waitingForAuthorisation = false; }; callbacks.PermissionGranted += (permission) => { _authorisationStatus = AuthorisationStatus.Authorised; _hasRequestedAuthorisation = true; _waitingForAuthorisation = false; }; #if !UNITY_2023_1_OR_NEWER callbacks.PermissionDeniedAndDontAskAgain += (permission) => { _authorisationStatus = AuthorisationStatus.Denied; _hasRequestedAuthorisation = true; _waitingForAuthorisation = false; }; #endif Permission.RequestUserPermission(AndroidPermissionReadMediaVideo, callbacks); return new WaitForAuthorisation(); } #else public static CustomYieldInstruction RequestUserAuthorisation() { if (_authorisationStatus == AuthorisationStatus.Authorised) { // Already authorised return null; } Permission.RequestUserPermission(AndroidPermissionReadMediaVideo); // Unfortunately there is no way to know when the dialog has been closed so no way // to determine if permission has been denied as there is nothing to distinguish // the result of the permission check before, during and after the request unless // permission has been authorised. return null; } #endif } } #endif