我正在开发一个健身追踪应用程序。目前,我的应用程序将跟踪用户的移动,并按照我想要的方式在谷歌地图片段上绘制折线叠加。唯一的问题是它仅在应用程序打开时才执行此操作(即不在后台运行或手机被锁定时)。我已经收集到,我想要解决这个问题的方法是使用一项服务继续在后台跟踪我的位置。我对 android 应用程序开发非常陌生,并且有几个问题。我能否在后台更新折线,以便当用户重新打开应用程序时,他们的锻炼路线是最新的?我将如何将当前跟踪用户移动的 android 活动转变为即使在手机锁定时也能跟踪它的服务?下面是跟踪所有用户移动的活动。
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.Gms.Maps;
using Android.Gms.Maps.Model;
using Android.Locations;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Plugin.CurrentActivity;
using Plugin.Geolocator;
using Plugin.Geolocator.Abstractions;
namespace TriTrack
{
[Activity(Label = "MapsActivity")]
public class MapsActivity : Activity, IOnMapReadyCallback
{
GoogleMap daMap;
Position position;
IGeolocator locator = CrossGeolocator.Current;
double lat;
double _long;
TextView latlonglist;
PolylineOptions polyline = new PolylineOptions().InvokeWidth(20).InvokeColor(Color.Red.ToArgb());
MarkerOptions start = new MarkerOptions();
bool WorkoutInProgress = false;
protected override void OnCreate(Bundle savedInstanceState)
{
CrossCurrentActivity.Current.Activity = this;
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Map);
MapFragment mapFragment = (MapFragment)FragmentManager.FindFragmentById(Resource.Id.the_fucking_map);
mapFragment.GetMapAsync(this);
Button switchB = FindViewById<Button>(Resource.Id.switch_button);
latlonglist = FindViewById<TextView>(Resource.Id.LATLONG);
getPos();
switchB.Click += delegate
{
if(WorkoutInProgress == false){
WorkoutInProgress = true;
start.SetPosition(new LatLng(position.Latitude, position.Longitude));
start.SetTitle("Start");
daMap.AddMarker(start);
polyline.Add(new LatLng(position.Latitude, position.Longitude));
StartListening();
LatLng latlng = new LatLng(position.Latitude, position.Longitude);
CameraUpdate camera = CameraUpdateFactory.NewLatLngZoom(latlng, 15);
daMap.MoveCamera(camera);
switchB.Text = "WORKOUT IN PROGRESS";
}
else{
WorkoutInProgress = false;
StopListening();
Android.App.AlertDialog.Builder diaglog = new AlertDialog.Builder(this);
AlertDialog alert = diaglog.Create();
alert.SetTitle("Good Work");
alert.SetMessage("Your workout is complete, would you like to record it?");
alert.SetButton("Yes", (c, ev) => {
alert.Dismiss(); //TODO: save polyine data to new table in the database.
});
alert.SetButton2("No", (c, ev) =>{
alert.Dismiss();
});
alert.Show();
}
};
}
void Locator_PositionChanged(object sender, PositionEventArgs e)
{
position = e.Position;
string latstring = position.Latitude.ToString();
string longstring = position.Latitude.ToString();
latlonglist.Text += (latstring + "," + longstring + "\n");
DrawMarker();
//FindViewById<Button>(Resource.Id.switch_button).Text = position.Latitude.ToString();
}
public void DrawMarker(){
lat = position.Latitude;
_long = position.Longitude;
polyline.Add(new LatLng(lat, _long));
//polyline.Add(new LatLng(40.739487, -96.65715119999999)); THIS IS FOR DEBUGGING
daMap.AddPolyline(polyline);
}
public void OnMapReady(GoogleMap googleMap)
{
daMap = googleMap;
daMap.MapType = GoogleMap.MapTypeHybrid;
getPos();
}
public async void getPos(){
position = await locator.GetPositionAsync();
}
public async void StartListening(){
await locator.StartListeningAsync(new TimeSpan(0, 0, 0, 3), 0.0, true, new Plugin.Geolocator.Abstractions.ListenerSettings
{
ActivityType = Plugin.Geolocator.Abstractions.ActivityType.Fitness,
AllowBackgroundUpdates = true
});
locator.PositionChanged += Locator_PositionChanged;
}
public async void StopListening(){
await locator.StopListeningAsync();
}
}
}