Поэтому, с Android О, вы должны иметь свой сервис работает как фоновый сервис, если вы хотите получать больше, чем просто несколько обновлений местоположения в час.
Я заметил, что старый способ запуска службы на переднем плане, кажется, для работы на о. т. е.
startForeground(NOTIFICATION_ID, getNotification());
По поведению изменений руководство ЗДЕСЬ: https://developer.android.com/preview/behavior-changes.html
и GT;диспетчер уведомлений.startServiceInForeground() метод запускает фоновый сервис. Старый способ запустить фоновый сервис больше не работает.
Однако новый метод работает только при ориентации О, кажется, что старый метод до сих пор, кажется, работает на устройстве О если таргетирования o или нет.
Редактировать В том числе, например:
Образец проекта Google LocationUpdatesForegroundService вообще-то есть рабочий пример, где можно увидеть выпуск первых рук. https://github.com/googlesamples/android-play-location/tree/master/LocationUpdatesForegroundService
В startForeground метод, кажется, работает без проблем ли ориентация и компиляции с использованием API уровня 25 или таргетинг и составления в отношении О. (Как указано здесь: https://developer.android.com/preview/migration.html#uya)
Так, чтобы воспроизвести.
Сервис работает на переднем плане (показан значок на панели уведомлений). Обновления приходят через, как ожидалось (каждые 10 секунд) даже на устройстве под управлением О., Что я здесь отсутствует?
Этот работал для меня.
- В классе Activity, службы начинают использовать startForegroundService() вместо startService()
Intent myService = new Intent(this, MyService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(myService);
} else {
startService(myService);
}
- Теперь в классе обслуживания в onStartCommand() выполните следующие действия
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
......
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Notification.Builder builder = new Notification.Builder(this, ANDROID_CHANNEL_ID)
.setContentTitle(getString(R.string.app_name))
.setContentText(text)
.setAutoCancel(true);
Notification notification = builder.build();
startForeground(1, notification);
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.app_name))
.setContentText(text)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true);
Notification notification = builder.build();
startForeground(1, notification);
}
return START_NOT_STICKY;
}
Примечание: используя уведомление.Строитель вместо NotificationCompat.Строитель заставили его работать. Только в уведомлении.Строителя вы должны указать идентификатор канала, который является новая функция в Android Орео.
Надеюсь, что это работает!
В деятельности (или любого контекста, что начинается служба на переднем плане), называют это:
в
Intent intent = new Intent(this, MyService.class)
ContextCompat.startForegroundService(context, intent);
в
Когда служба запущена, создайте уведомлений канал, используя подобный код, чтобы то, что Андроид врачи скажут, что, а затем создать построить и использовать его:
final Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID).setSmallIcon(...)//
.setPriority(...).setCategory(...).setContentTitle(...).setContentText(...).setTicker(...);
// and maybe other preparations to the notification...
startForeground(notificationId, builder.build());
Обычно вы начинаете свой сервис от радиовещательного приемника с помощью startService. Они говорят, что это's нет больше возможности (или надежный) называть
startService, потому что там сейчас фон ограничений, так что вы должны позвонить startServiceInForeground вместо. Однако из документов он's не совсем понятно, когда это происходит потому, что приложение в белый список, когда он получает широковещательный намерения, поэтому он's не ясно, когда именно startService "бросков" IllegalStateException
.
Устаревший способ запуска на переднем плане по-прежнему работает, когда приложение находится на переднем плане, однако рекомендуется начать переднего плана обслуживания для приложений, ориентированных на API уровня 26/Андроид благодаря недавно введенной диспетчер уведомлений#startServiceInForeground способ, чтобы создать план обслуживания в первую очередь.
Старый способ запуск сервиса в фоновом режиме, а затем продвигать его на передний план не будет работать, если приложение находится в фоновом режиме, потому что на фоне ограничения исполнении О. Андроид
Процесс миграции и шаги описаны здесь. https://developer.android.com/preview/features/background.html#migration
А также @Kislingk отметил в комментарии `диспетчер уведомлений.startServiceInForeground был удален. Он был помечен как устаревший ж/ к совершению 08992ac.
От коммита:
а не требуется априорная уведомление будет поставляться в целях запустить службу непосредственно в государственный план, мы принимаем двухступенчатый соединение работы для проведения текущего обслуживания работать даже с фоновое состояние выполнения. Контекст#startForegroundService() не тема на фоне ограничений, с требованием, что услуги официально войти в состояние изображения с помощью startForeground() в 5 секунд. Если сервис не сделает так, она остановила ОС и приложение обвиняют в службе НРУ.
Я добавить образец если некоторым нужно с застройщика backstack
val notifyManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val playIntent = Intent(this, this::class.java).setAction(PAUSE)
val cancelIntent = Intent(this, this::class.java).setAction(EXIT)
val stop = PendingIntent.getService(this, 1, playIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val exit = PendingIntent.getService(this, 2, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notifyManager.createNotificationChannel(NotificationChannel(NOTIFICATION_ID_CHANNEL_ID, getString(R.string.app_name), NotificationManager.IMPORTANCE_HIGH))
NotificationCompat.Builder(this, NOTIFICATION_ID_CHANNEL_ID)
} else
NotificationCompat.Builder(this)
builder.apply {
setContentTitle(station.name)
setContentText(metaToText(meta) )
setSmallIcon(R.drawable.ic_play_arrow_white_24px)
setAutoCancel(false)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) priority = Notification.PRIORITY_MAX
addAction(R.drawable.ic_stop_white_24px, getString(R.string.player_notification_stop), stop)
addAction(R.drawable.ic_close_white_24px, getString(R.string.player_notification_exit), exit)
}
val stackBuilder = TaskStackBuilder.create(this)
stackBuilder.addParentStack(PlayerActivity::class.java)
stackBuilder.addNextIntent(Intent(this, PlayerActivity::class.java))
builder.setContentIntent(stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT))
startForeground(NOTIFICATION_ID, builder.build())
startForeground(1, уведомление); будет работать на Android O, но согласно требованию к Андроид мы должны показать уведомление пользователю. В то же время это может запутать пользователя в некоторых случаях (система оповещения о Приложение работает в фоновом режиме и влияет батареи) и таким образом, пользователь может удалить приложение. Так что лучше будет использовать вновь ввести класс workmanager для планирования задач в качестве фона.
Фрагмент кода:
OneTimeWorkRequest work =
new OneTimeWorkRequest.Builder(MyWorker.class)
.build();
WorkManager.getInstance().enqueue(work);