Forum Xamarin.Android

Runtime Permissions

LotokLotok GBMember ✭✭
edited September 2017 in Xamarin.Android

I am working on an app that needs to request permissions before it can run. Without the permissions the app needs to close, it cannot continue. I am having trrouble with 2 areas of this.

Firstly I tried using the permissions plugin by James Montemagno, but don't seem to be having much luck. I can get the permission requests to show, but I cannot get the app to stop running if they are denied, or long enough to wait for a response. As it is async, it keeps going back to the main thread.

I could do something like

while(!_isPermissionsSet){ //wait }

but apart from that being ugly, it would then stop the async calls to permissions plugin completing their task. I am thinking the while may be the only way though. I played around this idea but really there just has to be something better.

var result = await CrossPermissions.Current.RequestPermissionsAsync(requiredPermissions.ToArray()); 
while (!_isPermissionGranted)
        {
            var locationPermission2 = await CrossPermissions.Current.CheckPermissionStatusAsync(PermissionsPlugin.Permission.Location);
            var storagePermission2 = await CrossPermissions.Current.CheckPermissionStatusAsync(PermissionsPlugin.Permission.Storage);

            if (locationPermission2 == PermissionsPlugin.PermissionStatus.Granted &&
                storagePermission2 == PermissionsPlugin.PermissionStatus.Granted)
            {
                _isPermissionGranted = true;
            }

        }

All examples I can find show just not running the code using the permissions until they are granted, but I do not have that luxury. If the permissions do not get granted, I need to close the app with something like

FinishAndRemoveTask();

With this in mind I tried this, but the code never seemed to hit, at least on my Splash Screen (Main Activity with centered image set by appcompat no toolbar theme) I couldn't get any message to show or the app to close.

foreach (var result in results.Result)
        {
            if(result.Value != PermissionsPlugin.PermissionStatus.Granted)
            {
                Toast.MakeText(this, "Permissions are needed to continue", ToastLength.Short);
                FinishAndRemoveTask();
            }
        }

The short of it is I just can't quite get my head around it and would really appreciate a little pointer if anyone can spare the time

Thanks

Best Answer

Answers

  • LjusnanLjusnan DEMember ✭✭✭

    Hi, I am using the same plugin and it's working great. You don't need the while-loop. Just await CheckPermissionStatusAsync and then check if one PermissionStatus is not Granted. Can you provide the complete code from the Splash Screen actitivty? Maybe the permission code is in the wrong place.

  • LotokLotok GBMember ✭✭
    edited September 2017

    I have tried various things, this is just the state the code is in now after a number of hours fiddling with it. I did have Rationale checks, then if required it used an alertDialog, but the dialog wouldn't show. Possibly it was underneath the image set by theme?

    So just to try and get something working I removed that. Currently there is a Toast.makeText call in there but that never shows either. I need to prevent the MapActivity ever being called if the permissions are not set. Having an await on RequestPermissionsAsync allows it back to the main thread which then calls into that activity. Which I why I tried playing with the while loop idea.

    [Activity(Label = "AppNameRemoved", MainLauncher = true, Theme = "@style/SplashTheme", NoHistory = true)]
     public class MainActivity : AppCompatActivity
     {
        private bool _isPermissionGranted;
    
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
    
            RequestPermissions();
    
            var intent = new Intent(this, typeof(MapActivity));
            StartActivity(intent);
        }
    
    
    
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
        {
            Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    
        private async void RequestPermissions()
        {
            var locationPermission = await CrossPermissions.Current.CheckPermissionStatusAsync(PermissionsPlugin.Permission.Location);
            var storagePermission =  await CrossPermissions.Current.CheckPermissionStatusAsync(PermissionsPlugin.Permission.Storage);
    
            //if we already have permission, continue
            if (locationPermission == PermissionsPlugin.PermissionStatus.Granted &&
                    storagePermission == PermissionsPlugin.PermissionStatus.Granted)
            {
                _isPermissionGranted = true;
                return;
            }
    
            //request permissions 
            var requiredPermissions = new List<PermissionsPlugin.Permission>();
    
            if (locationPermission != PermissionsPlugin.PermissionStatus.Granted)
                requiredPermissions.Add(PermissionsPlugin.Permission.Location);
    
            if (storagePermission != PermissionsPlugin.PermissionStatus.Granted)
                requiredPermissions.Add(PermissionsPlugin.Permission.Storage);
    
            var results = await CrossPermissions.Current.RequestPermissionsAsync(requiredPermissions.ToArray());
    
            //check results
            foreach (var result in results)
            {
                if(result.Value != PermissionsPlugin.PermissionStatus.Granted)
                {
                    Toast.MakeText(this, "Permissions are needed to continue", ToastLength.Short);
                    FinishAndRemoveTask();
                }
            }
    
    
            //wait for result
            while (!_isPermissionGranted)
            {
                var locationPermission2 = await CrossPermissions.Current.CheckPermissionStatusAsync(PermissionsPlugin.Permission.Location);
                var storagePermission2 = await CrossPermissions.Current.CheckPermissionStatusAsync(PermissionsPlugin.Permission.Storage);
    
                if (locationPermission == PermissionsPlugin.PermissionStatus.Granted &&
                    storagePermission == PermissionsPlugin.PermissionStatus.Granted)
                {
                    _isPermissionGranted = true;
                }
    
            }
        }
    
    
    }
    
  • LotokLotok GBMember ✭✭

    Doing the work OnCreate seems to be the issue, moved to OnResume and everything started working correctly.

    Thanks very much

Sign In or Register to comment.