私は、Oreoより前のすべてのOSバージョンで適切に動作するフォアグラウンドサービスを作成しました。 Oreoから、アプリケーションを閉じて、最近のアプリケーションを削除してから5分後にプロセスが強制終了されます。
Androidの開発者向けドキュメント バックグラウンド実行制限 OSは、フォアグラウンドサービスが実行され、通知ウィンドウに通知が表示されているアプリケーションを強制終了してはなりません。
開発者向けドキュメントのガイドラインに従って。以下の手順に従って、フォアグラウンドサービスを開始しました。
startForegroundService()
メソッドで開始されますstartForeground()
を使用してサービスの通知が表示されますservice
のonStartCommand()
からSTART_STICKY
を返します次の電話でこの問題に直面しています。
フォアグラウンドサービスが破壊されるのを防ぐために何を試みましたか?
フォアグラウンドサービスを再起動しようとしましたか?
AlarmManager
を使用して、onTaskRemoved()からサービスを再起動しました。詳細については、 このリンク を確認してください。私の理解では、これらのメーカーはAOSPをカスタマイズしており、フォアグラウンドサービスの実行を許可するためのOSガイドラインを尊重していません。これらのメーカーは、ユーザーに長いバッテリー寿命を与えているため、これを行っている可能性があります。
フォアグラウンドサービスクラス
class DataCaptureService : Service() {
private var isServiceStarted = false
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).run {
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WakelockTag123").apply {
acquire()
}
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val serviceAction = intent?.action
LogUtils.logD("OnStartCommand(). Action=$serviceAction")
if (Constants.INTENT.ACTION_STOP_SERVICE == serviceAction) {
LogUtils.logD("Stopping data capture service")
stopForeground(true)
stopSelf()
} else if (Constants.INTENT.ACTION_START_SERVICE == serviceAction && !isServiceStarted) {
LogUtils.logD("Starting data capture service")
isServiceStarted = true
// Here showing notification using a utility method (startForeground(id, notification))
createNotification(this)
// Doing some stuff here
----------------------
//
}
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
if (isServiceStarted) {
LogUtils.logD("onDestroy of DataCaptureService method is invoked")
// Doing some stuff here
----------------------
//
isServiceStarted = false
if (wakeLock.isHeld) {
wakeLock.release()
}
}
}
override fun onTaskRemoved(rootIntent: Intent?) {
LogUtils.logD("onTaskRemoved of DataCaptureService method is invoked")
ensureServiceStaysRunning()
super.onTaskRemoved(rootIntent)
}
private fun ensureServiceStaysRunning() {
val restartAlarmInterval = 60 * 1000
val resetAlarmTimer = 30 * 1000L
// From this broadcast I am restarting the service
val restartIntent = Intent(this, ServiceRestartBroadcast::class.Java)
restartIntent.action = "RestartedViaAlarm"
restartIntent.flags = Intent.FLAG_RECEIVER_FOREGROUND
val alarmMgr = getSystemService(Context.ALARM_SERVICE) as AlarmManager
val restartServiceHandler = @SuppressLint("HandlerLeak")
object : Handler() {
override fun handleMessage(msg: Message) {
val pendingIntent = PendingIntent.getBroadcast(applicationContext, 87, restartIntent, PendingIntent.FLAG_CANCEL_CURRENT)
val timer = System.currentTimeMillis() + restartAlarmInterval
val sdkInt = Build.VERSION.SDK_INT
if (sdkInt < Build.VERSION_CODES.KitKat)
alarmMgr.set(AlarmManager.RTC_WAKEUP, timer, pendingIntent)
else if (Build.VERSION_CODES.KitKat <= sdkInt && sdkInt < Build.VERSION_CODES.M)
alarmMgr.setExact(AlarmManager.RTC_WAKEUP, timer, pendingIntent)
else if (sdkInt >= Build.VERSION_CODES.M) {
alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timer, pendingIntent)
}
sendEmptyMessageDelayed(0, resetAlarmTimer)
stopSelf()
}
}
restartServiceHandler.sendEmptyMessageDelayed(0, 0)
}
}
同様のタイプの問題に直面し、この解決策を見つけることができた場合は、提案を共有してください。
私はあなたと同じ状況にいるので、OnePlusの問題を分析しました。現在見ているように、解決策はありません。 OnePlusは明らかに悪い慣習に従っています。
この方法でプロセスを強制終了するソースコードをリリースしていないため、OnePlus ROM(OnePlus 5T 5.1.5を選択)をダウンロードし、それを抽出し、これを行う.classを見つけます。 (services.vdexのOnePlusHighPowerDetector.class)、それを逆コンパイルし、何が起こっているのかを見つけようとしました。
このクラスのバージョンはここで見つけることができます(私によるものではなく、おそらく私が使用したバージョンとは異なります): https://github.com/joshuous/oneplus_blobs_decompiled/blob/master /com/Android/server/am/OnePlusHighPowerDetector.Java
残念ながら、最も重要な関数は正常に逆コンパイルされません。しかし、とにかくバイトコードを分析できます。私が見つけたものは次のとおりです。
com_oneplus_systemui_recent_task_lockd_list
)、殺されません。そのため、ユーザーはピン留めしてアプリを保存できます。しかし、彼らにとっては不便です。oneplus-framework-res.apk/res/values/array.xml
、キーstring-array name="backgroundprocess_detection_app_whitelist"
。このリストには主に地図とフィットネスのアプリケーションが含まれています1。.vdexファイルを逆コンパイルするために必要な手順は次のとおりです。
--ignore-crc-error
オプション)1暴言:これは、現在の状況がどれほど悪いかを示しています。 OnePlus、これは本当に解決策ですか?バックグラウンドで実行できる10〜15個のアプリケーションを選択しましたが、他のすべてのアプリケーションを気にしませんか?デバイスで安全に動作する新しいフィットネス/マップ/音楽プレーヤーアプリケーションを作成するにはどうすればよいですか?
この問題を解決するのに数時間費やしました。 Xiaomi電話、オレオ。私には解決策があります、2つのステップ:
Xiaomiには追加の許可が必要です。設定->許可->自動起動。自動的に開始できるアプリケーションのリストがあります。 BOOT_COMPLETEDとSTART_STICKYでは不十分です。 Facebook、Outlook、Skype +私のアプリがここにリストされています。ユーザーにプログラムでこの許可を与えるように依頼する方法がわかりません。
サービスは再作成されますが、START_STICKYを返しても再起動されません。アプリを強制終了(実行中のアプリからスワイプアウト)すると、onCreateが再度呼び出されますが、onStartCommandは呼び出されません。 Log.d()を試してみてください。通知を作成し、startForeground()を呼び出してSTART_STICKYを返す以外のすべてのロジックをonCreateに移動しました。これはonStartCommand()に残っている必要があります。
アプリケーションのBatery最適化も無効にする必要がありますが、以前のバージョンのAndroidで既に必要でした。
現在、私のサービスは数秒以内に実行を継続するか、100%成功して再作成されます。
サービス内でstartForeground(id, notification)
メソッドを使用します。
ユーザーは、システムによって殺されない何かがバックグラウンドで動作していることを知っている必要があります。そのため、Androidシステムは通知をユーザーに通知する必要があります。
ちなみにWakeLockを使用できます。
PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PARTIAL_WAKE_LOCK,
TAG_FOR_DEBUG);
wakeLock.acquire()
ただし、使用する前にWakeLockを読んでください。また、作業が終了したら無効にすることを忘れないでください。
Terminalでadb Shell dumpsys power
コマンドを使用して、現在有効なウェイクロックを確認できます。
私のアプリのOnePlus3でも同じ問題に直面しました。その後、アプリとフォアグラウンドサービスが強制終了されるたびに、logcatで次の行に気付きました。
10-12 18:30:40.644 1439 1519 I OHPD : [BgDetect]force stop com.mycompany.MyAndroidApp (uid 10905) level 0
10-12 18:30:40.645 1439 1519 I ActivityManager: Force stopping com.mycompany.MyAndroidApp appid=10905 user=0: from pid 1439
10-12 18:30:40.645 1439 1519 I ActivityManager: Killing 23139:com.mycompany.MyAndroidApp/u0a905 (adj 200): stop com.mycompany.MyAndroidApp
10-12 18:30:40.647 1439 1519 W ActivityManager: Scheduling restart of crashed service com.mycompany.MyAndroidApp/md55852635cfc9dced970aa39ae09e74ead.MyForegroundService in 1000ms
10-12 18:30:40.651 1439 1519 I ActivityManager: Force finishing activity ActivityRecord{a5c8d39 u0 com.mycompany.MyAndroidApp/md55852635cfc9dced970aa39ae09e74ead.MainActivity t3108}
10-12 18:30:40.655 1439 1519 I ActivityManager: Force stopping service ServiceRecord{6052f94 u0 com.mycompany.MyAndroidApp/md55852635cfc9dced970aa39ae09e74ead.MyForegroundService}
10-12 18:30:40.660 1439 1519 I OHPD : [BgDetect]chkExcessCpu level: 1 doKills: true critical false uptime: 300328
10-12 18:30:40.710 1439 8213 I WindowManager: WIN DEATH: Window{c381342 u0 com.mycompany.MyAndroidApp/md55852635cfc9dced970aa39ae09e74ead.MainActivity}
次に、キーワード「OHPD:[BgDetect] chkExcessCpu level:1 doKills:true」でインターネットを検索すると、このSO answer:
「フォークされたプロセスで過剰なCPUを検出する」ためにバックグラウンドサービスが強制終了されないようにする
その回答とGitHubの問題で示唆されているように、アプリをロック/ピン留めすると、Oxygen OSがアプリ(MainActivityおよびForground Service)を強制終了できなくなりました。
oneplus 6tでは、このadbコマンドを実行します
設定putシステムcom_oneplus_systemui_recent_task_lockd_list {com.topjohnwu.magisk/a.c#0} {com.mycompany.MyAndroidApp/com.mycompany.MyAndroidApp.MainActivity#0}
com.topjohnwu.magiskおよびcom.mycompany.MyAndroidAppの強制終了を防ぎます