Skip to content

Commit

Permalink
Hacky attempt at android 13 notification action buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
nico-abram committed Nov 4, 2023
1 parent 6d69451 commit 7074d8a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public class MediaSessionPlayerUi extends PlayerUi
private static final String TAG = "MediaSessUi";

private MediaSessionCompat mediaSession;
private MediaSessionConnector sessionConnector;
// Changing the visibility here is likely suspect/hacky?
public MediaSessionConnector sessionConnector;

private final String ignoreHardwareMediaButtonsKey;
private boolean shouldIgnoreHardwareMediaButtons = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.schabi.newpipe.player.mediasession;

import static android.support.v4.media.session.PlaybackStateCompat.ACTION_SKIP_TO_NEXT;
import static android.support.v4.media.session.PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS;
import static android.support.v4.media.session.PlaybackStateCompat.ACTION_SKIP_TO_QUEUE_ITEM;

import android.net.Uri;
Expand Down Expand Up @@ -46,7 +44,7 @@ public PlayQueueNavigator(@NonNull final MediaSessionCompat mediaSession,
@Override
public long getSupportedQueueNavigatorActions(
@Nullable final com.google.android.exoplayer2.Player exoPlayer) {
return ACTION_SKIP_TO_NEXT | ACTION_SKIP_TO_PREVIOUS | ACTION_SKIP_TO_QUEUE_ITEM;
return ACTION_SKIP_TO_QUEUE_ITEM;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.schabi.newpipe.player.notification;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.media.session.PlaybackStateCompat;
import android.util.Log;

import androidx.annotation.DrawableRes;
Expand Down Expand Up @@ -40,6 +43,8 @@
import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_REPEAT;
import static org.schabi.newpipe.player.notification.NotificationConstants.ACTION_SHUFFLE;

import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;

/**
* This is a utility class for player notifications.
*/
Expand Down Expand Up @@ -220,16 +225,60 @@ private void initializeNotificationSlots() {
@SuppressLint("RestrictedApi")
private void updateActions(final NotificationCompat.Builder builder) {
builder.mActions.clear();
final var customActionProviders =
new java.util.ArrayList<MediaSessionConnector.CustomActionProvider>();
for (int i = 0; i < 5; ++i) {
addAction(builder, notificationSlots[i]);
addAction(builder, notificationSlots[i], customActionProviders);
}
player.UIs()
.get(MediaSessionPlayerUi.class)
.ifPresent(mediaSessionPlayerUi -> {
mediaSessionPlayerUi.sessionConnector.setCustomActionProviders(
customActionProviders.toArray(
new MediaSessionConnector.CustomActionProvider[0]));
});
}
// Hacky way to return a second value from getAction
// (Couldn't figure out a simple way to get a String out-param or return a tuple)
String lastIntentAction;

private static class CustomAction implements MediaSessionConnector.CustomActionProvider {
private final String action;
private final CharSequence name;
private final int icon;
private final Context context;
CustomAction(final String action2, final CharSequence name2,
final int icon2, final Context context2) {
this.action = action2;
this.name = name2;
this.icon = icon2;
this.context = context2;
}
@Override
public void onCustomAction(final com.google.android.exoplayer2.Player player,
final String action2, @Nullable final Bundle extras) {
context.sendBroadcast(new Intent(action));
}

@Nullable
@Override
public PlaybackStateCompat.CustomAction
getCustomAction(final com.google.android.exoplayer2.Player player) {
return new PlaybackStateCompat.CustomAction.Builder(action, name, icon).build();
}
}
private void addAction(final NotificationCompat.Builder builder,
@NotificationConstants.Action final int slot) {
@NotificationConstants.Action final int slot,
final List<MediaSessionConnector.CustomActionProvider> actions) {
final NotificationCompat.Action action = getAction(slot);

if (action != null) {
builder.addAction(action);
if (lastIntentAction != null && lastIntentAction != ACTION_PLAY_PAUSE) {
actions.add(new CustomAction(lastIntentAction,
action.getTitle().toString(),
action.getIcon(), player.getContext()));
}
}
}

Expand Down Expand Up @@ -277,6 +326,7 @@ private NotificationCompat.Action getAction(
|| player.getCurrentState() == Player.STATE_BLOCKED
|| player.getCurrentState() == Player.STATE_BUFFERING) {
// null intent -> show hourglass icon that does nothing when clicked
lastIntentAction = null;
return new NotificationCompat.Action(R.drawable.ic_hourglass_top,
player.getContext().getString(R.string.notification_action_buffering),
null);
Expand Down Expand Up @@ -333,6 +383,7 @@ private NotificationCompat.Action getAction(
private NotificationCompat.Action getAction(@DrawableRes final int drawable,
@StringRes final int title,
final String intentAction) {
this.lastIntentAction = intentAction;
return new NotificationCompat.Action(drawable, player.getContext().getString(title),
PendingIntentCompat.getBroadcast(player.getContext(), NOTIFICATION_ID,
new Intent(intentAction), FLAG_UPDATE_CURRENT, false));
Expand Down

0 comments on commit 7074d8a

Please sign in to comment.