Skip to content

Error appearing new button in API notification 33 #940

@byJS93

Description

@byJS93

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());

    }
}

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions