Xamarin Forms: How to check if GPS is on or off in Xamarin ios app?

不问归期 提交于 2021-01-29 08:12:05

问题


Whenever I am opening my app I need to check the GPS is on or off. If the GPS is off, I need to redirect the user to the location settings page. I have done the android part using the dependency service like below.

ILocSettings

public interface ILocSettings
{
    void OpenSettings();

    bool isGpsAvailable();
}

Android implementation

[assembly: Dependency(typeof(LocationShare))]
namespace Projectname.Droid.Services 
{
    public class LocationShare : ILocSettings
    {
        public bool isGpsAvailable()
        {
            bool value = false;
            Android.Locations.LocationManager manager = (Android.Locations.LocationManager)Android.App.Application.Context.GetSystemService(Android.Content.Context.LocationService);
            if (!manager.IsProviderEnabled(Android.Locations.LocationManager.GpsProvider))
            {
                //gps disable
                value = false;
            }
            else
            {
                //Gps enable
                value = true;
            }
            return value;
        }

        public void OpenSettings()
        {
            Intent intent = new Android.Content.Intent(Android.Provider.Settings.ActionLocat‌​ionSourceSettings);
            intent.AddFlags(ActivityFlags.NewTask);
            Android.App.Application.Context.StartActivity(intent);
        }
    }
}

Finally from the shared project called like below:

//For checking the GPS Status
bool gpsStatus = DependencyService.Get<ILocSettings>().isGpsAvailable();
//For opening the location settings 
DependencyService.Get<ILocSettings>().OpenSettings();

For ios how I can I do the same features? I tried like below:

[assembly: Dependency(typeof(LocationShare))]
namespace Projectname.iOS.Serivces
{
    class LocationShare : ILocSettings
    {
        public bool isGpsAvailable()
        {
            //how to check the GPS is on or off here
        }

        public void OpenSettings()
        {
            UIApplication.SharedApplication.OpenUrl(new NSUrl(UIApplication.OpenSettingsUrlString));
        }
    }
}

Location settings page opening on ios simulators, but don't know how to check the GPS status.

Update1

I have tried the CLLocationManager code and it is not working as expected. It returns true always even if the location is off or on.

OpenSettings() function code (UIApplication.SharedApplication.OpenUrl(new NSUrl(UIApplication.OpenSettingsUrlString));) is also not working as expected, it is redirecting to some other page, I need to open the location settings page if the GPS is off.

Also, I am requesting location permission like below:

var status = await Permissions.RequestAsync<Permissions.LocationAlways>();

In android, location permission is asking, but in ios, no permissions are asking.

Update2

I have tried the new codes and getting false value always as GPS status. I have added all the location permission on the info.plist like below:

But location permission is not asking when running the app (not even a single time). I have tried Permissions.LocationWhenInUse instead of Permissions.LocationAlways, but no luck.

Update 3

Following is my complete flow for checking location permission, checking GPS status, and open settings. The permission status value is always Disabled.

//Requesting permission like below:
var status = await Permissions.RequestAsync<Permissions.LocationAlways>();
if (status == PermissionStatus.Granted)
{
    //Then checking the GPS state like below
    bool gpsStatus = DependencyService.Get<ILocSettings>().isGpsAvailable();
    if (!gpsStatus)
    {
        //show a message to user here for sharing the GPS
        //If user granted GPS Sharing, opening the location settings page like below:
        DependencyService.Get<ILocSettings>().OpenSettings();
    }
}

I have tried the below 2 codes for requesting or checking permission. In both cases, the status value is Disabled. If I uninstall the app and reinstall it again, getting the same status and not showing any permission pop-up window.

var status = await Permissions.RequestAsync<Permissions.LocationAlways>();
var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();

回答1:


Unlike the Android system, iOS can set the GPS switch separately, and can only get the status of whether the location service is turned on. The rest of the specific positioning method will be left to the iOS system to choose.

At the beginning, we need to have a look at the status of location in iOS:

CLAuthorizationStatus Enum

UIApplicationOpenSettingsURLString: Used to create a URL that you can pass to the openURL: method. When you open the URL built from this string, the system launches the Settings app and displays the app’s custom settings, if it has any.

From now, iOS only support this way to displays the app’s custom settings. There are two helpful discussion, you could have a look. How to jump to system setting's location service on iOS10? and Open Location Settings Not working in ios 11 Objective c?.

If it is redirecting to some other page as follows:

That means your app not do any settings about the location service after installing the app . Therefore, you not need to open the setting page, because it will not show the location service bellow the setting page of your app. Now the CLAuthorizationStatus should be NotDetermined. You could use CLLocationManager.RequestWhenInUseAuthorization to request the permission, the popup window of location service will show for customer to choose inside the app.

If customer select Don't Allow first time, that means next time opening the app to check the location service that will show Denied status. Now you will need to use UIApplicationOpenSettingsURLString to open the settings page and will see the location service inside the app’s custom settings list.

At last, the final code of LocationShare is as follows:

public class LocationShare : ILocSettings
{
    public bool isGpsAvailable()
    {
        bool value = false;

        if ( CLLocationManager.LocationServicesEnabled )
        {
            if(CLLocationManager.Status == CLAuthorizationStatus.Authorized || CLLocationManager.Status == CLAuthorizationStatus.AuthorizedAlways || CLLocationManager.Status == CLAuthorizationStatus.AuthorizedWhenInUse)
            {//enable
                value = true;
            }
            else if (CLLocationManager.Status == CLAuthorizationStatus.Denied)
            {
                value = false;
                OpenSettings();
            }
            else{
                value = false;
                RequestRuntime();
            }
        }
        else
        {
            //location service false
            value = false;
            //ask user to open system setting page to turn on it manually.
        }
        return value;
    }


    public void RequestRuntime()
    {
        CLLocationManager cLLocationManager = new CLLocationManager();
        cLLocationManager.RequestWhenInUseAuthorization();
    }

    public void OpenSettings()
    {

        UIApplication.SharedApplication.OpenUrl(new NSUrl(UIApplication.OpenSettingsUrlString));
    }
}

Similarly, if CLAuthorizationStatus is Denied (the same as status == PermissionStatus.Unknown in Forms), the following code will not work in Forms.

var status = await Permissions.RequestAsync<Permissions.LocationAlways>();

It only works when CLAuthorizationStatus is NotDetermined. And you'd better request Permissions.LocationWhenInUse instead of Permissions.LocationAlways, this should be the better recommanded option.

============================Update #2================================

I have modified the above code, and you will see that if CLLocationManager.LocationServicesEnabled is false, we only can ask user to redirect to the system setting page to turn on the service manually. Because from iOS 10, iOS not supports to navigate to system setting page from non-system app.

============================Update #3======================================

If location service is enabled, when using UIApplication.SharedApplication.OpenUrl(new NSUrl(UIApplication.OpenSettingsUrlString)); method you will see the similar screenshot as follows:

The Loaction option will show in the list.



来源:https://stackoverflow.com/questions/64940855/xamarin-forms-how-to-check-if-gps-is-on-or-off-in-xamarin-ios-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!