Context.startForegroundService () затем не вызывал Service.startForeground () только на устройствах Android 11 Samsung.

Я получаю этот сбой только для устройств Samsung под управлением Android 11. Очевидно, приложение вызывает startForegroundService(intent) и требует, чтобы я отправил уведомление, чтобы пользователь знал, что я запускаю службу переднего плана, но этот вызов startForegroundService(intent) никогда не выполнялся в приложении исходный код, возможно ли, что Samsung произвела индивидуальную реализацию Android 11 и автоматически вызывает startForegroundService(intent) всякий раз, когда я вызываю startService(intent)?

Трассировки стека

Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{4ab4323 u0 {app package name}/{library package name}.player.PlayerService}
android.app.ActivityThread$H.handleMessage (ActivityThread.java:2240)
android.os.Handler.dispatchMessage (Handler.java:106)
android.os.Looper.loop (Looper.java:246)
android.app.ActivityThread.main (ActivityThread.java:8506)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:602)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1130)

Я запускаю службу с помощью context.startService(intent), и служба запускается в OnResume приложения, а контекст - это контекст приложения.

Также вот как сервис объявлен в манифесте

 <service
            android:name=".player.PlayerService"
            android:exported="false"
            android:foregroundServiceType="mediaPlayback"
            android:stopWithTask="false">
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_BUTTON" />
            </intent-filter>
  </service>

Обновление: я нашел причину, по которой выполняется вызов startForegroundService(Intent), я использую следующий приемник от Android, чтобы помочь обрабатывать устройства управления действиями, такие как кнопки наушников, поэтому, поскольку я преобразовал приложение в androidx, он начал использовать новый MediaButtonReceiver

 <receiver android:name="androidx.media.session.MediaButtonReceiver">
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_BUTTON" />
            </intent-filter>
 </receiver>

Это код, который выполняется, когда Получатель получает событие

@Override
    public void onReceive(Context context, Intent intent) {
        if (intent == null
                || !Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())
                || !intent.hasExtra(Intent.EXTRA_KEY_EVENT)) {
            Log.d(TAG, "Ignore unsupported intent: " + intent);
            return;
        }
        ComponentName mediaButtonServiceComponentName =
                getServiceComponentByAction(context, Intent.ACTION_MEDIA_BUTTON);
        if (mediaButtonServiceComponentName != null) {
            intent.setComponent(mediaButtonServiceComponentName);
            startForegroundService(context, intent);
            return;
        }
        ComponentName mediaBrowserServiceComponentName = getServiceComponentByAction(context,
                MediaBrowserServiceCompat.SERVICE_INTERFACE);
        if (mediaBrowserServiceComponentName != null) {
            PendingResult pendingResult = goAsync();
            Context applicationContext = context.getApplicationContext();
            MediaButtonConnectionCallback connectionCallback =
                    new MediaButtonConnectionCallback(applicationContext, intent, pendingResult);
            MediaBrowserCompat mediaBrowser = new MediaBrowserCompat(applicationContext,
                    mediaBrowserServiceComponentName, connectionCallback, null);
            connectionCallback.setMediaBrowser(mediaBrowser);
            mediaBrowser.connect();
            return;
        }
        throw new IllegalStateException("Could not find any Service that handles "
                + Intent.ACTION_MEDIA_BUTTON + " or implements a media browser service.");
    }

Вы можете видеть, что на самом деле он запускает службу переднего плана, я все еще изучаю сбой, но, по крайней мере, я знаю, что в приложении запущена служба переднего плана.

Кроме того, этот сбой происходит не только в Samsung, как я думал, сгруппированные отчеты о сбоях Samsung разбились вместе, потому что это сбой на платформе Android, другие экземпляры того же сбоя происходят реже, поэтому они были далеко внизу в списке сбоев на firebase.


person oziomajnr    schedule 02.03.2021    source источник
comment
Эй, я тоже столкнулся с той же проблемой. Вы уже нашли какое-нибудь решение?   -  person vishu srivastava    schedule 30.06.2021
comment
@vishusrivastava вы создаете приложение для медиаплеера?   -  person oziomajnr    schedule 30.06.2021
comment
да, в приложении есть функция подкастов.   -  person vishu srivastava    schedule 05.07.2021
comment
вам просто нужно убедиться, что ваше приложение отправляет уведомление при запуске службы переднего плана. Как указано в большинстве ответов.   -  person oziomajnr    schedule 05.07.2021
comment
Мой случай немного отличается, потому что я не запускал службу переднего плана в приложении, однако androidx.media.session.MediaButtonReceiver вызывает передний план, когда нажимается кнопка воспроизведения с наушников, и мое приложение было последним приложением, воспроизводившим звук.   -  person oziomajnr    schedule 05.07.2021


Ответы (2)


Обновлять

Возможная причина

После того, как вы предоставили дополнительный код, все еще неясно, вызываете ли вы startForeground() в своем PlayerService или нет. Похоже, что вы этого не делаете, и именно поэтому вы видите крушение. С другой стороны, если этот сбой происходит только на Android 11, у вас также может быть другая проблема.

Образец кода

Я только что сделал простое приложение для воспроизведения сбоя для PlayerService, если startForeground() не вызывается. Может быть, это будет вам полезно.

приложение / build.gradle

Добавить зависимость для использования androidx MediaButtonReceiver

...
implementation "androidx.media:media:1.2.1" 
...

AndroidManifest.xml

...
    <service
        android:name=".PlayerService"
        android:exported="false"
        android:foregroundServiceType="mediaPlayback"
        android:stopWithTask="false">
        <intent-filter>
            <action android:name="android.intent.action.MEDIA_BUTTON" />
        </intent-filter>
    </service>

    <receiver android:name="androidx.media.session.MediaButtonReceiver">
        <intent-filter>
            <action android:name="android.intent.action.MEDIA_BUTTON" />
        </intent-filter>
    </receiver>   
...

MainActivity.java

Эмулируйте событие медиа-кнопки, как показано ниже

...
@Override
protected void onResume() {
    super.onResume();

    Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
    intent.setClass(this, MediaButtonReceiver.class);
    intent.putExtra(Intent.EXTRA_KEY_EVENT, "test");
    sendBroadcast(intent);
}
... 

PlayerService.java

public class PlayerService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        MediaButtonReceiver.handleIntent(null, intent);

        return super.onStartCommand(intent, flags, startId);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

Исправить

Добавляя startForeground() к onCreate(), проблема решается. Обратите внимание, что я подготавливаю параметры и использую этот метод как только черновик. Подробную информацию см. В официальной документации здесь.

...
    @Override
    public void onCreate() {
        super.onCreate();

        Notification testNotification = new Notification();
        int testId = 1;
        startForeground(testId, testNotification);
    }
...
person Anatolii    schedule 24.03.2021

для некоторых служб переднего плана, которые должны выполнять работы, требующие доступа к location, microphone, mediaProjection, phoneCall, camera, dataSync, connectedDevice и mediaPlayback, вы должны указать "foregroundServiceType" в манифесте и установить ServiceInfo для службы при вызове startForeground в службе. Думаю, это решит вашу проблему.

Изменить

Вы должны запустить свой service в своем onStartCommand сервисе следующим образом:

if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q){
            startForeground(NOTIFICATION_ID, notification)
        }
        else{
            startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK)
        }

ты это делаешь?

person Mahdi Noori    schedule 02.03.2021