Только для Android 9 (круговая диаграмма): Context.startForegroundService() не вызывал Service.startForeground() - отлично работает на Oreo
Мы настроили наше текущее уведомление для Oreo, и оно работало отлично. Теперь, только на Pie (не происходит на устройствах Oreo), мы получаем заголовочную ошибку. Что-то изменилось в сервисах переднего плана в Pie, которые мне не хватает?
Здесь код onCreate для службы переднего плана ->
override fun onCreate() {
super.onCreate()
val notification: Notification = NotificationCompat.Builder(this, packageName)
.setSmallIcon(R.drawable.status_notification_icon)
.setContentTitle(getString(R.string.ongoing_notify_temp_title))
.setContentText(getString(R.string.ongoing_notify_temp_message))
.setGroup(AppConstants.NOTIFICATION_GROUP_ONGOING)
.setColor(ContextCompat.getColor(this, R.color.custom_blue))
.build()
startForeground(ONGOING_NOTIFY_ID, notification)
appSettings = AppSettings(this)
weatherLookUpHelper = WeatherLookUpHelper()
MyRoomDatabase.getInstance().invalidationTracker.addObserver(onChange)
retrieveCurrentLocation()
createAlarmManager()
}
как видите, мы просто создаем уведомление и затем вызываем startForeground. Любые идеи о том, почему этот код приведет к ошибке с названием?
Примечание стороны: Fabric Crashlytics показывает, что этот сбой происходит только на устройствах Pixel (пиксель, пиксель xl, пиксель 2, пиксель 2 xl) с Pie
РЕДАКТИРОВАТЬ: у нас есть разрешение переднего плана в нашем манифесте
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Ответы
Ответ 1
Как упоминалось здесь Фоновые ограничения службы, у приложения/службы есть пять секунд для вызова startForeground()
. Если приложение не вызывает startForeground() в течение определенного времени, система останавливает службу и объявляет приложение быть ANR.
Есть несколько возможностей:
- Либо ваша служба переднего плана будет уничтожена/завершена перед вызовом метода
startForeground()
.
- Или, если служба переднего плана уже создана и ее снова вызывают, то метод
onCreate
вызываться не будет, вместо этого будет вызываться onStartCommand
. Затем переместите свою логику в onStartCommand
, чтобы вызвать метод startForeground()
.
- Ваш идентификатор уведомления в
startForeground
не должен быть 0, в противном случае это также приведет к сбою.
Ответ 2
Что-то изменилось в сервисах переднего плана в Pie, которые мне не хватает?
ДА Посмотрите здесь заметки о миграции Android 9/Pie
+ Изменить
Разрешение на обслуживание переднего плана
Резюме
Приложения, желающие использовать службы переднего плана, теперь должны сначала запросить разрешение FOREGROUND_SERVICE. Это нормальное разрешение, поэтому система автоматически предоставляет его запрашивающему приложению. Запуск службы переднего плана без разрешения вызывает исключение SecurityException.
ОБНОВИТЬ
связанная с этим проблема в Google Issue Tracker Context.startForegroundService() не вызывала Service.startForeground
Ответ 3
Это проблема самой платформы Android. Многие разработчики подали ошибку для того же, но Google не склонен исправлять это поведение. В моем случае ошибка, помеченная мной, была помечена как "не будет устранена", и люди из Google несколько раз пытались ответить на вопрос, существует ли эта проблема.
Единственный способ обойти это сейчас - вообще не использовать Context.startForegroundService(). Вы можете использовать Context.startService(), когда у вас есть приоритет переднего плана. Но помните, что это нельзя использовать, если ваше приложение работает в фоновом режиме.
Использование Context.startService(), а затем продвижение службы на передний план работает, как и ожидалось.
Чтобы узнать, как я развернул этот обходной путь, вот блог, который я написал со всеми деталями. Ссылка на блог здесь с обещанием, что ссылка не будет мертвой до бесконечности :)
https://www.theandroiddeveloper.com/blog/context-startforegroundservice-did-not-then-call-service-startforeground