我是Xamarin
的新手,到目前为止已经尝试了一些初学者教程。
现在,我想构建一些自定义内容,并需要请求当前位置。
为此,我安装了Xamarin.GooglePlayServices.Location
以访问FusedLocationProviderClient
类。
在MainActivity
中,我检索了FusedLocationProviderClient
:
public class MainActivity : FormsAppCompatActivity, ILocationProvider
{
private FusedLocationProviderClient FusedLocationClient { get; set; }
protected override void OnCreate(Bundle savedInstanceState)
{
// snip
FusedLocationClient = LocationServices.GetFusedLocationProviderClient(this);
}
}
ILocationProvider
需要实现方法TaskCompletionSource<Model.Location> GetPosition()
:
public TaskCompletionSource<Model.Location> GetPosition()
{
// snip
if (CheckSelfPermission(Manifest.Permission_group.Location) == Permission.Granted)
{
FusedLocationClient.LastLocation.AddOnCompleteListener(new OnLocationRequestCompleteListener(this, tcs));
}
// snip
}
UI上有一个用于请求当前位置的按钮。
每当用户单击按钮时,我都会通过ILocationProvider
获得DependencyService
并执行GetPosition
方法:
private void GetPositionClicked(object sender, EventArgs e)
{
var provider = DependencyService.Get<ILocationProvider>();
if(provider != null)
{
var tcs = provider.GetPosition();
// snip
}
}
现在的问题是,一旦我尝试在CheckSelfPermission
中执行GetPosition()
方法,应用程序就会崩溃。
我在GetPosition()
中设置了一个断点,并注意到FusedLocationClient
是null
,尽管在调用null
之后显然不是OnCreate
。
然后我检查了this
和OnCreate
中的GetPosition
,发现它们不是同一实例,这使我得出结论,这里显然有问题。
为解决此问题,我做了以下工作:
public class MainActivity : FormsAppCompatActivity, ILocationProvider
{
internal static MainActivity Instance { get; private set; }
private FusedLocationProviderClient FusedLocationClient { get; set; }
protected override void OnCreate(Bundle savedInstanceState)
{
// snip
Instance = this
// snip
}
// snip
public TaskCompletionSource<Model.Location> GetPosition()
{
if (this != Instance)
{
return Instance.GetPosition();
}
// snip
}
}
至少现在可以,但是我无法想象这是要走的路。
到目前为止,我了解到DependencyService
似乎尚未获得已创建的实例,而是创建了一个实例(至少创建了一次)。
从共享的MainActivity
库中调用.NET Standard
中的方法的正确方法是什么?
答案 0 :(得分:1)
将这些方法从Activity类中移出到独立类中(在Xamarin.Android应用程序(或Xamarin.Android库项目中)内。
public interface ILocationProvider
{
Task<Tuple<double, double>> GetPosition();
}
public class Location_Android: Java.Lang.Object, ILocationProvider
{
private FusedLocationProviderClient FusedLocationClient { get; set; }
public Location_Android()
{
FusedLocationClient = new FusedLocationProviderClient(Application.Context);
}
public async Task<Tuple<double, double>> GetPosition()
{
var loc = await FusedLocationClient?.GetLastLocationAsync();
return new Tuple<double, double>(loc.Latitude, loc.Longitude);
}
}