Huawei, оптимизация батареи телефонов Honor, Foreground Service - PullRequest
4 голосов
/ 22 января 2020

Этот вопрос может показаться очень широким, но я постараюсь подвести итог как можно более коротким.

Итак, я тиражирую пример приложения в магазине Play Multi Timer Free

Приложение предназначено для установки нескольких таймеров.

Я почти завершил приложение. но я сталкиваюсь с некоторыми проблемами оптимизации батареи и Alarm Manager, в частности, Huawai и Honor (китайская ОС Andorid). Моя служба Foreground перестает работать через некоторое время.

Вопрос: Пример приложения, упомянутого выше, работает очень фантастично c даже без белого списка оптимизации батареи. Что может быть решением для этого?

Я почти все, что упомянуто в ссылках ниже. но не повезло

Режим ожидания - продолжают ли работать службы переднего плана?

Как обрабатывать фоновые службы в ANDROID O?

Как отключить оптимизацию батареи на устройствах Huawei

Как отключить оптимизацию батареи на устройствах Huawei

Как отключить оптимизацию батареи на устройствах Huawei

Не убивайте мое приложение!

Устройство Huawei, убивающее мой сервис переднего плана, даже с помощью dontkillmyapp Решение .com

Не выключайте устройство

Оптимизируйте для режима ожидания и ожидания приложения

Android M startActivity Оптимизация батареи

Оптимизация батареи (wakelocks) в Huawei EMUI 4.0 +

служба убита, когда приложение закрывается только на устройстве huawei

Oreo (8.1) не может запустить действие на экране блокировки

Создание бесконечного фона ая служба в Android> 7

Как режим ожидания влияет на фоновые / передние услуги, с / без частичных / полных wakelocks?

Что делать, если аварийные сигналы или отслеживание сна не работают?

Пример кода, Когда нажата кнопка блокировки / разблокировки устройства, я хочу, чтобы при получении сообщения SCREEN_ON показывался простой TOAST. Это работает нормально в течение некоторого времени.

Но в устройстве Huawei => После уничтожения приложения проведением пальцем -> через 1 - 2 минуты мой тост перестает работать.

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
    )
}
}

1 Ответ

0 голосов
/ 29 января 2020

Может быть проблема в том, что у вас нет setRepeating при планировании будильника?

Я делаю в основном то же самое (обновляю виджет, когда экран включен), и я делать это так:

alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis() + 1000, interval, pendingIntent)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...