Служба завершения AlarmManager, когда приложение закрыто (LocationManager) - PullRequest
0 голосов
/ 01 февраля 2019

Я работаю в проекте Xamarin, который будет отслеживать пользователей во время их работы, даже если приложение закрыто.Это в основном приложение для наших клиентов (у нас есть ERP), отслеживающее их продавцов.

Для этого я реализовал довольно простой BroadcastReceiver для запуска сервиса (LocationService), который собирается получить позицию пользователя и сохранитьэто в базе данных или POST некоторому API.

Проблема в том, что, когда я не использую LocationManager, он работает нормально (я закрываю приложение, и оно продолжает подавать сообщения, например).Но если я использую LocationManager, сервис «вылетает» после закрытия приложения и прекращает отслеживание.Я делаю что-то неправильно?Проект полностью настроен для отслеживания GPS (он прекрасно работает, когда приложение открыто или приостановлено).

PS: Я впервые работаю с Xamarin.Android.До того как я только что работал с Xamarin.Forms.

Вот LogCat .Похоже, это происходит, когда AlarmManager запущен и пытается найти местоположение.

Вот мой код:

Начать отслеживание

private void StartTrackingAlarm(int period)
    {
        Intent intent = new Intent(this, typeof(TrackingService));
        PendingIntent pendingIntent = PendingIntent.GetBroadcast(this, 0, intent, PendingIntentFlags.CancelCurrent);

        WriteLine($"Started tracking with period of {period} seconds.");
        AlarmManager manager = (AlarmManager)GetSystemService(AlarmService);
        manager.SetRepeating(AlarmType.RtcWakeup, SystemClock.ElapsedRealtime(), period * 1000, pendingIntent);
    }

    private void StopTrackingAlarm()
    {
        Intent intent = new Intent(this, typeof(TrackingService));
        PendingIntent pendingIntent = PendingIntent.GetBroadcast(this, 0, intent, 0);

        WriteLine($"Stopped tracking at {DateTime.Now.ToLongTimeString()} seconds.");
        AlarmManager manager = (AlarmManager)GetSystemService(AlarmService);
        manager.Cancel(pendingIntent);
    }

BroadcastReceiver

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new string[] { "android.intent.action.BOOT_COMPLETED" }, Priority = (int)IntentFilterPriority.HighPriority)]
public class TrackingService : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        Intent intentToStart = new Intent(context, typeof(LocationService));
        context.StartService(intentToStart);
    }
}

LocationService

[Service]
public class LocationService : IntentService, ILocationListener
{
    private string LogTag => $"[{nameof(LocationService)}]";
    private LocationManager LocManager { get; set; }
    private string LocationProvider { get; set; }

    protected override void OnHandleIntent(Intent intent)
    {
        Log.WriteLine(LogPriority.Debug, LogTag, $"Handling intent at {DateTime.Now.ToLongTimeString()}");
        InitializeLocationManager();

        if (LocManager.IsProviderEnabled(LocationProvider))
        {
            LocManager.RequestSingleUpdate(LocationProvider, this, null);
            Location location = LocManager.GetLastKnownLocation(LocationProvider);
            Log.WriteLine(LogPriority.Debug, LogTag, $"Last Position: [{location.Latitude}, {location.Longitude}].");
        }      
    }

    private void InitializeLocationManager()
    {
        LocManager = (LocationManager)GetSystemService(LocationService);
        Criteria criteriaForLocationService = new Criteria { Accuracy = Accuracy.Fine };
        IList<string> acceptableLocationProviders = LocManager.GetProviders(criteriaForLocationService, true);

        if (acceptableLocationProviders.Any())            
            LocationProvider = acceptableLocationProviders.First();            
        else            
            LocationProvider = string.Empty;

        Log.Debug(LogTag, $"Using {LocationProvider} at {DateTime.Now}.");
    }

    #region ILocationListener
    public void OnLocationChanged(Location location) { }

    public void OnProviderDisabled(string provider) { }

    public void OnProviderEnabled(string provider) { }

    public void OnStatusChanged(string provider, [GeneratedEnum] Availability status, Bundle extras) { }
    #endregion
}
...