我正在使用Xamarin构建一个应该使用位置服务的Android应用程序。
在OnCreate中,我构建了GoogleApiClient:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
global::Xamarin.Forms.Forms.Init (this, bundle);
LoadApplication (new KMN.App ());
apiClient = new GoogleApiClient.Builder(this, this, this).AddApi(LocationServices.API).Build();
apiClient.Connect();
}
之后apiClient是!= null。比我进入:
public void OnConnected(Bundle connectionHint)
{
LocationRequest locRequest = new LocationRequest();
locRequest.SetPriority(LocationRequest.PriorityBalancedPowerAccuracy);
locRequest.SetFastestInterval(500);
locRequest.SetInterval(1000);
LocationServices.FusedLocationApi.RequestLocationUpdates(apiClient, locRequest, this);
}
这里apiClient仍然是!= null。
永远不会调用此方法:
public void OnLocationChanged(Android.Locations.Location location)
{
LastLocation = location;
}
当我从UI调用此方法时,apiClient为null:
public Adresse getAdresse()
{
if (LastLocation!= null)
{
return new Adresse()
{
Latitude = LastLocation.Latitude,
Longitude = LastLocation.Longitude
};
}
else
{
return new Adresse()
{
Latitude = 0,
Longitude = 0
};
}
}
答案 0 :(得分:0)
你可以使用在Android Application
子类中定义的静态变量等......但这是我首选的方式......; - )
public interface ILocationService : IDisposable
{
Task<bool> Init();
MyLocation Currentlocation();
void Subscribe(EventHandler handler);
void Unsubscribe(EventHandler handler);
}
public class MyLocation
{
public MyLocation(double Latitude, double Longitude)
{
this.Latitude = Latitude;
this.Longitude = Longitude;
}
public double Latitude { get; private set; }
public double Longitude { get; private set; }
}
public class LocationEventArgs<T> : EventArgs
{
public T EventData { get; private set; }
public LocationEventArgs(T EventData)
{
this.EventData = EventData;
}
}
public class LocationService : Java.Lang.Object,
ILocationService,
GoogleApiClient.IConnectionCallbacks,
GoogleApiClient.IOnConnectionFailedListener,
Android.Gms.Location.ILocationListener,
IDisposable
{
bool _init;
GoogleApiClient gClient;
LocationRequest locRequest;
ManualResetEventSlim resetEvent;
EventHandler eventHandler;
public async Task<bool> Init()
{
await Task.Run(() =>
{
if (!_init)
{
resetEvent = new ManualResetEventSlim();
gClient = new GoogleApiClient.Builder(Forms.Context, this, this).AddApi(LocationServices.API).Build();
_init = true;
}
resetEvent.Reset();
gClient.Connect();
resetEvent.Wait();
});
return gClient.IsConnected;
}
public new void Dispose()
{
resetEvent?.Dispose();
if (gClient != null)
LocationServices.FusedLocationApi.RemoveLocationUpdates(gClient, this);
gClient?.Dispose();
base.Dispose();
}
public void OnConnected(Bundle connectionHint)
{
resetEvent.Set();
}
public void OnConnectionFailed(ConnectionResult result)
{
resetEvent.Set();
}
public void OnConnectionSuspended(int cause)
{
LocationServices.FusedLocationApi.RemoveLocationUpdates(gClient, this);
}
public void OnLocationChanged(Android.Locations.Location location)
{
Log.Debug("SO", location.ToString());
eventHandler?.Invoke(null, new LocationEventArgs<MyLocation>(new MyLocation(location.Latitude, location.Longitude)));
}
public void Subscribe(EventHandler locationHandler)
{
locRequest = new LocationRequest();
locRequest.SetPriority(LocationRequest.PriorityBalancedPowerAccuracy);
locRequest.SetFastestInterval(100);
locRequest.SetInterval(5000);
eventHandler += locationHandler;
LocationServices.FusedLocationApi.RequestLocationUpdates(gClient, locRequest, this);
}
public void Unsubscribe(EventHandler locationHandler)
{
LocationServices.FusedLocationApi.RemoveLocationUpdates(gClient, this);
eventHandler -= locationHandler;
}
public MyLocation Currentlocation()
{
if (gClient != null)
{
var lastLocation = LocationServices.FusedLocationApi.GetLastLocation(gClient);
Log.Debug("SO", lastLocation.ToString());
if (lastLocation != null)
return new MyLocation(lastLocation.Latitude, lastLocation.Longitude);
}
return null;
}
}
var startLocationUpdates = new Command(async () =>
{
if (await DependencyService.Get<ILocationService>().Init())
{
// Subscribe to the location change events...
DependencyService.Get<ILocationService>().Subscribe((sender, e) =>
{
var loc = (e as LocationEventArgs<MyLocation>).EventData;
System.Diagnostics.Debug.WriteLine($"{loc.Latitude}:{loc.Longitude}");
});
// Or just grab the Fused-based LastLocation (it might not be available!)
var loc2 = DependencyService.Get<ILocationService>().Currentlocation();
if (loc2 != null)
System.Diagnostics.Debug.WriteLine($"{loc2?.Latitude}:{loc2?.Longitude}");
}
});
var button = new Button { Text = "Start Location Updates", Command = startLocationUpdates };