Только для 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.

Есть несколько возможностей:

  1. Либо ваша служба переднего плана будет уничтожена/завершена перед вызовом метода startForeground().
  2. Или, если служба переднего плана уже создана и ее снова вызывают, то метод onCreate вызываться не будет, вместо этого будет вызываться onStartCommand. Затем переместите свою логику в onStartCommand, чтобы вызвать метод startForeground().
  3. Ваш идентификатор уведомления в 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