Я делаю приложение Alarm и использую AlarmManager для установки сигналов тревоги. Я сохраняю каждый будильник с помощью Room после запуска setAlarm в AlarmManager, поэтому я могу позже восстановить их, если телефон выключится и o .
Я запускаю BroadcastReceiver после загрузки устройства, используя руководство с сайта разработчика Android: https://developer.android.com/training/scheduling/alarms#boot
И моя идея состоит в том, чтобы получать будильники из комнаты по методу onReceive Но Room использует приостановку для получения сигналов тревоги, но я не могу запустить ее на onReceive, так как BroadcastReceiver не имеет жизненного цикла.
Как я мог добиться подобного результата?
@CommonsWare Я думаю, что они что-то берут из комнаты, поэтому им нужен способ, чтобы получатель мог дождаться ввода-вывода.
В точку. В репозитории есть функция приостановки, которая получает информацию. И чтобы вызвать эту функцию, мне нужно запустить ее в области сопрограммы.
В этом разделе документации BroadcastReceiver приведен пример того, как это сделать.
Вы можете немного почистить его с помощью функции расширения:
fun BroadcastReceiver.goAsync(
context: CoroutineContext = EmptyCoroutineContext,
block: suspend CoroutineScope.() -> Unit
) {
val pendingResult = goAsync()
CoroutineScope(SupervisorJob()).launch(context) {
try {
block()
} finally {
pendingResult.finish()
}
}
}
Затем в своем приемнике вы можете использовать его, как показано ниже. Код в блоке goAsync
— это сопрограмма. Помните, что вы не должны использовать Dispatchers.Main
в этой сопрограмме.
override fun onReceive(context: Context, intent: Intent) = goAsync {
val repo = MyRepository.getInstance(context)
val alarms = repo.getAlarms() // a suspend function
// do stuff
}
Любить это!. Я проверю это сегодня вечером, и если это сработает, отметьте ваш ответ как решение
Я бы сказал, что какой-то одноэлементный объект репозитория должен быть тем, который взаимодействует с Room, а ваш получатель говорит репозиторию что-то делать. Репозиторий может использовать уровень процесса
CoroutineScope
, который вы специально настроили для такой работы.