Xamarin Forms:如何在 Xamarin ios 应用程序中检查 GPS 是打开还是关闭?

Posted

技术标签:

【中文标题】Xamarin Forms:如何在 Xamarin ios 应用程序中检查 GPS 是打开还是关闭?【英文标题】:Xamarin Forms: How to check if GPS is on or off in Xamarin ios app? 【发布时间】:2020-11-21 07:42:50 【问题描述】:

每当我打开我的应用程序时,我都需要检查 GPS 是打开还是关闭。如果 GPS 关闭,我需要将用户重定向到位置设置页面。我已经使用dependency service 完成了android 部分,如下所示。

ILocSettings

public interface ILocSettings

    void OpenSettings();

    bool isGpsAvailable();

Android 实现

[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);
        
    

最后来自共享项目,如下所示:

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

对于 ios,我怎样才能实现相同的功能?我尝试如下:

[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));
        
    

在ios模拟器上打开位置设置页面,但不知道如何查看GPS状态。

更新1

我已经尝试了CLLocationManager 代码,但它没有按预期工作。即使 location 关闭或打开,它也始终返回 true。

OpenSettings() 功能代码 (UIApplication.SharedApplication.OpenUrl(new NSUrl(UIApplication.OpenSettingsUrlString));) 也没有按预期工作,它正在重定向到其他一些 page,如果 GPS 关闭,我需要打开位置 settings page。

另外,我正在请求位置权限,如下所示:

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

在android 中,请求位置权限,但在 ios 中,没有请求权限。

更新2

我已经尝试了新代码并始终获得错误值作为 GPS 状态。我已经在info.plist 上添加了所有位置权限,如下所示:

但是在运行应用程序时不会询问位置权限(甚至一次都没有)。我试过Permissions.LocationWhenInUse而不是Permissions.LocationAlways,但没有运气。

更新 3

以下是我检查位置权限、检查 GPS 状态和打开设置的完整流程。权限状态值始终为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();
    

我已尝试使用以下 2 个代码来请求或检查权限。在这两种情况下,状态值都是禁用的。如果我卸载该应用程序并重新安装它,获得相同的状态并且没有显示任何权限弹出窗口。

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

【问题讨论】:

使用 Essentials 并检查 FeatureNotEnabledException 【参考方案1】:

不同于Android系统,iOS可以单独设置GPS开关,只能获取定位服务是否开启的状态。剩下的具体定位方式留给iOS系统选择。

一开始,我们需要看看iOS中位置的状态:

CLAuthorizationStatus 枚举

UIApplicationOpenSettingsURLString:用于创建可以传递给 openURL: 方法的 URL。当您打开使用此字符串构建的 URL 时,系统会启动“设置”应用并显示该应用的自定义设置(如果有)。

从现在开始,iOS 仅支持以这种方式显示应用的自定义设置。有两个有用的讨论,你可以看看。 How to jump to system setting's location service on iOS10? 和 Open Location Settings Not working in ios 11 Objective c?。

如果它正在重定向到其他页面,如下所示:

这意味着您的应用在安装应用后不会对定位服务进行任何设置。 因此,您不需要打开设置页面,因为它不会在您的应用设置页面下方显示位置服务。现在CLAuthorizationStatus 应该是NotDetermined。您可以使用 CLLocationManager.RequestWhenInUseAuthorization 来请求权限, 定位服务的弹出窗口将显示供客户在应用程序内选择。

如果客户第一次选择不允许,则意味着下次打开应用查看定位服务会显示拒绝状态。现在您需要使用 UIApplicationOpenSettingsURLString 打开设置页面,并会在应用的自定义设置列表中看到定位服务。

最后,LocationShare的最终代码如下:

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));
    

同理,如果 CLAuthorizationStatusDenied(与 Forms 中的 status == PermissionStatus.Unknown 相同),则以下代码在 Forms 中不起作用。

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

仅当 CLAuthorizationStatusNotDetermined 时有效。而且您最好请求Permissions.LocationWhenInUse 而不是Permissions.LocationAlways,这应该是更好的推荐选项。

=============================更新#2================ ================

我修改了上面的代码,你会看到如果CLLocationManager.LocationServicesEnabled为false,我们只能要求用户重定向到系统设置页面手动开启服务。因为从 iOS 10 开始,iOS 不支持从非系统应用导航到系统设置页面。

=============================更新#3================ =======================

如果启用了定位服务,当使用UIApplication.SharedApplication.OpenUrl(new NSUrl(UIApplication.OpenSettingsUrlString));方法时你会看到类似的截图如下:

位置选项将显示在列表中。

【讨论】:

我已经用新的发现更新了我的问题,你能看看吗? @SreejithSree Okey,我好像忘记了一些情况,我已经更新了答案。 我已经尝试了新的代码,但没有运气,你能看看 Update2 的问题吗? @SreejithSree Okey,这很奇怪。您是否在物理设备中运行应用程序? 是的,我在物理设备上运行。

以上是关于Xamarin Forms:如何在 Xamarin ios 应用程序中检查 GPS 是打开还是关闭?的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin.Forms 手势密码实现

如何在 Xamarin.Forms 中获取/检测屏幕大小?

如何删除 Xamarin.Forms 导航栏?

在 Xamarin.Forms 中录制语音后如何保存音频文件

Xamarin.forms - 如何在 MapView 上创建可拖动元素(标记)?

Xamarin.Forms 如何使按钮出现在一行中