-
Notifications
You must be signed in to change notification settings - Fork 630
Description
Hello, I have reviewed all the old requests about the implementation of the notification in API 33. I have been trying to implement it in mine but it always appears by default, it does not modify it. I have been using codes from other requests from other colleagues and nothing, the button does not appear. I have looked at the guides on the Android developer website and the information is very scarce and they do it in dribs and drabs, they do not accompany it with codes and I think it lacks a better detailed explanation of how to make notifications work in API 33. This is my code that I use in my app and it works perfectly in the api less than 33 and from there it creates the default notification but I have used both codes from other guides such as those mentioned in #38, #200, #11027, #216 and many but but I can't find my mistake. I need help!!!!
public class PlayerService extends MediaSessionService {
public static NotificationManager notificationManager;
public static ExoPlayer player;
private final IBinder serviceBinder = new ServiceBinder();
public static String ACCION_REPRODUCIR = "Reproducir/Pause";
public static String ACCION_NEXT = "Next";
public static String ACCION_PREVIOUS = "Previous";
public static String ACCION_SHUFFLE = "Shuffle";
public static String ACCION_CLOSE = "Close";
public static boolean isPlayOn = false; // Inicialmente, el botón es visible
private boolean isShuffleOn = false; // Inicialmente, el botón es visible
private static NotificationCompat.Builder notificationBuilder;
MediaSession mediaSession = null;
private static final SessionCommand CUSTOM_COMMAND_FAVORITES =
new SessionCommand("ACTION_FAVORITES", new Bundle());
CommandButton favoriteButton;
public class ServiceBinder extends Binder {
public PlayerService getPlayerService() {
return PlayerService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
super.onBind(intent);
return serviceBinder;
}
@Override
public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
return mediaSession;
}
@OptIn(markerClass = UnstableApi.class) public void onCreate() {
super.onCreate();
player = new ExoPlayer.Builder(getApplicationContext()).build();
player.setAudioAttributes(new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).setContentType(C.AUDIO_CONTENT_TYPE_MUSIC).build(), true);
favoriteButton = new CommandButton.Builder()
.setDisplayName("Save to favorites")
.setIconResId(R.drawable.baseline_shuffle)
.setSessionCommand(CUSTOM_COMMAND_FAVORITES)
.build();
mediaSession = new MediaSession.Builder(this, player)
.setCallback(new MyCallback())
.setCustomLayout(ImmutableList.of(favoriteButton))
.build();
player.addListener(new Player.Listener() {
@Override
public void onPlaybackStateChanged(int playbackState) {
Player.Listener.super.onPlaybackStateChanged(playbackState);
switch (playbackState) {
case Player.STATE_ENDED:
// La reproducción ha terminado
// Puedes realizar acciones cuando se completa la reproducción de audio
Log.i("JsonData", "La reproducción ha terminado service");
player.seekTo(0, 0);
break;
case Player.STATE_READY:
// El reproductor está listo para reproducir
Log.i("JsonData", "El reproductor está listo para reproducir service");
showNotification(Objects.requireNonNull(Objects.requireNonNull(player.getCurrentMediaItem()).mediaMetadata.title).toString());
player.play();
isPlayOn = false;
break;
case Player.STATE_BUFFERING:
// El reproductor está almacenando en búfer datos multimedia
Log.i("JsonData", "El reproductor está almacenando en búfer datos multimedia service");
break;
case Player.STATE_IDLE:
// El reproductor no tiene ningún medio que reproducir
Log.i("JsonData", "El reproductor no tiene ningún medio que reproducir service");
if (player != null && player.getMediaItemCount() > 0) {
// Asegúrate de que haya al menos un medio en la lista de reproducción
MediaItem mediaItem = player.getMediaItemAt(player.getCurrentMediaItemIndex());
if (mediaItem != null) {
// Accede a la URL del medio
String mediaUrl = mediaItem.localConfiguration.uri.toString();
webView.loadUrl("https://mp3api.ytjar.info/?id=" + mediaUrl);
// Ahora tienes la URL del medio actual
Log.i("JsonData", mediaUrl);
}
}
break;
}
}
});
}
private class MyCallback implements MediaSession.Callback {
@OptIn(markerClass = UnstableApi.class)
@Override
public MediaSession.ConnectionResult onConnect(
MediaSession session, MediaSession.ControllerInfo controller) {
// Set available player and session commands.
Log.i("MyCallback", "onConnect");
return new MediaSession.ConnectionResult.AcceptedResultBuilder(session)
.setAvailablePlayerCommands(
MediaSession.ConnectionResult.DEFAULT_PLAYER_COMMANDS.buildUpon()
.remove(COMMAND_SEEK_TO_NEXT)
.remove(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM)
.remove(COMMAND_SEEK_TO_PREVIOUS)
.remove(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM)
.build())
.setAvailableSessionCommands(
MediaSession.ConnectionResult.DEFAULT_SESSION_COMMANDS.buildUpon()
.add(CUSTOM_COMMAND_FAVORITES)
.build())
.build();
}
public ListenableFuture onCustomCommand(
MediaSession session,
MediaSession.ControllerInfo controller,
SessionCommand customCommand,
Bundle args) {
if (customCommand.customAction.equals(CUSTOM_COMMAND_FAVORITES.customAction)) {
// Do custom logic here
Log.i("MyCallback", "CUSTOM_COMMAND_FAVORITES");
//saveToFavorites(session.getPlayer().getCurrentMediaItem());
return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS));
}
return MediaSession.Callback.super.onCustomCommand(
session, controller, customCommand, args);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("onStartCommand", "Accionado");
if (intent != null && intent.getAction() != null) {
String action = intent.getAction();
if (action.equals(ACCION_REPRODUCIR)) {
// Realiza la acción de reproducir
if (isPlayOn)
{
player.play();
isPlayOn = false;
updatenotificacionaccion(getApplicationContext(),"accion_play_pause",1,R.drawable.ic_pause,"accion_pause");
}
else{
player.pause();
isPlayOn = true;
updatenotificacionaccion(getApplicationContext(),"accion_play_pause",1,R.drawable.ic_play,"accion_play");
}
Log.i("onStartCommand", ACCION_REPRODUCIR);
}else if (action.equals(ACCION_PREVIOUS)) {
player.seekToPreviousMediaItem();
Log.i("onStartCommand", ACCION_PREVIOUS);
} else if (action.equals(ACCION_NEXT)) {
player.seekToNextMediaItem();
Log.i("onStartCommand", ACCION_NEXT);
} else if (action.equals(ACCION_SHUFFLE)) {
if (isShuffleOn)
{
player.setShuffleModeEnabled(false);
isShuffleOn = false;
updatenotificacionaccion(getApplicationContext(),"accion_shuffle",3,R.drawable.baseline_shuffle,"accion_shuffle");
}
else{
player.setShuffleModeEnabled(true);
isShuffleOn = true;
updatenotificacionaccion(getApplicationContext(),"accion_shuffle",3,R.drawable.baseline_shuffle_on,"accion_shuffle");
}
//notificationManager.setPlayer(player);
Log.i("onStartCommand", ACCION_SHUFFLE);
} else if (action.equals(ACCION_CLOSE)) {
//notificationManager.setPlayer(null);
Log.i("onStartCommand", ACCION_CLOSE);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.cancel(154); // Reemplaza 154 con el ID de tu notificación
player.stop();
}
}
}
// Devuelve el comportamiento adecuado para el servicio
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
if (player.isPlaying()) {
player.stop();
}
//notificationManager.setPlayer(null);
player.release();
player = null;
stopForeground(true);
stopSelf();
super.onDestroy();
}
@OptIn(markerClass = UnstableApi.class) public void showNotification(String title) {
Log.i("JsonData", "showNotification");
// Crear un canal de notificación para versiones de Android posteriores a Oreo
NotificationChannel channel = new NotificationChannel(getResources().getString(R.string.app_name), "Reproducción de música", NotificationManager.IMPORTANCE_LOW);
notificationManager = getApplicationContext().getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
// Crear un objeto NotificationCompat.Builder
notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), getResources().getString(R.string.app_name))
.setSmallIcon(R.drawable.ic_launcher) // Icono de la notificación
.setContentTitle(title) // Título de la notificación
.setColorized(true)
.setUsesChronometer(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setOngoing(true) //para dejar fijo
//.setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.ic_launcher)) // Imagen grande para la notificación
.setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
.setMediaSession(mediaSession.getSessionCompatToken()).setShowActionsInCompactView(0, 1, 2));
Intent intentAccion0 = new Intent(getApplicationContext(), MiReceptorDeAccionPersonalizada.class);
intentAccion0.setAction("accion_previous");
PendingIntent pendingIntentAccion0 = PendingIntent.getBroadcast(getApplicationContext(), 0, intentAccion0, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
Intent intentAccion1 = new Intent(getApplicationContext(), MiReceptorDeAccionPersonalizada.class);
intentAccion1.setAction("accion_play_pause");
PendingIntent pendingIntentAccion1 = PendingIntent.getBroadcast(getApplicationContext(), 1, intentAccion1, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
Intent intentAccion2 = new Intent(getApplicationContext(), MiReceptorDeAccionPersonalizada.class);
intentAccion2.setAction("accion_next");
PendingIntent pendingIntentAccion2 = PendingIntent.getBroadcast(getApplicationContext(), 2, intentAccion2, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
Intent intentAccion3 = new Intent(getApplicationContext(), MiReceptorDeAccionPersonalizada.class);
intentAccion3.setAction("accion_shuffle");
PendingIntent pendingIntentAccion3 = PendingIntent.getBroadcast(getApplicationContext(), 3, intentAccion3, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
Intent intentAccion4 = new Intent(getApplicationContext(), MiReceptorDeAccionPersonalizada.class);
intentAccion4.setAction("accion_close");
PendingIntent pendingIntentAccion4 = PendingIntent.getBroadcast(getApplicationContext(), 4, intentAccion4, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
// Agregar acciones a la notificación (pausar y avanzar canción)
notificationBuilder.addAction(R.drawable.ic_skip_previous, "accion_previous", pendingIntentAccion0); // Acción de pausa
if (isPlayOn)
{
notificationBuilder.addAction(R.drawable.ic_play, "accion_play", pendingIntentAccion1); // Acción de avanzar canción
}else{
notificationBuilder.addAction(R.drawable.ic_pause, "accion_pause", pendingIntentAccion1); // Acción de avanzar canción
}
notificationBuilder.addAction(R.drawable.ic_skip_next, "accion_next", pendingIntentAccion2); // Acción de avanzar canción
if (isShuffleOn)
{
notificationBuilder.addAction(R.drawable.baseline_shuffle_on, "accion_shuffle_on", pendingIntentAccion3); // Acción de avanzar canción
}else{
notificationBuilder.addAction(R.drawable.baseline_shuffle, "accion_shuffle", pendingIntentAccion3); // Acción de avanzar canción
}
notificationBuilder.addAction(R.drawable.ic_close, "accion_close", pendingIntentAccion4);
// Mostrar la notificación
notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(154, notificationBuilder.build());
}
public void releasePlayer() {
if (player != null) {
player.release();
player = null;
}
}
public static void updatenotificacionaccion(Context context, String accion, int RequestCode, int icon, String title) {
Intent intentAccion = new Intent(context, MiReceptorDeAccionPersonalizada.class);
intentAccion.setAction(accion);
PendingIntent pendingIntentAccion = PendingIntent.getBroadcast(context, 1, intentAccion, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
notificationBuilder.mActions.set(RequestCode, new NotificationCompat.Action.Builder(icon, title, pendingIntentAccion).build());
notificationManager.notify(154, notificationBuilder.build());
}
}