#android #kotlin #service #retrofit2 #alarmmanager
#Android #kotlin #Обслуживание #retrofit2 #alarmmanager
Вопрос:
Итак, я пытаюсь запустить службу, которая отправляет определенные данные о комнате на сервер каждую полночь (примерно) и удаляет их из локальной базы данных. Читая документы Android, я пришел к выводу, что лучшим подходом в настоящее время является настройка будильника, который срабатывает в полночь и запускает службу, которая выполняет синхронизацию). Хотя я не совсем уверен, какой тип сервиса мне следует использовать, мои файлы выглядят так:
MainActivity.kt
alarmMgr = applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager?
alarmIntent = Intent(this, SendTakesReceiver::class.java).let { intent ->
PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
// Set the alarm to send takes at approximately 00:00 a.m.
val calendar: Calendar = Calendar.getInstance().apply {
timeInMillis = System.currentTimeMillis()
set(Calendar.HOUR_OF_DAY, 0)
}
// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr?.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
alarmIntent
)
SendtakesReceiver.kt
class SendTakesReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
//these following logs are always shown
Log.d("TAKES INTENT", intent.toString())
if (intent != null) {
context?.run {
Log.d("TAKES SERVICE", intent.toString())
startService(intent)
}
}
}
}
SendTakesService.kt
class SendTakesService : Service() {
val sp: SharedPreferences = getSharedPreferences("login", Context.MODE_PRIVATE)
private var prescriptionTakeDao =
AppDatabase.getDatabase(applicationContext).prescriptionTakeDao()
override fun onCreate() {
super.onCreate()
Log.d("TakesService", "onCreate()")
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
}
И, наконец, в моем файле манифеста у меня есть (внутри тега приложения):
<receiver
android:name=".src.ui.prescriptions.SendTakesReceiver"
android:enabled="true" />
<service
android:name="com.glik.glik.src.services.SendTakesService"
android:enabled="true"
android:process=":SendTakes">
</service>
Но проблема в том, что ни один из классов служб (Service, IntentService, JobIntentService), которые я пытался использовать, не вызывает их основной метод. Например, здесь onCreate()
журнал никогда не отображается. Я видел бесчисленное множество подобных вопросов, касающихся того, что службы не запускаются, но, похоже, я не могу точно определить точную ошибку, которую я здесь делаю, из-за которой служба не запускается. Если бы кто-нибудь мог помочь мне найти его или, возможно, порекомендовать более элегантный подход к синхронизации БД, я был бы очень благодарен. Заранее спасибо.
Комментарии:
1. Служба не будет работать в Android 8 и выше, вам необходимо использовать службу переднего плана.
2. Это правда. Я изменил свой приемник, чтобы проверить, должен ли он запускать foregroundservice или нет, но
onCreate
метод по-прежнему не вызывается3. Для запуска службы переднего плана необходимо отправить уведомление. developer.android.com/guide/components/foreground-services
Ответ №1:
В зависимости от производителя используемого телефона при таком подходе вы столкнетесь с различными проблемами. Смотрите https://dontkillmyapp.com /
Вы должны использовать WorkManager, чтобы уменьшить использование батареи и избежать необходимости вручную обрабатывать множество угловых случаев: https://developer.android.com/topic/libraries/architecture/workmanager/basics