这个问题可能看起来很广泛,但我会尽力总结一下。

因此,我在Play商店Multi Timer Free上复制了一个示例应用

该应用程序用于设置多个计时器。

我已经快完成了应用程序。但我遇到了一些电池优化和警报管理器的问题,尤其是Huawai和Honor(中国Andorid OS)。我的前台服务在一段时间后停止工作。

问题:
上面提到的示例应用程序即使没有电池优化白名单,也可以非常出色地工作。对此有什么解决方案?

我几乎尝试了以下链接中提到的所有内容。但没有运气

Doze mode - do foreground services continue to run?

How to handle background services in ANDROID O?

How to turn off battery optimization on Huawei devices

How to turn off battery optimization on the Huawei devices

How to turn off battery optimization on Huawei devices

Don't kill my app!

Huawei device killing my foreground service, even with dontkillmyapp.com's solution

Keep the device awake

Optimize for Doze and App Standby

Android M startActivity battery optimization

Battery optimizations (wakelocks) on Huawei EMUI 4.0+

service killed when app cloes just in huawei device

Oreo (8.1) cannot start activity on lock screen

Creating a never ending background service in Android > 7

How does doze mode affect background/foreground services, with/without partial/full wakelocks?

What to do if alarms or sleep tracking don’t work?


package com.demo.forgroundservicedemo

import android.content.Intent
import android.os.IBinder
import androidx.core.app.NotificationCompat
import android.os.Build
import android.app.*
import android.app.NotificationManager
import android.app.NotificationChannel
import android.content.BroadcastReceiver
import android.content.Context
import android.content.IntentFilter
import android.graphics.Color
import android.util.Log
import androidx.annotation.RequiresApi
import android.os.SystemClock
import android.app.AlarmManager
import android.app.PendingIntent
import android.widget.Toast


class ForegroundService : Service() {

    override fun onCreate() {
        Log.e("ForegroundService", "onCreate called")
        super.onCreate()
    }

@RequiresApi(Build.VERSION_CODES.O)
private fun startMyOwnForeground() {
    val NOTIFICATION_CHANNEL_ID = CONST.CHANNELID
    val channelName = CONST.channelName
    val chan = NotificationChannel(
        NOTIFICATION_CHANNEL_ID,
        channelName,
        NotificationManager.IMPORTANCE_NONE
    )
    chan.lightColor = Color.BLUE
    chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
    val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    manager.createNotificationChannel(chan)

    val notificationIntent = Intent(this, MainActivity::class.java)

    notificationIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP

    val intent = PendingIntent.getActivity(
        this, 0,
        notificationIntent, 0
    )

    val notificationBuilder = NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
    notificationBuilder.setContentIntent(intent)
    val notification = notificationBuilder.setOngoing(true)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle(CONST.serviceTitle)
        .setPriority(NotificationManager.IMPORTANCE_MIN)
        .setCategory(Notification.CATEGORY_SERVICE)
        .setAutoCancel(false)
        .build()

    notification.flags = notification.flags or Notification.FLAG_AUTO_CANCEL
    startForeground(2, notification)
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

    Log.e("ForegroundService", "onStartCommand called")
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        Log.e("SDK_INT", ">= Build.VERSION_CODES.O")
        startMyOwnForeground()
    } else {
        startForeground(1, Notification())
    }

    registerBroadcastReceiver()
    return START_STICKY
}

override fun onDestroy() {
    Log.e("ForegroundService", "onDestroy called")
    super.onDestroy()
}

override fun onBind(intent: Intent?): IBinder? {
    return null
}

private var mPowerKeyReceiver: BroadcastReceiver? = null

private fun registerBroadcastReceiver() {

    Log.e("registerBroadcast", "called")
    val theFilter = IntentFilter()
    /** System Defined Broadcast  */
    theFilter.addAction(Intent.ACTION_SCREEN_ON)
    //theFilter.addAction(Intent.ACTION_SCREEN_OFF)

    mPowerKeyReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {

            Log.e("onReceive", "onReceive called")
            val strAction = intent!!.action

            if (strAction == Intent.ACTION_SCREEN_ON) {
                Toast.makeText(context, "SCREEN ON", Toast.LENGTH_LONG).show()
            }
        }
    }

    applicationContext.registerReceiver(mPowerKeyReceiver, theFilter)
}

private fun unregisterReceiver() {
    val apiLevel = Build.VERSION.SDK_INT

    if (apiLevel >= 7) {
        try {
            applicationContext.unregisterReceiver(mPowerKeyReceiver)
        } catch (e: IllegalArgumentException) {
            mPowerKeyReceiver = null
        }

    } else {
        applicationContext.unregisterReceiver(mPowerKeyReceiver)
        mPowerKeyReceiver = null
    }
}

override fun onTaskRemoved(rootIntent: Intent?) {
    super.onTaskRemoved(rootIntent)
    Log.e("onTaskRemoved", "onTaskRemoved called")
    unregisterReceiver()

    val restartService = Intent(
        applicationContext,
        this.javaClass
    )
    restartService.setPackage(packageName)
    val restartServicePI = PendingIntent.getService(
        applicationContext, 1, restartService,
        PendingIntent.FLAG_ONE_SHOT
    )
    val alarmService =
        applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
    alarmService.setExactAndAllowWhileIdle(
        AlarmManager.ELAPSED_REALTIME,
        SystemClock.elapsedRealtime() + 500,
        restartServicePI
    )
}
}

最佳答案

也许问题是在安排警报时您没有setRepeating

我基本上是在做同样的事情(在屏幕打开时更新小部件),并且这样做是这样的:

alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis() + 1000, interval, pendingIntent)

10-04 23:01