Xamarin.Android:屏幕关闭时服务停止工作(Doze / App待机模式)

时间:2017-06-03 07:01:08

标签: android xamarin.android android-doze android-doze-and-standby

我必须每120秒发送一次GPS(Lat / Lon)服务。到我的REST后端。

我遇到的问题是,当屏幕关闭时,服务似乎停止工作。

  1. 尝试使用StartedService和BroadcastReceiver
  2. 尝试使用IntentService和WakefulBroadcastReceiver
  3. 1.尝试在SAMSUNG Galaxy X COVER上工作,但在HUAWEI P9 Lite上没有。尽管我已经关闭了HUAWEI手机中的省电模式(Power Apps)。所以我的应用程序在屏幕关闭时继续运行。在例如10分钟之后,我在华为手机上打开了屏幕,看到服务正在运行的运行服务(经过几秒钟),所以我可以验证服务没有关闭。

    2.屏幕关闭时,尝试无手机。

    当屏幕开启(无睡眠)时,两次尝试都正常工作。

    注意:为简洁起见,我删除了不相关方法的代码(获取/传输gps数据)。

    以下是1.尝试的代码:

    服务

    [Service]
    public class GpsTrackerService : Service
    {
        private static readonly string LogTag = "X:TruckerApp-" + typeof(GpsTrackerService).Name;
        private static readonly int NOTIFICATION_ID = 10000;
        private MobileServiceClient _mobileServiceClient;
    
        public TelephonyManager GetTelefonyManager()
        {
            return (Android.Telephony.TelephonyManager) GetSystemService(TelephonyService);
        }
    
        public bool IsRunningAsService { get; set; }
    
    
        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            Log.Debug(LogTag, "GpsTrackerService.OnStartCommand :: Service started. Timer instantiated.");
            GpsTrackerServiceUtils.SendGenericMessageToApplicationInsights("Gps-Info", LogTag, _mobileServiceClient, this, "GpsTrackerService.OnStartCommand :: Service started.Timer instantiated.");
    
            Task.Run(async () =>
            {
                try
                {
                    await DoWork();
                    await Task.Delay(TimeSpan.FromMinutes(2));
                }
                catch (Exception e)
                {
                    Log.Debug(LogTag, $"GpsTrackerService.HandleTimerCallback :: (OUTER try-catch) Exception:{e.Message} Type:{e.GetType().Name}, Stacktrack:{e.StackTrace}");
                    if (e.InnerException != null)
                    {
                        Log.Debug(LogTag, $"GpsTrackerService.HandleTimerCallback :: (OUTER try-catch) Exception:{e.InnerException.Message} Type:{e.InnerException.GetType().Name}, Stacktrack:{e.InnerException.StackTrace}");
                    }
                    GpsTrackerServiceUtils.SendExceptionToApplicationInsights(e, LogTag, _mobileServiceClient, this);
                }
                finally
                {
                    // Restart Service
                    Intent broadcastIntent = new Intent(action: GpsConstants.GpsRestart);
                    SendBroadcast(broadcastIntent);
                }
    
            });
    
            return StartCommandResult.Sticky;
        }
    
          public override IBinder OnBind(Intent intent)
        {
            // This is a started service, not a bound service, so we just return null.
            return null;
        }
    }
    

    广播接收器

    [BroadcastReceiver(Enabled = true, Exported = true, Name = GpsConstants.GpsBroadcastReceiver, Label = "RestartServiceWhenStopped")]
    [IntentFilter(new[] {GpsConstants.GpsRestart})]
    public class GpsTrackerServiceBroadcastReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            try
            {
                MetricsManagerHelper.Instance.SendGenericMessageToApplicationInsights("Gps-Info", "OnReceive :: Gps Service broadcast message received. Restarting GPS Service...");
                context.StartService(new Intent(context, typeof(GpsTrackerService)));
             }
            catch (Exception e)
            {
                MetricsManagerHelper.Instance.SendExceptionToApplicationInsights(e);
            }
        }
    }
    

    在MainActivity.OnCreate中注册Broadcastreceiver

     GpsTrackerServiceBroadcastReceiver = new GpsTrackerServiceBroadcastReceiver();
     RegisterReceiver(GpsTrackerServiceBroadcastReceiver, new IntentFilter(GpsConstants.GpsBroadcastReceiver));
    

    2.Attempt

    服务

    [Service]
    public class GpsTrackerIntentService : IntentService
    {
        private static readonly string LogTag = "X:TruckerApp-" + typeof(GpsTrackerIntentService).Name;
        private static readonly int NOTIFICATION_ID = 10000;
        private MobileServiceClient _mobileServiceClient;
    
        public TelephonyManager GetTelefonyManager()
        {
            return (TelephonyManager) GetSystemService(TelephonyService);
        }
    
        protected override async void OnHandleIntent(Intent intent)
        {
            try
            {
                // perform task
                await Bootstrap();
    
                GpsTrackerServiceUtils.SendGenericMessageToApplicationInsightsWakeLock("Gps-Info", LogTag, _mobileServiceClient, this, "GpsTrackerService.OnHandleIntent :: Invoked.");
    
                await DoWork();
                await Task.Delay(TimeSpan.FromMinutes(2));
            }
            catch (Exception e)
            {
                Log.Debug(LogTag, $"GpsTrackerService.OnCreate :: Exception:{e.Message} Type:{e.GetType().Name}");
                GpsTrackerServiceUtils.SendExceptionToApplicationInsightsWakeLock(e, LogTag, _mobileServiceClient, this);
            }
            finally
            {
                WakefulBroadcastReceiver.CompleteWakefulIntent(intent);
                SendBroadcast(new Intent(this, typeof(GpsTrackerServceWakefulReceiver)));
                //var wakefulReceiverIntent = new Intent(this, typeof(GpsTrackerServceWakefulReceiver));
                //var pending = PendingIntent.GetBroadcast(this, 0, wakefulReceiverIntent, PendingIntentFlags.UpdateCurrent);
                //AlarmManager manager = (AlarmManager)GetSystemService(AlarmService);
                //manager.SetRepeating(AlarmType.RtcWakeup, SystemClock.ElapsedRealtime(), 120 * 1000, pending);
            }
        }
    
    
        public async Task DoWork()
        {
            // long running code ...
            Log.Debug(LogTag, "GpsTrackerService.HandleTimerCallback :: Invoked.");
            GpsTrackerServiceUtils.SendGenericMessageToApplicationInsightsWakeLock("Gps-Info", LogTag, _mobileServiceClient, this, "GpsTrackerService.HandleTimerCallback :: Invoked.");
    
    
        }
    }
    

    WakefulReceiver

    [BroadcastReceiver]
    public class GpsTrackerServceWakefulReceiver : WakefulBroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            var serviceIntent = new Intent(context, typeof(GpsTrackerIntentService));
            StartWakefulService(context, serviceIntent);
        }
    }
    

    的AndroidManifest.xml

    添加了WAKE_LOCK权限

      <uses-permission android:name="android.permission.WAKE_LOCK"/>
      <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
    

    我现在非常绝望。希望可以有人帮帮我。 感谢

    埃里克

0 个答案:

没有答案