#android #kotlin #android-intent #android-service
#Android #kotlin #android-намерение #android-сервис
Вопрос:
ForegroundService
Для запуска у меня требуется некоторое время. Тем временем пользователь может перейти к приложению в фоновом режиме во время его работы, например, нажав кнопку «Домой» или введя другое приложение. Когда ForegroundService
достигается «триггер», он пытается запустить новое намерение. Это отлично работает, если приложение находится на переднем плане, но не работает, если оно находится в фоновом режиме. Цель состоит в том, чтобы при достижении «триггера» приложение вернулось на передний план, чтобы пользователь мог внести необходимый вклад в новое намерение. В попытке сделать это я добавил флаги FLAG_ACTIVITY_NEW_TASK
, и FLAG_ACTIVITY_SINGLE_TOP
, похоже, они этого добьются. Но приложение не возвращается на передний план. Это то, что можно сделать?
Ниже приведены соответствующие части рассматриваемого кода:
MainActivity.kt
...
private fun startService() {
val serviceIntent = Intent(this, ForegroundService::class.java)
ContextCompat.startForegroundService(this, serviceIntent)
}
...
ForegroundService.kt
...
//When trigger is reached, start the new activity and bring app to foreground if it was moved to background
private fun startNewActivity() {
//First two lines are to shut down the foreground service since it has reached a trigger and is complete.
super.onDestroy()
stopSelf()
//Start the new intent
val startNewIntent = Intent(this, NewIntent:: class.java)
startNewIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP //Assumption was these flags would bring app to foreground
startActivity(startNewIntent)
}
...
Ответ №1:
Чтобы зарегистрировать намерение в системе, вам нужно использовать a PendingIntent
вместо обычного Intent
; когда служба переднего плана завершена (когда срабатывает ваш триггер), вы можете отправить это ожидающее намерение с помощью send()
метода
ForegroundService.kt
...
//When trigger is reached, start the new activity and bring app to foreground if it was moved to background
private fun startNewActivity() {
//First two lines are to shut down the foreground service since it has reached a trigger and is complete.
super.onDestroy()
stopSelf()
//Start the new intent
val startNewIntent = Intent(this, NewIntent:: class.java)
val pendingIntent = PendingIntent.getActivity(
this, 0, startNewIntent,
PendingIntent.FLAG_UPDATE_CURRENT
or PendingIntent.FLAG_ONE_SHOT
)
try {
pendingIntent.send() // this should start `NewIntent` activity
} catch (e: CanceledException) {
e.printStackTrace()
}
}
...
Комментарии:
1. спасибо за сообщение. Я попытался реализовать это и обнаружил, что оно ведет себя так же, как и раньше. Другими словами, приложение не возвращается на передний план, используя
PendingIntent
, хотя журналы отладки показывают, чтоpendingIntent.send()
это вызывается. Я нашел эту ссылку , где говорится: «приложение может запускать действия в течение нескольких секунд после отправки ожидающего намерения». Похоже, это должно сработать.2. Более того,
pendingIntent.send()
вызывается, ноonCreate
в NewIntent не вызывается, пока я вручную не верну приложение в фокус. Это было определено с помощью ведения журнала.3. Кажется странным.. Можете ли вы протестировать его на другом устройстве и на другом уровне API… Также, возможно, вам нужно отправить BroadcastReceiver, завернутый с ожидающим намерением.. И сделайте тот же код в onReceive ()
4. Я тестировал в API v16, и это сработало. Но тестирование с помощью API v30 как в эмуляторе, так и на физическом устройстве не сработало. Интересно, произошли ли изменения, блокирующие это в более новых версиях? Есть ли у вас пример использования BroadcastReceiver, завернутого с ожидающим намерением?
5. @Tom произошли изменения на уровне API 29 (Android 10), которые описаны в документе здесь: developer.android.com/guide/components/activities/… В нем изложен список условий, одно из которых должно быть выполнено, чтобы вывести приложение на передний план.