use of androidx.media.app.NotificationCompat.MediaStyle in project kdeconnect-android by KDE.
the class MprisMediaSession method updateMediaNotification.
/**
* Update the media control notification
*/
private void updateMediaNotification() {
BackgroundService.RunCommand(context, service -> {
// If the user disabled the media notification, do not show it
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
if (!prefs.getBoolean(context.getString(R.string.mpris_notification_key), true)) {
closeMediaNotification();
return;
}
// Make sure our information is up-to-date
updateCurrentPlayer(service);
// If the player disappeared (and no other playing one found), just remove the notification
if (notificationPlayer == null) {
closeMediaNotification();
return;
}
// Update the metadata and playback status
if (mediaSession == null) {
mediaSession = new MediaSessionCompat(context, MPRIS_MEDIA_SESSION_TAG);
mediaSession.setCallback(mediaSessionCallback);
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
}
MediaMetadataCompat.Builder metadata = new MediaMetadataCompat.Builder();
// Fallback because older KDE connect versions do not support getTitle()
if (!notificationPlayer.getTitle().isEmpty()) {
metadata.putString(MediaMetadataCompat.METADATA_KEY_TITLE, notificationPlayer.getTitle());
} else {
metadata.putString(MediaMetadataCompat.METADATA_KEY_TITLE, notificationPlayer.getCurrentSong());
}
if (!notificationPlayer.getArtist().isEmpty()) {
metadata.putString(MediaMetadataCompat.METADATA_KEY_AUTHOR, notificationPlayer.getArtist());
metadata.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, notificationPlayer.getArtist());
}
if (!notificationPlayer.getAlbum().isEmpty()) {
metadata.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, notificationPlayer.getAlbum());
}
if (notificationPlayer.getLength() > 0) {
metadata.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, notificationPlayer.getLength());
}
Bitmap albumArt = notificationPlayer.getAlbumArt();
if (albumArt != null) {
metadata.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt);
}
mediaSession.setMetadata(metadata.build());
PlaybackStateCompat.Builder playbackState = new PlaybackStateCompat.Builder();
if (notificationPlayer.isPlaying()) {
playbackState.setState(PlaybackStateCompat.STATE_PLAYING, notificationPlayer.getPosition(), 1.0f);
} else {
playbackState.setState(PlaybackStateCompat.STATE_PAUSED, notificationPlayer.getPosition(), 0.0f);
}
// Create all actions (previous/play/pause/next)
Intent iPlay = new Intent(service, MprisMediaNotificationReceiver.class);
iPlay.setAction(MprisMediaNotificationReceiver.ACTION_PLAY);
iPlay.putExtra(MprisMediaNotificationReceiver.EXTRA_DEVICE_ID, notificationDevice);
iPlay.putExtra(MprisMediaNotificationReceiver.EXTRA_MPRIS_PLAYER, notificationPlayer.getPlayer());
PendingIntent piPlay = PendingIntent.getBroadcast(service, 0, iPlay, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action.Builder aPlay = new NotificationCompat.Action.Builder(R.drawable.ic_play_white, service.getString(R.string.mpris_play), piPlay);
Intent iPause = new Intent(service, MprisMediaNotificationReceiver.class);
iPause.setAction(MprisMediaNotificationReceiver.ACTION_PAUSE);
iPause.putExtra(MprisMediaNotificationReceiver.EXTRA_DEVICE_ID, notificationDevice);
iPause.putExtra(MprisMediaNotificationReceiver.EXTRA_MPRIS_PLAYER, notificationPlayer.getPlayer());
PendingIntent piPause = PendingIntent.getBroadcast(service, 0, iPause, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action.Builder aPause = new NotificationCompat.Action.Builder(R.drawable.ic_pause_white, service.getString(R.string.mpris_pause), piPause);
Intent iPrevious = new Intent(service, MprisMediaNotificationReceiver.class);
iPrevious.setAction(MprisMediaNotificationReceiver.ACTION_PREVIOUS);
iPrevious.putExtra(MprisMediaNotificationReceiver.EXTRA_DEVICE_ID, notificationDevice);
iPrevious.putExtra(MprisMediaNotificationReceiver.EXTRA_MPRIS_PLAYER, notificationPlayer.getPlayer());
PendingIntent piPrevious = PendingIntent.getBroadcast(service, 0, iPrevious, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action.Builder aPrevious = new NotificationCompat.Action.Builder(R.drawable.ic_previous_white, service.getString(R.string.mpris_previous), piPrevious);
Intent iNext = new Intent(service, MprisMediaNotificationReceiver.class);
iNext.setAction(MprisMediaNotificationReceiver.ACTION_NEXT);
iNext.putExtra(MprisMediaNotificationReceiver.EXTRA_DEVICE_ID, notificationDevice);
iNext.putExtra(MprisMediaNotificationReceiver.EXTRA_MPRIS_PLAYER, notificationPlayer.getPlayer());
PendingIntent piNext = PendingIntent.getBroadcast(service, 0, iNext, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action.Builder aNext = new NotificationCompat.Action.Builder(R.drawable.ic_next_white, service.getString(R.string.mpris_next), piNext);
Intent iOpenActivity = new Intent(service, MprisActivity.class);
iOpenActivity.putExtra("deviceId", notificationDevice);
iOpenActivity.putExtra("player", notificationPlayer.getPlayer());
/*
TODO: Remove when Min SDK >= 16
The only way the intent extra's are delivered on API 14 and 15 is by either using a different requestCode every time
or using PendingIntent.FLAG_CANCEL_CURRENT instead of PendingIntent.FLAG_UPDATE_CURRENT
*/
PendingIntent piOpenActivity = TaskStackBuilder.create(context).addNextIntentWithParentStack(iOpenActivity).getPendingIntent(Build.VERSION.SDK_INT > 15 ? 0 : (int) System.currentTimeMillis(), PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notification = new NotificationCompat.Builder(context, NotificationHelper.Channels.MEDIA_CONTROL);
notification.setAutoCancel(false).setContentIntent(piOpenActivity).setSmallIcon(R.drawable.ic_play_white).setShowWhen(false).setColor(ContextCompat.getColor(service, R.color.primary)).setVisibility(androidx.core.app.NotificationCompat.VISIBILITY_PUBLIC).setSubText(service.getDevice(notificationDevice).getName());
if (!notificationPlayer.getTitle().isEmpty()) {
notification.setContentTitle(notificationPlayer.getTitle());
} else {
notification.setContentTitle(notificationPlayer.getCurrentSong());
}
// Only set the notification body text if we have an author and/or album
if (!notificationPlayer.getArtist().isEmpty() && !notificationPlayer.getAlbum().isEmpty()) {
notification.setContentText(notificationPlayer.getArtist() + " - " + notificationPlayer.getAlbum() + " (" + notificationPlayer.getPlayer() + ")");
} else if (!notificationPlayer.getArtist().isEmpty()) {
notification.setContentText(notificationPlayer.getArtist() + " (" + notificationPlayer.getPlayer() + ")");
} else if (!notificationPlayer.getAlbum().isEmpty()) {
notification.setContentText(notificationPlayer.getAlbum() + " (" + notificationPlayer.getPlayer() + ")");
} else {
notification.setContentText(notificationPlayer.getPlayer());
}
if (albumArt != null) {
notification.setLargeIcon(albumArt);
}
if (!notificationPlayer.isPlaying()) {
Intent iCloseNotification = new Intent(service, MprisMediaNotificationReceiver.class);
iCloseNotification.setAction(MprisMediaNotificationReceiver.ACTION_CLOSE_NOTIFICATION);
iCloseNotification.putExtra(MprisMediaNotificationReceiver.EXTRA_DEVICE_ID, notificationDevice);
iCloseNotification.putExtra(MprisMediaNotificationReceiver.EXTRA_MPRIS_PLAYER, notificationPlayer.getPlayer());
PendingIntent piCloseNotification = PendingIntent.getBroadcast(service, 0, iCloseNotification, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setDeleteIntent(piCloseNotification);
}
// Add media control actions
int numActions = 0;
long playbackActions = 0;
if (notificationPlayer.isGoPreviousAllowed()) {
notification.addAction(aPrevious.build());
playbackActions |= PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS;
++numActions;
}
if (notificationPlayer.isPlaying() && notificationPlayer.isPauseAllowed()) {
notification.addAction(aPause.build());
playbackActions |= PlaybackStateCompat.ACTION_PAUSE;
++numActions;
}
if (!notificationPlayer.isPlaying() && notificationPlayer.isPlayAllowed()) {
notification.addAction(aPlay.build());
playbackActions |= PlaybackStateCompat.ACTION_PLAY;
++numActions;
}
if (notificationPlayer.isGoNextAllowed()) {
notification.addAction(aNext.build());
playbackActions |= PlaybackStateCompat.ACTION_SKIP_TO_NEXT;
++numActions;
}
// Documentation says that this was added in Lollipop (21) but it seems to cause crashes on < Pie (28)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (notificationPlayer.isSeekAllowed()) {
playbackActions |= PlaybackStateCompat.ACTION_SEEK_TO;
}
}
playbackState.setActions(playbackActions);
mediaSession.setPlaybackState(playbackState.build());
// Only allow deletion if no music is notificationPlayer
notification.setOngoing(notificationPlayer.isPlaying());
// Use the MediaStyle notification, so it feels like other media players. That also allows adding actions
MediaStyle mediaStyle = new MediaStyle();
if (numActions == 1) {
mediaStyle.setShowActionsInCompactView(0);
} else if (numActions == 2) {
mediaStyle.setShowActionsInCompactView(0, 1);
} else if (numActions >= 3) {
mediaStyle.setShowActionsInCompactView(0, 1, 2);
}
mediaStyle.setMediaSession(mediaSession.getSessionToken());
notification.setStyle(mediaStyle);
notification.setGroup("MprisMediaSession");
// Display the notification
mediaSession.setActive(true);
final NotificationManager nm = ContextCompat.getSystemService(context, NotificationManager.class);
nm.notify(MPRIS_MEDIA_NOTIFICATION_ID, notification.build());
});
}
use of androidx.media.app.NotificationCompat.MediaStyle in project zype-android by zype.
the class PlayerFragment method showNotification.
public void showNotification(boolean isLive, int mediaType) {
Logger.d("showNotification()");
if (player == null || TextUtils.isEmpty(fileId)) {
return;
}
VideoData video = VideoHelper.getVideo(getActivity().getContentResolver(), fileId);
String title = "";
if (video != null) {
title = video.getTitle();
} else {
title = "Live";
}
Intent notificationIntent;
Bundle bundle = new Bundle();
bundle.putInt(BundleConstants.MEDIA_TYPE, mediaType);
bundle.putString(BundleConstants.VIDEO_ID, fileId);
if (isLive) {
notificationIntent = new Intent(getActivity(), LivePlayerActivity.class);
title = "Live";
} else {
notificationIntent = new Intent(getActivity(), VideoDetailActivity.class);
}
notificationIntent.putExtras(bundle);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
PendingIntent intent = PendingIntent.getActivity(getActivity(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(getActivity(), ZypeApp.NOTIFICATION_CHANNEL_ID);
builder.setContentIntent(intent).setContentTitle(getActivity().getString(R.string.app_name)).setContentText(title).setSmallIcon(R.drawable.ic_background_playback).setPriority(NotificationCompat.PRIORITY_MAX).setAutoCancel(true).setOngoing(true).setWhen(0);
// builder.addAction(R.drawable.ic_stop_black_24px, "Stop", pendingIntentStop);
if (player != null) {
if (player.getPlayerControl().isPlaying()) {
builder.addAction(new NotificationCompat.Action(R.drawable.ic_pause_black_24dp, "Pause", MediaButtonReceiver.buildMediaButtonPendingIntent(getActivity(), PlaybackStateCompat.ACTION_PLAY_PAUSE)));
} else {
builder.addAction(new NotificationCompat.Action(R.drawable.ic_play_arrow_black_24dp, "Play", MediaButtonReceiver.buildMediaButtonPendingIntent(getActivity(), PlaybackStateCompat.ACTION_PLAY_PAUSE)));
}
}
builder.setStyle(new MediaStyle().setMediaSession(mediaSession.getSessionToken()).setShowCancelButton(true).setCancelButtonIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(getActivity(), PlaybackStateCompat.ACTION_STOP)));
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getActivity());
notificationManager.notify(ZypeApp.NOTIFICATION_ID, builder.build());
}
use of androidx.media.app.NotificationCompat.MediaStyle in project Phonograph by kabouzeid.
the class PlayingNotificationImpl24 method update.
@Override
public synchronized void update() {
stopped = false;
final Song song = service.getCurrentSong();
final boolean isPlaying = service.isPlaying();
final int playButtonResId = isPlaying ? R.drawable.ic_pause_white_24dp : R.drawable.ic_play_arrow_white_24dp;
Intent action = new Intent(service, MainActivity.class);
action.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
final PendingIntent clickIntent = PendingIntent.getActivity(service, 0, action, 0);
final ComponentName serviceName = new ComponentName(service, MusicService.class);
Intent intent = new Intent(MusicService.ACTION_QUIT);
intent.setComponent(serviceName);
final PendingIntent deleteIntent = PendingIntent.getService(service, 0, intent, 0);
final int bigNotificationImageSize = service.getResources().getDimensionPixelSize(R.dimen.notification_big_image_size);
service.runOnUiThread(() -> SongGlideRequest.Builder.from(Glide.with(service), song).checkIgnoreMediaStore(service).generatePalette(service).build().into(new SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, bigNotificationImageSize) {
@Override
public void onResourceReady(BitmapPaletteWrapper resource, GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
Palette palette = resource.getPalette();
update(resource.getBitmap(), palette.getVibrantColor(palette.getMutedColor(Color.TRANSPARENT)));
}
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
update(null, Color.TRANSPARENT);
}
void update(Bitmap bitmap, int color) {
if (bitmap == null)
bitmap = BitmapFactory.decodeResource(service.getResources(), R.drawable.default_album_art);
NotificationCompat.Action playPauseAction = new NotificationCompat.Action(playButtonResId, service.getString(R.string.action_play_pause), retrievePlaybackAction(ACTION_TOGGLE_PAUSE));
NotificationCompat.Action previousAction = new NotificationCompat.Action(R.drawable.ic_skip_previous_white_24dp, service.getString(R.string.action_previous), retrievePlaybackAction(ACTION_REWIND));
NotificationCompat.Action nextAction = new NotificationCompat.Action(R.drawable.ic_skip_next_white_24dp, service.getString(R.string.action_next), retrievePlaybackAction(ACTION_SKIP));
NotificationCompat.Builder builder = new NotificationCompat.Builder(service, NOTIFICATION_CHANNEL_ID).setSmallIcon(R.drawable.ic_notification).setSubText(song.albumName).setLargeIcon(bitmap).setContentIntent(clickIntent).setDeleteIntent(deleteIntent).setContentTitle(song.title).setContentText(song.artistName).setOngoing(isPlaying).setShowWhen(false).addAction(previousAction).addAction(playPauseAction).addAction(nextAction);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setStyle(new MediaStyle().setMediaSession(service.getMediaSession().getSessionToken()).setShowActionsInCompactView(0, 1, 2)).setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O && PreferenceUtil.getInstance(service).coloredNotification())
builder.setColor(color);
}
if (stopped)
// notification has been stopped before loading was finished
return;
updateNotifyModeAndPostNotification(builder.build());
}
}));
}
use of androidx.media.app.NotificationCompat.MediaStyle in project ExoPlayer by google.
the class PlayerNotificationManager method createNotification.
/**
* Creates the notification given the current player state.
*
* @param player The player for which state to build a notification.
* @param builder The builder used to build the last notification, or {@code null}. Re-using the
* builder when possible can prevent notification flicker when {@code Util#SDK_INT} < 21.
* @param ongoing Whether the notification should be ongoing.
* @param largeIcon The large icon to be used.
* @return The {@link NotificationCompat.Builder} on which to call {@link
* NotificationCompat.Builder#build()} to obtain the notification, or {@code null} if no
* notification should be displayed.
*/
@Nullable
protected NotificationCompat.Builder createNotification(Player player, @Nullable NotificationCompat.Builder builder, boolean ongoing, @Nullable Bitmap largeIcon) {
if (player.getPlaybackState() == Player.STATE_IDLE && player.getCurrentTimeline().isEmpty()) {
builderActions = null;
return null;
}
List<String> actionNames = getActions(player);
List<NotificationCompat.Action> actions = new ArrayList<>(actionNames.size());
for (int i = 0; i < actionNames.size(); i++) {
String actionName = actionNames.get(i);
@Nullable NotificationCompat.Action action = playbackActions.containsKey(actionName) ? playbackActions.get(actionName) : customActions.get(actionName);
if (action != null) {
actions.add(action);
}
}
if (builder == null || !actions.equals(builderActions)) {
builder = new NotificationCompat.Builder(context, channelId);
builderActions = actions;
for (int i = 0; i < actions.size(); i++) {
builder.addAction(actions.get(i));
}
}
MediaStyle mediaStyle = new MediaStyle();
if (mediaSessionToken != null) {
mediaStyle.setMediaSession(mediaSessionToken);
}
mediaStyle.setShowActionsInCompactView(getActionIndicesForCompactView(actionNames, player));
// Configure dismiss action prior to API 21 ('x' button).
mediaStyle.setShowCancelButton(!ongoing);
mediaStyle.setCancelButtonIntent(dismissPendingIntent);
builder.setStyle(mediaStyle);
// Set intent which is sent if the user selects 'clear all'
builder.setDeleteIntent(dismissPendingIntent);
// Set notification properties from getters.
builder.setBadgeIconType(badgeIconType).setOngoing(ongoing).setColor(color).setColorized(colorized).setSmallIcon(smallIconResourceId).setVisibility(visibility).setPriority(priority).setDefaults(defaults);
// Changing "showWhen" causes notification flicker if SDK_INT < 21.
if (Util.SDK_INT >= 21 && useChronometer && player.isPlaying() && !player.isPlayingAd() && !player.isCurrentMediaItemDynamic() && player.getPlaybackParameters().speed == 1f) {
builder.setWhen(System.currentTimeMillis() - player.getContentPosition()).setShowWhen(true).setUsesChronometer(true);
} else {
builder.setShowWhen(false).setUsesChronometer(false);
}
// Set media specific notification properties from MediaDescriptionAdapter.
builder.setContentTitle(mediaDescriptionAdapter.getCurrentContentTitle(player));
builder.setContentText(mediaDescriptionAdapter.getCurrentContentText(player));
builder.setSubText(mediaDescriptionAdapter.getCurrentSubText(player));
if (largeIcon == null) {
largeIcon = mediaDescriptionAdapter.getCurrentLargeIcon(player, new BitmapCallback(++currentNotificationTag));
}
setLargeIcon(builder, largeIcon);
builder.setContentIntent(mediaDescriptionAdapter.createCurrentContentIntent(player));
if (groupKey != null) {
builder.setGroup(groupKey);
}
builder.setOnlyAlertOnce(true);
return builder;
}
Aggregations