簡體   English   中英

Android 10 服務停止工作一次不充電和屏幕關閉

[英]Android 10 service stops working once not charging and screen turned off

我編寫了服務來觀看連接到我的 wifi 的 ping 設備,以便關閉/關閉公寓的暖氣。

我正要購買樹莓派,但我想到了使用我的舊 android 10 手機運行血統操作系統。

我確實寫了服務。 它運行良好,直到我關閉屏幕。 然后它停止 ping 設備並控制加熱 api。

一旦我重新打開屏幕,它就會再次自行啟動。

這就是我啟動服務的方式:

        public void StartService()
        {
            var intent = new Intent(context, typeof(AutomationService));

            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
            {
                context.StartForegroundService(intent);
            }
            else
            {
                context.StartService(intent);
            }
        }

通知:

        public Notification GetNotification()
        {
            // Building intent
            var intent = new Intent(context, typeof(MainActivity));
            intent.AddFlags(ActivityFlags.SingleTop);
            intent.PutExtra("Title", "Message");

            var pendingIntent = PendingIntent.GetActivity(context, 0, intent, PendingIntentFlags.UpdateCurrent);

            var notifBuilder = new NotificationCompat.Builder(context, foregroundChannelId)
                .SetContentTitle("Netatmo automation")
                .SetContentText("Running")
                .SetSmallIcon(Resource.Drawable.abc_ab_share_pack_mtrl_alpha)
                .SetOngoing(true)
                .SetContentIntent(pendingIntent);

            // Building channel if API verion is 26 or above
            if (global::Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                NotificationChannel notificationChannel = new NotificationChannel(foregroundChannelId, "Title", NotificationImportance.High);
                notificationChannel.Importance = NotificationImportance.High;
                notificationChannel.EnableLights(true);
                notificationChannel.EnableVibration(true);
                notificationChannel.SetShowBadge(true);
                notificationChannel.SetVibrationPattern(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 });

                var notifManager = context.GetSystemService(Context.NotificationService) as NotificationManager;
                if (notifManager != null)
                {
                    notifBuilder.SetChannelId(foregroundChannelId);
                    notifManager.CreateNotificationChannel(notificationChannel);
                }
            }

            return notifBuilder.Build();
        }

以及服務本身:

    [Service]
    public class AutomationService : Service
    {
        public AutomationService()
        {
            controlApplication = new ControlApplication();
        }
        public override IBinder OnBind(Intent intent)
        {
            return null;
        }

        public const int ServiceRunningNotifID = 9000;
        private readonly ControlApplication controlApplication;

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            Notification notif = DependencyService.Get<INotificationHelper>().GetNotification();
            StartForeground(ServiceRunningNotifID, notif);

            controlApplication.StartApplication();

            return StartCommandResult.Sticky;
        }

        public override void OnDestroy()
        {
            base.OnDestroy();
        }

        public override bool StopService(Intent name)
        {
            return base.StopService(name);
        }

    }

這部分controlApplication.StartApplication(); 只是在執行 ping 檢查並通過邏輯發送 http 請求的任務中啟動 while(true) 循環。

有人可以幫我在屏幕關閉時如何讓服務保持活力嗎?

我首先選擇了手機,因為它比覆盆子更省電。

我會很高興有任何意見。

干杯

編輯 -

這是 StartApplication 方法...它不在主線程上運行。

        public void StartApplication()
        {
            this.Log().Debug("Starting application");
            _ = Task.Run(async () =>
            {
                await authorizationService.AuthorizeAsync(username, password).ConfigureAwait(false);
                pingWatchService.Start();
            });
        }

問題是 while(true) 循環在主線程中運行。 當屏幕關閉時,循環將阻塞。 所以你的服務將被系統殺死。 當我在 OnStartCommand 方法中添加一個 while(true) 時,我重復了你的問題。 你可以解決它,只需創建一個新線程來執行循環。 如:

Thread thread = new Thread( controlApplication.StartApplication);
thread.Start();

使用 PowerManager 服務:

將代碼添加到您的服務。

 private PowerManager.WakeLock wakeLock;
 PowerManager powerManager = (PowerManager)this.GetSystemService(Context.PowerService);
 wakeLock = powerManager.NewWakeLock(WakeLockFlags.Partial,Class.Name);
 wakeLock.Acquire();

並添加 wakeLock.Release(); 到服務的 OnDestory 方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM