如何在 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。
我正在使用 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。