如何在 Xamarin 表单中检查 network_provider 和 gps_provider?

How to check for network_provider and gps_provider in Xamarin forms?

我正在使用 Xamarin.Forms 并正在处理一个将 运行 用于 Android 和 Iphone 的项目。我的项目结构(如果该信息有用?)是同一解决方案中的三个项目 "MyApp"、"MyApp.Android" 和 "MyApp.iOS"。

现在我正在使用不同的插件,例如 Xam.Plugin.Geolocator 和 Plugin.Geofencing.Eddy 来使用地理围栏,但我遇到了一些问题(如另一个问题 中所述) .

现在我想检查地理围栏是否可以工作,检查GPS_PROVIDER和NETWORK_PROVIDER是否可用,我该如何实现?现在我只能检查是否启用了位置,但不能检查哪个提供商。

public bool IsLocationAvailable()
            {
                if (!CrossGeolocator.IsSupported)
                    return false;
                if (!CrossGeolocator.Current.IsGeolocationEnabled)
                    return false;
                if (!CrossGeolocator.Current.IsGeolocationAvailable)
                    return false;
                if (!CrossGeofencing.IsSupported)
                    return false;
                return true;
            }

现在,如果位置提供程序设置为 "GPS only",它会因此抛出错误,但我不确定如何捕捉和处理它。我已经看到了一些其他示例和问题,但这些示例和问题是专门针对 android 的,如果我已经在使用这些插件并且主要在 xamarin 表单项目(又名 "MyApp")上工作,我不确定如何实施这些示例和问题android 个中的一个 ("MyApp.Android")

对不起,图片太大了,我不知道如何调整它的大小!

您始终可以在共享项目 "MyApp" 中使用 运行 平台特定代码,使用 Xamarin.Forms Dependency Service

基本思路是在共享项目中创建一个接口,我们称之为 IGetLocationProvider:

public interface IGetLocationProvider {
    string GetProvider (); 
}

然后在Android、"MyApp.Android"、and/or、iOS、"MyApp.iOS"应用项目中,你在class中实现接口并将 Dependency 属性添加到 class。但首先您需要访问 Android 应用上下文。在 Android 应用程序项目中使其全局可用的最简单方法是将静态变量添加到 MainActivity class 并在 OnCreate 中设置它:

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    public static Context Context;
    ... 
    protected override void OnCreate(Bundle savedInstanceState)
    {
        ...
        MainActivity.Context = this;

    }
}

现在这里是 Android 的特定于平台的依赖服务,它将 return 一个用逗号分隔的可用位置提供程序的字符串:

using System;
using GetLP.Droid;
using Xamarin.Forms;
using Android.Locations;

[assembly: Dependency(typeof(GetLocationProvider))]
namespace GetLP.Droid
{
    public class GetLocationProvider : IGetLocationProvider
    {
        public string GetProvider()
        {
            string returnString = "";

            LocationManager manager = (LocationManager)MainActivity.Context.GetSystemService(Android.Content.Context.LocationService);
            bool gpsProviderEnabled = manager.IsProviderEnabled(LocationManager.GpsProvider);
            bool networkProviderEnabled = manager.IsProviderEnabled(LocationManager.NetworkProvider);
            bool passiveProviderEnabled = manager.IsProviderEnabled(LocationManager.PassiveProvider);

            returnString += gpsProviderEnabled ? "GPS," : ",";
            returnString += networkProviderEnabled ? "Network," : ",";
            returnString += passiveProviderEnabled ? "Passive" : "";

            return returnString;
        }
    }
}

现在您可以从您的共享代码调用 GetProvider:

string providers = DependencyService.Get<IGetLocationProvider>().GetProvider();

变量 providers 将是可用提供程序的逗号分隔字符串,例如如果 GSP 和 Passive 可用,则字符串将为 "GPS,,Passive",如果 Network 和 Passive 可用,则字符串将为“,Network,Passive”。当然,您可以将 GetProvider 更改为 return 数组或列表或您想要的任何内容,只需确保它在所有平台上都可用,即不要 return LocationManager,因为那是 Android 具体类型。

对于iOS,没有相似之处。 iOS 决定使用什么方法来获取位置以及 OS 使用的方法在获取位置时对应用程序开发人员不可用,因此您只想在 运行 时调用此依赖服务宁 Android。