Android PeriodicWorker не работает на Xiaomi?
Дано:
1. Обучающийся нуб в лице меня
2. Телефон Xiaomi Note 8 Pro c 9 android
3. Телефон Samsung Galaxy S6 c 7 android
Надо:
1. Заставить программу выполнять работу в фоне, при полностью закрытом состоянии, в том числе и после перезагрузки. Потом прога должна будет лазать в сеть за данными и проверять их на свежие данные, пока просто notification для теста.
Что делалось:
1. Для проверки работы в фоне вообще, выводятся Notification
2. Перелопачены кучи гайдов с разными подходами, переписывалось всё это не один раз и вечер.
3. Изначально были попытки сделать на IventService - не работало как надо. Посоветовали сделать на PeriodicWorker
4. На финальном этапе уже просто скопипастил код с очердного гайда - не работает.
5. Почесал репу и отрыл старую мобилу, попробовал на ней
Итого:
1. На старой мобиле код работает как от него хочется - прога закрыта, уведомления шлются каждые 15+ минут
2. На новой мобиле - уведомления шлются только когда прога запущена и на экране (телефон в режиме "не отключать экран"). Стоит приложуху просто свернуть, перейдя на главный экран мобилы - уведомления не шлются вообще. При закрытой проге аналогично.
Вопрос:
Вероятно, проблема именно в телефоне (или версии ОС?). Может кто сталкивался с таким? МОжет дело в именно "китайском" производителе? Это можно как-то обойти? Ведь на телефоне есть и другие программы и они в целом в закрытом состоянии порой шлют свои уведомления, значит как-то это реализуется и на таких аппаратах. Может надо вернуться к варианту с IntentService + foreground ?
Главная активи:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
// Тестим workmanager
val constraints =
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val workRequest =
PeriodicWorkRequest
.Builder(NewsUpdaterWorker::class.java, 15L, TimeUnit.MINUTES)
.setConstraints(constraints)
.build()
WorkManager.getInstance(this).enqueue(workRequest)
}
}
Класс worker
private const val TAG = "NewsUpdaterWorker"
class NewsUpdaterWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
companion object {
const val NOTIFICATION_ID = "notification_id"
const val NOTIFICATION_NAME = "new_news"
const val NOTIFICATION_CHANNEL = "new_news_channel"
}
override fun doWork(): Result {
return try {
val id = inputData.getLong(NOTIFICATION_ID, 0).toInt()
sendNotification(id)
Result.success()
} catch (error: Throwable) {
Log.d(TAG, "doWork notification fail")
Result.failure()
}
}
private fun sendNotification(id: Int) {
val intent = Intent(applicationContext, MainActivity::class.java)
intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK
intent.putExtra(NOTIFICATION_ID, id)
val notificationManager =
applicationContext.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val bitmap = applicationContext.vectorToBitmap(R.drawable.ic_schedule_black_24dp)
val titleNotification = applicationContext.getString(R.string.notification_new_comic_title)
val subtitleNotification = applicationContext.getString(R.string.notification_new_comic_subtitle)
val pendingIntent = getActivity(applicationContext, 0, intent, 0)
val notification = NotificationCompat.Builder(applicationContext, NOTIFICATION_CHANNEL)
.setLargeIcon(bitmap).setSmallIcon(R.drawable.ic_schedule_white)
.setContentTitle(titleNotification).setContentText(subtitleNotification)
.setDefaults(DEFAULT_ALL).setContentIntent(pendingIntent).setAutoCancel(true)
notification.priority = PRIORITY_MAX
if (SDK_INT >= O) {
notification.setChannelId(NOTIFICATION_CHANNEL)
val ringtoneManager = Uri.parse("android.resource://"
+ applicationContext.packageName + "/" + R.raw.notifsound)
val audioAttributes = AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE)
.setContentType(CONTENT_TYPE_SONIFICATION).build()
val channel =
NotificationChannel(NOTIFICATION_CHANNEL, NOTIFICATION_NAME, IMPORTANCE_HIGH)
channel.enableLights(true)
channel.lightColor = RED
channel.enableVibration(true)
channel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
channel.setSound(ringtoneManager, audioAttributes)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(id, notification.build())
Log.d(TAG, "Notification send")
}
fun Context.vectorToBitmap(drawableId: Int): Bitmap? {
val drawable = getDrawable(drawableId) ?: return null
val bitmap = createBitmap(
drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888
) ?: return null
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
return bitmap
}
}