Xamarin Forms - 每 10 秒获取一次设备位置(当应用程序在前台/后台运行时)
Posted
技术标签:
【中文标题】Xamarin Forms - 每 10 秒获取一次设备位置(当应用程序在前台/后台运行时)【英文标题】:Xamarin Forms - Get device location every 10 seconds (when app runs in foreground/background) 【发布时间】:2020-06-23 12:08:33 【问题描述】:我创建了一个 Xamarin 表单应用程序。应用程序应定期(每 10 秒)获取设备的位置(ios 和 android)。我怎样才能做到这一点?我知道有一些库,例如:Xamarin.Essentials,但我无法决定该位置应该被占用多少次。
当 Xamarin 表单应用程序在后台运行时(在 IOS 和 Android 上),也应该可以获取设备的本地。
【问题讨论】:
“但我无法决定该位置应该被拍摄多少次。” - 你已经说过你需要每 10 秒更新一次。因此,请使用每 10 秒触发一次的 Timer。 说实话,我不认为你可以在 Android 操作系统发生变化之后做到这一点,这是不可能的,因为一旦设备进入待机状态并且打瞌睡几乎所有应用程序,即您将无法在此处不断分享位置更多信息developer.android.com/training/monitoring-device-state/… @M Yil 我搜索了一些并找到了一个可以获取设备位置的样本:github.com/CherryBu/LocationSample 【参考方案1】:我过去曾因为那个令人头疼的问题而忽略了,这是一个跨平台应用程序,它每 x 秒更新一次位置,它应该在后台运行。 我在 Xamarin Forms 中开发了一个模板,支持后台位置更新、后台权限,这些功能需要根据操作系统(iOs/Android)进行调整。
Check my Github repo here
为此,我使用了 Xamarin Essentials 和消息中心。 请让我知道该模板是否适合您的需求。 谢谢。
【讨论】:
如果可行,我会寄给你一大瓶 Guaro【参考方案2】:对于 Android,您可以尝试启动一个使用 Android 的 LocationManager 的服务来开始监听位置变化。您可以指定要跟踪的时间间隔和最小距离。
This section 帮助我弄清楚了如何使用它。对我来说,即使应用程序暂停(运行 Android 6.1 的物理设备),它也会发送位置更新。
为了获得位置,我将我的服务设为“LocationListener”并像这样实现了 ILocationListener-Interface:
[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)
有关后台和如何设置服务的更多信息,请阅读this。
需要注意的重要一点是 locationUpdates 的时间不一致(有时需要超过 10 秒),因为您只需给出 minimumTime 并且操作系统会根据其容量处理请求。不过还不错。
更新:这似乎不适用于 Android 8.0 及更高版本。见here
【讨论】:
【参考方案3】:您可以使用设备计时器来做到这一点。计时器将定期运行并检查位置更新并通知位置是否更新。我使用 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
【讨论】:
以上是关于Xamarin Forms - 每 10 秒获取一次设备位置(当应用程序在前台/后台运行时)的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin Forms Android 10 及更高版本在公共外部存储中按文件名查找视频并获取路径
Xamarin Forms 使用 CrossGeolocator 获取前台服务位置更新