Forum Xamarin.iOS

IOS CrossPermission CheckPermissionStatusAsync is returning Unknown on app load

sisaackssisaacks Member ✭✭✭

I have the following code:
PermissionStatus permissionStatus = await CrossPermissions.Current.CheckPermissionStatusAsync();

I have added the following keys to Info.plist
NSLocationWhenInUseUsageDescription
NSLocationAlwaysAndWhenInUseUsageDescription
NSLocationAlwaysUsageDescription

but still I am getting Permission Status of "Unknown"

Answers

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    Your check the permission code should use following code, add attribute <LocationAlwaysPermission> for location permission.

     var status = await CrossPermissions.Current.CheckPermissionStatusAsync<LocationAlwaysPermission>();
    

    Xamarin forums are migrating to a new home on Microsoft Q&A!
    We invite you to post new questions in the Xamarin forums’ new home on Microsoft Q&A!
    For more information, please refer to this sticky post.

  • sisaackssisaacks Member ✭✭✭

    @LeonLu I have quite a conundrum. We are wanting to get the current location (latitude and altitude) of the user when the app loads. This is easy to do with IOS because you can use await CrossPermissions.Current.RequestPermissionAsync();

    but if you do that with Android before the app loads....you will get a null ref exception. I am baffled as to how to do this in a cross platform app....other than on app load divide the code based on the platform...which seems awful

    I found a tutorial of how to add code to the Main Activity to force android to ask for permissions but this is not awaited and the code path continues. Any assistance in this matter would be greatly appreciated.

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    Open your android folder. Find AssemblyInfo.cs file. Add following code.

    [assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
    [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
    [assembly: UsesFeature("android.hardware.location", Required = false)]
    [assembly: UsesFeature("android.hardware.location.gps", Required = false)]
    [assembly: UsesFeature("android.hardware.location.network", Required = false)]
    

    Then, when you mainpage's OnAppearing method execute. You can get the location data after you grand the permission.

      protected  async override void OnAppearing()
            {
                base.OnAppearing();
    
                var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
               var cts = new CancellationTokenSource();
                var location = await Geolocation.GetLocationAsync(request, cts.Token);
                myLabel.Text = location.Latitude.ToString()+" "+ location.Longitude.ToString();
    
            }
    
  • sisaackssisaacks Member ✭✭✭

    @LeonLu do you know why the Plugin.Permissions.CrossPermissions does not work with Android in OnAppearing?

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    In the Android, you do not need to use Plugin.Permissions.CrossPermissions to request permission, just use above answer's step to make a test.

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    @sisaacks if reply is helpful, please click the Yes tab under the helpful answer.

  • sisaackssisaacks Member ✭✭✭

    @LeonLu it was and it wasn't. I am creating a crossplatform app and one of the things I do with OnApearing is check permissions. It appears based on the device I will have to have different methods.

    Another annoying issue, is I create a new instance of a class in OnStart that starts up Plugin BLE. In IOS it seems to happen on a different thread or something....I am not entirely sure what is going on, the class in instantiated but the values are not updated.

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    Let us focus on the first question, I put the following code in the MainPage.cs, I use Xamarin.Essentials.Permissions to achieve it, I add the breakpoint to var status = await CheckAndRequestPermissionAsync(new Permissions.LocationWhenInUse()); this line, when above line executed at first time, it status is unknow, but if I click the popup menu, I click allow once, var status = await CheckAndRequestPermissionAsync(new Permissions.LocationWhenInUse()); will execute again, then I can get the permission status is Granted like following screenshot.

      protected async override void OnAppearing()
            {
                base.OnAppearing();
                var status = await CheckAndRequestPermissionAsync(new Permissions.LocationWhenInUse());
                if (status != PermissionStatus.Granted)
                {
                    // Notify user permission was denied
                    return;
                }
    
                var location = await Geolocation.GetLocationAsync();
    
                MyLabel.Text = location.Latitude.ToString();
    
    
            }
    
            public async Task<PermissionStatus> CheckAndRequestPermissionAsync<T>(T permission)
                 where T : BasePermission
            {
                var status = await permission.CheckStatusAsync();
                if (status != PermissionStatus.Granted)
                {
                    status = await permission.RequestAsync();
                }
    
                return status;
            }
    

  • sisaackssisaacks Member ✭✭✭

    @LeonLu I figured out why it was unknown. I still dont understand why Android cannot do this onload.

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    I still dont understand why Android cannot do this onload.

    Do you mean that you want to get the Latitude or Longitude in the OnAppearing()? Based on my test, when we grand the location permission, then we can get Latitude and Longitude data. In the android, location permission is a dangerous permission, after user grand the permission. then our application that could get the data. If you grand location permission with Allow all the time or Allow only while using the app, you can get the Latitude and Longitude data in the OnAppearing method at the next time

  • sisaackssisaacks Member ✭✭✭

    @LeonLu yeah thats the problem, I need to get it the first time. Our app uses lat/long to calculation some stuff. So I need to ask for permission in OnAppearing....but with android, if the permission is not granted yet, the app will get a null reference. in OnApearing

  • sisaackssisaacks Member ✭✭✭

    @LeonLu I have a Xmarin Cross Platform App, I do not see an assembly file in the Android app.
    I know if I add these references in the main project then it affects IOS

    [assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
    [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
    [assembly: UsesFeature("android.hardware.location", Required = false)]
    [assembly: UsesFeature("android.hardware.location.gps", Required = false)]
    [assembly: UsesFeature("android.hardware.location.network", Required = false)]
    Then, when you mainpage's OnAppearing method execute. You can get the location data after you grand the permission.

    protected async override void OnAppearing()
    {
    base.OnAppearing();

            var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
           var cts = new CancellationTokenSource();
            var location = await Geolocation.GetLocationAsync(request, cts.Token);
            myLabel.Text = location.Latitude.ToString()+" "+ location.Longitude.ToString();
    
        }
    
  • sisaackssisaacks Member ✭✭✭

    @LeonLu Awhile back you gave me some code for Android to check if Location Services were on.
    It works fine...on the newer android phones but on Android 7 Api 24, even though location services are on, the code still returns false.

    Android.Locations.LocationManager manager = (Android.Locations.LocationManager)Android.App.Application.Context.GetSystemService(Android.Content.Context.LocationService);

            bool isAvailable;
            if (!manager.IsProviderEnabled(Android.Locations.LocationManager.GpsProvider))
            {
                //gps disable
                isAvailable = false;
            }
            else
            {
                //Gps enable
                isAvailable = true;
            }
            return isAvailable;
    
  • sisaackssisaacks Member ✭✭✭

    @LeonLu I am not sure whats going on....I cleaned and rebuilt and now it works perfect

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    emmmm, that is so awkward, thanks for your update and tips to fix this issue.

  • sisaackssisaacks Member ✭✭✭

    @LeonLu do you know much about the Plugin BLE? I am trying to figure out how to keep communication going when the phone screen goes to sleep in both Android and IOS. I have done some research and I have read that in Android you have to force the user to keep the app open? But that seems like a battery drain. Looking for some guidance on this....

  • sisaackssisaacks Member ✭✭✭

    @LeonLu so i removed the call on app load all together.
    Now I am calling it from a button click event.
    and this method...does not return at all...no matter what I select on the dialog

Sign In or Register to comment.