MediaSessionService: define foregroundServiceType
PiperOrigin-RevId: 447467287
This commit is contained in:
parent
54d8b5bc7c
commit
7a631f4050
@ -45,6 +45,7 @@
|
|||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".PlaybackService"
|
android:name=".PlaybackService"
|
||||||
|
android:foregroundServiceType="mediaPlayback"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="androidx.media3.session.MediaSessionService"/>
|
<action android:name="androidx.media3.session.MediaSessionService"/>
|
||||||
|
@ -19,13 +19,17 @@ import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
|||||||
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ServiceInfo;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import androidx.annotation.DoNotInline;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.core.app.NotificationManagerCompat;
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.media3.common.Player;
|
import androidx.media3.common.Player;
|
||||||
|
import androidx.media3.common.util.Log;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
@ -44,6 +48,8 @@ import java.util.concurrent.TimeoutException;
|
|||||||
*/
|
*/
|
||||||
/* package */ final class MediaNotificationManager {
|
/* package */ final class MediaNotificationManager {
|
||||||
|
|
||||||
|
private static final String TAG = "MediaNtfMng";
|
||||||
|
|
||||||
private final MediaSessionService mediaSessionService;
|
private final MediaSessionService mediaSessionService;
|
||||||
private final MediaNotification.Provider mediaNotificationProvider;
|
private final MediaNotification.Provider mediaNotificationProvider;
|
||||||
private final MediaNotification.ActionFactory actionFactory;
|
private final MediaNotification.ActionFactory actionFactory;
|
||||||
@ -170,8 +176,12 @@ import java.util.concurrent.TimeoutException;
|
|||||||
Player player = session.getPlayer();
|
Player player = session.getPlayer();
|
||||||
if (player.getPlayWhenReady() && canStartPlayback(player)) {
|
if (player.getPlayWhenReady() && canStartPlayback(player)) {
|
||||||
ContextCompat.startForegroundService(mediaSessionService, startSelfIntent);
|
ContextCompat.startForegroundService(mediaSessionService, startSelfIntent);
|
||||||
|
if (Util.SDK_INT >= 29) {
|
||||||
|
Api29.startForeground(mediaSessionService, mediaNotification);
|
||||||
|
} else {
|
||||||
mediaSessionService.startForeground(
|
mediaSessionService.startForeground(
|
||||||
mediaNotification.notificationId, mediaNotification.notification);
|
mediaNotification.notificationId, mediaNotification.notification);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
maybeStopForegroundService(/* removeNotifications= */ false);
|
maybeStopForegroundService(/* removeNotifications= */ false);
|
||||||
notificationManagerCompat.notify(
|
notificationManagerCompat.notify(
|
||||||
@ -251,4 +261,29 @@ import java.util.concurrent.TimeoutException;
|
|||||||
mediaSessionService.onUpdateNotification(session);
|
mediaSessionService.onUpdateNotification(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(29)
|
||||||
|
private static class Api29 {
|
||||||
|
|
||||||
|
@DoNotInline
|
||||||
|
public static void startForeground(
|
||||||
|
MediaSessionService mediaSessionService, MediaNotification mediaNotification) {
|
||||||
|
try {
|
||||||
|
// startForeground() will throw if the service's foregroundServiceType is not defined in the
|
||||||
|
// manifest to include mediaPlayback.
|
||||||
|
mediaSessionService.startForeground(
|
||||||
|
mediaNotification.notificationId,
|
||||||
|
mediaNotification.notification,
|
||||||
|
ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
Log.e(
|
||||||
|
TAG,
|
||||||
|
"The service must be declared with a foregroundServiceType that includes "
|
||||||
|
+ " mediaPlayback");
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Api29() {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
* <p>To extend this class, declare the intent filter in your {@code AndroidManifest.xml}:
|
* <p>To extend this class, declare the intent filter in your {@code AndroidManifest.xml}:
|
||||||
*
|
*
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* <service android:name="NameOfYourService">
|
* <service
|
||||||
|
* android:name="NameOfYourService"
|
||||||
|
* android:foregroundServiceType="mediaPlayback">
|
||||||
* <intent-filter>
|
* <intent-filter>
|
||||||
* <action android:name="androidx.media3.session.MediaSessionService"/>
|
* <action android:name="androidx.media3.session.MediaSessionService"/>
|
||||||
* </intent-filter>
|
* </intent-filter>
|
||||||
@ -85,9 +87,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
*
|
*
|
||||||
* <h2 id="ServiceLifecycle">Service Lifecycle</h2>
|
* <h2 id="ServiceLifecycle">Service Lifecycle</h2>
|
||||||
*
|
*
|
||||||
* <p>A media session service is a bound service. When a {@link MediaController} is created for the
|
* <p>A media session service is a bound service and its <a
|
||||||
* service, the controller binds to the service. {@link #onGetSession(ControllerInfo)} will be
|
* href="https://developer.android.com/guide/topics/manifest/service-element#foregroundservicetype">foreground
|
||||||
* called from {@link #onBind(Intent)}.
|
* service type</a> must include <em>mediaPlayback</em>. When a {@link MediaController} is created
|
||||||
|
* for the service, the controller binds to the service. {@link #onGetSession(ControllerInfo)} will
|
||||||
|
* be called from {@link #onBind(Intent)}.
|
||||||
*
|
*
|
||||||
* <p>After binding, the session's {@link MediaSession.SessionCallback#onConnect(MediaSession,
|
* <p>After binding, the session's {@link MediaSession.SessionCallback#onConnect(MediaSession,
|
||||||
* MediaSession.ControllerInfo)} will be called to accept or reject the connection request from the
|
* MediaSession.ControllerInfo)} will be called to accept or reject the connection request from the
|
||||||
|
@ -81,6 +81,7 @@
|
|||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service android:name="androidx.media3.session.MockMediaSessionService"
|
<service android:name="androidx.media3.session.MockMediaSessionService"
|
||||||
|
android:foregroundServiceType="mediaPlayback"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:process=":remote">
|
android:process=":remote">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -89,6 +90,7 @@
|
|||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service android:name="androidx.media3.session.LocalMockMediaSessionService"
|
<service android:name="androidx.media3.session.LocalMockMediaSessionService"
|
||||||
|
android:foregroundServiceType="mediaPlayback"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="androidx.media3.session.MediaSessionService" />
|
<action android:name="androidx.media3.session.MediaSessionService" />
|
||||||
@ -96,6 +98,7 @@
|
|||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service android:name="androidx.media3.session.MockMediaLibraryService"
|
<service android:name="androidx.media3.session.MockMediaLibraryService"
|
||||||
|
android:foregroundServiceType="mediaPlayback"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:process=":remote">
|
android:process=":remote">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user