Xamarin.forms Xamarin表单-每10秒获取设备位置(应用程序在前台/后台运行时)
我已经创建了一个Xamarin表单应用程序。应用程序应定期(每10秒)获取设备的位置(iOS和Android)。我怎样才能做到这一点?我知道有一些库,例如:Xamarin.Essentials,但我无法决定该位置应该使用多少次Xamarin.forms Xamarin表单-每10秒获取设备位置(应用程序在前台/后台运行时),xamarin.forms,geolocation,background-process,geofencing,Xamarin.forms,Geolocation,Background Process,Geofencing,我已经创建了一个Xamarin表单应用程序。应用程序应定期(每10秒)获取设备的位置(iOS和Android)。我怎样才能做到这一点?我知道有一些库,例如:Xamarin.Essentials,但我无法决定该位置应该使用多少次 当Xamarin forms应用程序在后台(在IOS和Android上)运行时,还可以获取设备的本地信息。对于Android,您可以尝试启动一项服务,使用Android的LocationManager开始监听位置更改。可以指定要跟踪的时间间隔和最小距离 帮我弄明白如何使用
当Xamarin forms应用程序在后台(在IOS和Android上)运行时,还可以获取设备的本地信息。对于Android,您可以尝试启动一项服务,使用Android的LocationManager开始监听位置更改。可以指定要跟踪的时间间隔和最小距离 帮我弄明白如何使用它。对我来说,即使应用程序被暂停(运行安卓6.1的物理设备),它也在发送位置更新 为了获得位置,我将我的服务设置为“LocationListener”,并实现了ILocationListener接口,如下所示:
[Service]
public class TestService : Service, ILocationListener
{
public override IBinder OnBind(Intent intent)
{
return null;
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
// start your location updates with the locationManager here
return StartCommandResult.Sticky; // remember to return sticky for the service to run when app is suspended
}
public override void OnDestroy() { }
...
public void OnLocationChanged(Location location)
{
// react to location changes here
}
public void OnProviderDisabled(string provider) { }
public void OnProviderEnabled(string provider) { }
public void OnStatusChanged(string provider, Availability status, Bundle extras) { }
}
有关背景和如何设置服务的更多信息,请阅读
重要的是要注意位置更新的时间不一致(有时需要10秒以上),因为您只需给出最短时间,操作系统会根据其容量处理请求。但也不算太糟
更新:这似乎不适用于Android 8.0及以上版本。请看我过去因为头痛而通过的一个跨平台应用程序,它每x秒更新一次位置,应该在后台运行。 我用Xamarin表单开发了一个模板,支持后台位置更新、后台权限,这些功能需要根据操作系统(iOs/Android)进行调整 为此,我使用了Xamarin Essentials和消息中心。 请让我知道模板是否适合您的需要。
谢谢。您可以使用设备计时器来完成。计时器将定期运行&检查位置更新,并在位置更新时通知。我使用Xam.Plugins.Notifier在位置更新时生成本地通知 下面是它的代码:
public partial class MainPage : ContentPage
{
Location oldLocation = null;
CancellationTokenSource cts;
public MainPage()
{
InitializeComponent();
Device.StartTimer(TimeSpan.FromSeconds(10), () =>
{
GetCurrentLocation();
return true;
});
}
protected async override void OnAppearing()
{
base.OnAppearing();
await GetCurrentLocation();
}
async Task GetCurrentLocation()
{
try
{
var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
cts = new CancellationTokenSource();
var location = await Geolocation.GetLocationAsync(request, cts.Token);
if (location != null)
{
Debug.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
if (oldLocation == null)
{
oldLocation = location;
map.MoveToRegion(MapSpan.FromCenterAndRadius(
new Position(location.Latitude, location.Longitude), Distance.FromMiles(0.3)));
}
if (location.Latitude != oldLocation.Latitude || location.Longitude != oldLocation.Longitude)
{
map.MoveToRegion(MapSpan.FromCenterAndRadius(
new Position(location.Latitude, location.Longitude), Distance.FromMiles(0.3)));
oldLocation = location;
double zoomLevel = 0.5;
double latlongDegrees = 360 / (Math.Pow(2, zoomLevel));
if (map.VisibleRegion != null)
{
map.MoveToRegion(new MapSpan(map.VisibleRegion.Center, latlongDegrees, latlongDegrees));
}
var placemarks = await Geocoding.GetPlacemarksAsync(location.Latitude, location.Longitude);
var placemark = placemarks?.FirstOrDefault();
if (placemark != null)
{
var geocodeAddress =
$"AdminArea: {placemark.AdminArea}\n" +
$"CountryCode: {placemark.CountryCode}\n" +
$"CountryName: {placemark.CountryName}\n" +
$"FeatureName: {placemark.FeatureName}\n" +
$"Locality: {placemark.Locality}\n" +
$"PostalCode: {placemark.PostalCode}\n" +
$"SubAdminArea: {placemark.SubAdminArea}\n" +
$"SubLocality: {placemark.SubLocality}\n" +
$"SubThoroughfare: {placemark.SubThoroughfare}\n" +
$"Location : {placemark.Location}\n" +
$"Thoroughfare: {placemark.Thoroughfare}\n";
Debug.WriteLine(geocodeAddress);
}
CrossLocalNotifications.Current.Show("Location Updated", "You checked in to " + placemark.FeatureName + " " + placemark.Locality + " " + placemark.SubLocality, 101, DateTime.Now.AddSeconds(5));
}
}
}
catch (FeatureNotSupportedException)
{
// Handle not supported on device exception
}
catch (FeatureNotEnabledException)
{
// Handle not enabled on device exception
}
catch (PermissionException)
{
// Handle permission exception
}
catch (Exception)
{
// Unable to get location
}
}
}
“但我无法决定该位置应该被拍摄多少次。”-您已经声明需要每10秒更新一次。所以,使用一个每10秒触发一次的计时器。老实说,我认为在安卓操作系统发生变化之后,你无法做到这一点,这是不可能的,因为一旦设备进入待机状态,打瞌睡就会停止几乎所有的应用程序,也就是说,你将无法在这里不断共享位置更多信息@M Yil我搜索了一些,并找到了一个可以获取时间间隔内设备位置的示例:如果这样做有效,我就给你邮寄一大瓶GuaroWell?来吧,分享爱!它起作用了吗?