¿Cómo agregar un botón a las notificaciones en Android?

84

Mi aplicación reproduce música y cuando los usuarios abren la pantalla de notificaciones deslizando el dedo desde la parte superior de la pantalla (o generalmente desde la parte inferior derecha de la pantalla en tabletas), quiero presentarles un botón para detener la música que se está reproduciendo actualmente y volver a iniciarla si ellos quieren.

No planeo poner un widget en la pantalla de inicio del usuario, sino solo en las notificaciones. ¿Cómo puedo hacer esto?

franco
fuente
lo siento en ese caso
franco
62
Creo que es una pregunta válida
hunterpillar
7
¿Cómo no es esta una pregunta válida ffs?
Radu
3
Algunas personas simplemente
7
Este es el resultado principal en mi búsqueda de Google y no hay respuestas ...
Ben

Respuestas:

11

Puede crear una intención para la acción (en este caso, dejar de jugar) y agregarla como un botón de acción a su notificación.

Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
snoozeIntent.setAction(ACTION_SNOOZE);
snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
PendingIntent snoozePendingIntent =
        PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent);

Consulte la documentación de Android .

Rubén Miquelino
fuente
Para mejorar su respuesta, agregará "texto" sin icono. Por favor, proporcione una forma de crear la intención, agregue el botón de icono al área de notificación y únase a ambos, luego cómo recibir la intención.
tabebqena
8

Agregar botón de acción a la notificación

Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
snoozeIntent.setAction(ACTION_SNOOZE);
snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
PendingIntent snoozePendingIntent =
        PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);

NotificationCompat.Builder mBuilder = new 
NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent);

Para obtener más detalles, visite https://developer.android.com/training/notify-user/build-notification.html

labhya sharma
fuente
Para mejorar su respuesta, agregará "texto" sin icono. Por favor, proporcione una forma de crear la intención, agregue el botón de icono en el área de notificación y únase a ambos.
tabebqena
"Agregar botón de acción" agregará el botón debajo del contenido de la notificación que no está dentro de él.
tabebqena
4

Intentaré proporcionar una solución que he usado y la mayoría de los reproductores de música también usan la misma técnica para mostrar los controles del reproductor en la barra de notificaciones.

Estoy ejecutando un servicio que se usa para administrar Media Player y todos sus controles. Actividad El control del usuario interactúa con el Servicio enviando Intents al servicio, por ejemplo

 Intent i = new Intent(MainActivity.this, MyRadioService.class);
        i.setAction(Constants.Player.ACTION_PAUSE);

        startService(i);

PARA recibir intenciones y realizar acciones en la clase de servicio, estoy usando el siguiente código en el método de servicio onStartCommand

 @Override
public int onStartCommand(Intent intent, int flags, int startId) {


    if (intent.getAction().equals(Constants.Player.ACTION_PAUSE)) {
        if(mediaPlayer.isPlaying()) {
            pauseAudio();
        }
    }

Ahora para responder exactamente a su pregunta para mostrar la notificación con los controles de reproducción. Puede llamar a los siguientes métodos para mostrar notificaciones con controles.

   //    showNotification
private void startAppInForeground() {
//  Start Service in Foreground

    // Using RemoteViews to bind custom layouts into Notification
    RemoteViews views = new RemoteViews(getPackageName(),
            R.layout.notification_status_bar);

// Define play control intent 
   Intent playIntent = new Intent(this, MyRadioService.class);
    playIntent.setAction(Constants.Player.ACTION_PLAY);

// Use the above play intent to set into PendingIntent
    PendingIntent pplayIntent = PendingIntent.getService(this, 0,
            playIntent, 0);

// binding play button from layout to pending play intent defined above 
views.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent);
views.setImageViewResource(R.id.status_bar_play,
            R.drawable.status_bg);

Notification status = null;
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        status = new Notification.Builder(this).build();
    }

  status.flags = Notification.FLAG_ONGOING_EVENT;
    status.icon = R.mipmap.ic_launcher;
    status.contentIntent = pendingIntent;
    startForeground(Constants.FOREGROUND_SERVICE, status);

} Espero que esto realmente te ayude. Y podrás lograr lo que deseas. Que tengas una codificación feliz :)

Ankit Gupta
fuente
1
No lo intenté. Pero parece que la única completerespuesta fital caso del usuario.
tabebqena
4
    // It shows buttons on lock screen (notification).

Notification notification = new Notification.Builder(context)
    .setVisibility(Notification.VISIBILITY_PUBLIC)
    .setSmallIcon(R.drawable.NotIcon)
    .addAction(R.drawable.ic_prev, "button1",ButtonOneScreen) 
    .addAction(R.drawable.ic_pause, "button2", ButtonTwoScreen)  
   .....
    .setStyle(new Notification.MediaStyle()
    .setShowActionsInCompactView(1)
    .setMediaSession(mMediaSession.getSessionToken())
    .setContentTitle("your choice")
    .setContentText("Again your choice")
    .setLargeIcon(buttonIcon)
    .build();

Consulte esto para obtener más detalles Haga clic aquí

Chandsi Gupta
fuente
1

Creo que además de la Ankit Guptarespuesta, puede usar MediaSession (API> 21) para agregar la vista nativa de mediaController :

notificationBuilder
        .setStyle(new Notification.MediaStyle()
            .setShowActionsInCompactView(new int[]{playPauseButtonPosition})  // show only play/pause in compact view
            .setMediaSession(mSessionToken))
        .setColor(mNotificationColor)
        .setSmallIcon(R.drawable.ic_notification)
        .setVisibility(Notification.VISIBILITY_PUBLIC)
        .setUsesChronometer(true)
        .setContentIntent(createContentIntent(description)) // Create an intent that would open the UI when user clicks the notification
        .setContentTitle(description.getTitle())
        .setContentText(description.getSubtitle())
        .setLargeIcon(art);

Fuente: tutorial

También puede crear una vista personalizada y mostrarla en el área de notificación, la primera respuesta aquí es excelente.

tabebqena
fuente
1

probado, código de trabajo con Android Pie. Todos estos van dentro de la misma clase de servicio.

Mostrar una notificación:

public void setNotification() {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
    {
    NotificationChannel channel = new NotificationChannel("a", "status", NotificationManager.IMPORTANCE_DEFAULT);
    channel.setDescription("notifications");
    notificationManager = getSystemService(NotificationManager.class);
    notificationManager.createNotificationChannel(channel);

    }
else
    notificationManager =  (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);


Receiver.service = this;
Notification.MediaStyle style = new Notification.MediaStyle();

notification = new Notification.Builder(this)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle("Notification")
        .addAction(R.drawable.close_icon,  "quit_action", makePendingIntent("quit_action"))
        .setStyle(style);

style.setShowActionsInCompactView(0);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
    {
    notification.setChannelId("a");
    }

// notificationManager.notify(123 , notification.build()); // pre-oreo
startForeground(126, notification.getNotification());
}

Función de ayudante:

public PendingIntent makePendingIntent(String name)
    {
    Intent intent = new Intent(this, FloatingViewService.Receiver.class);
    intent.setAction(name);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
    return pendingIntent;
    }

Para manejar las acciones:

static public class Receiver extends BroadcastReceiver {
static FloatingViewService service;

@Override
public void onReceive(Context context, Intent intent)
    {

    String whichAction = intent.getAction();

    switch (whichAction)
        {

        case "quit_action":
            service.stopForeground(true);
            service.stopSelf();
            return;

        }

    }
}

También necesitará actualizar su manifiesto:

<receiver android:name=".FloatingViewService$Receiver">
        <intent-filter>
            <action android:name="quit_action" />
        </intent-filter>
    </receiver>
Al Ro
fuente
1

puede agregar el botón como se muestra a continuación y puede realizar una acción en ese botón también lo he hecho por mí como se muestra a continuación, por favor verifique.

NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                        .setSmallIcon(R.drawable.ic_logo)
                        .setAutoCancel(true)
                        .setContentTitle(name)
                        .setContentText(body)
                        .setGroupSummary(true)
                        .addAction(android.R.drawable.ic_menu_directions, "Mark as read", morePendingIntent);

// morePendingIntent (haz tus cosas)

  PendingIntent morePendingIntent = PendingIntent.getBroadcast(
                        this,
                        REQUEST_CODE_MORE,
                        new Intent(this, NotificationReceiver.class)
                                .putExtra(KEY_INTENT_MORE, REQUEST_CODE_MORE)
                                .putExtra("bundle", object.toString()),
                        PendingIntent.FLAG_UPDATE_CURRENT
                );
yuvrajsinh
fuente
0

No sé si esta es la forma correcta o no, pero funciona.

  1. Crea una BroadCastReceiverclase para recibir los datos cuando se presiona el botón.
public class MyBroadCastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        
        String log = "URI: " + intent.toUri(Intent.URI_INTENT_SCHEME);
        Log.d("my", "LOG:::::::" + log);
    }
}
  1. Ahora en cualquier actividad en la que desee crear la notificación:
 Intent intent = new Intent();
        intent.setAction("unique_id");
        intent.putExtra("key", "any data you want to send when button is pressed");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, REQUEST_CODE, intent, 0);
  1. Ahora use esta intención pendiente cuando esté creando la notificación y, por último, debe registrar esta transmisión para recibirla en la clase MyBroadCastReceiver.
BroadcastReceiver br = new MyBroadCastReceiver();
        IntentFilter filter = new IntentFilter("unique_id");
        registerReceiver(br, filter);

Ahora, si desea hacer ciertas cosas cuando se presiona el botón, puede hacerlo en el onReceive()método en MyBroadCastReceiverclase.

Sudhanshu Dubey
fuente