【问题标题】:How to check for network_provider and gps_provider in Xamarin forms?如何在 Xamarin 表单中检查 network_provider 和 gps_provider?
【发布时间】:2018-11-13 10:26:16
【问题描述】:

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

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

现在我想检查地理围栏是否能够工作,检查 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”,它会因此引发错误,但我不知道如何捕获和处理它。我已经看到了一些其他示例和问题,但仅适用于 android,如果我已经在使用这些插件并且主要在 xamarin 表单项目(又名“MyApp”)而不是 android 项目(“ MyApp.Android")

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

【问题讨论】:

    标签: android xamarin xamarin.forms gps geofencing


    【解决方案1】:

    您始终可以使用Xamarin.Forms Dependency Service 在您的共享项目“MyApp”中运行特定于平台的代码。

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

    public interface IGetLocationProvider {
        string GetProvider (); 
    }
    

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

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

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

    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 以返回数组或列表或任何您想要的,只要确保它在所有平台上都可用,即不要返回 LocationManager,因为它是 Android 特定的类型。

    对于 iOS,没有类似的东西。 iOS 决定使用什么方法来获取位置,并且操作系统在获取位置时不可用,因此您只想在 Android 上运行时调用此依赖服务。

    【讨论】:

    • 在这种情况下,我可以在“MyApp”项目中调用 GetProvider(),这会给我想要的结果,但是对于我不想执行此代码的 iOS 呢?我一直在阅读,如果我不在 iOS 中实现接口并在 if (Device.RuntimePlatform == Device.Android) 中进行调用,可以吗?
    • 如果我回答了你的问题,我似乎已经回答了,请接受答案,谢谢!
    • 对不起!我正在尝试答案,现在我可以说它完美无缺!在此之前,我尝试了类似但没有依赖服务的东西,它可以工作,但只在 android 上运行,并且在 iOS 上出现了一些编译错误。然后我尝试了这个答案,它按预期工作!非常感谢
    猜你喜欢
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多