Notificaciones
Para este ejemplo vamos a seguir paso a paso la documentación oficial de Android respecto a las notificaciones:
- Página 1: https://developer.android.com/guide/topics/ui/notifiers/notifications?hl=es-419
- Página 2: https://developer.android.com/training/notify-user/build-notification?hl=es-419
- Página 3: https://developer.android.com/training/notify-user/expanded?hl=es-419
Revisa la documentación antes de continuar. En el ejemplo se ha separado cada tipo de notificación en un botón diferente.
Creación del canal de notificaciones
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = getString(R.string.channel_name);
String description = getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}Este canal de notificaciones es obligatorio únicamente a partir del API 26, por lo que la primera línea que tenemos al intentar crearlo es ` if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { … }` . Por lo tanto si la versión es inferior no es necesario la creación de este canal.
El canal deberá de tener un CHANNEL_ID único, que habrá que tener en cuenta cuando creemos la notificación. Una vez configurados todos los parámetros se creará el canal con notificationManager.createNotificationChannel(channel)
Notificación básica
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_android_black_24dp) // el icono debe de ser en gama de blancos y negros
.setContentTitle("Título")
.setContentText("Contenido")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
// Mostramos la notificación
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(1, builder.build());A tener en cuenta:
- Se debe haber creado anteriormente el canal, y utilizar esa ID para crear la notificación (
CHANNEL_ID). - Para que se muestre el icono correctamente debe de tener un canal alfa. El icono se mostrará en blanco y negro, pero podemos cambiar el color mediante:
builder.setColor(ContextCompat.getColor(context, R.color.colorPrimary))- El
requestCodeennotify()debe de ser único para cada notificación. En caso contrario se irán agrupando.
Notificación con acción toque a una actividad
// Intent explícito hacia una actividad
Intent intent = new Intent(this, Main2Activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_android_black_24dp)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
.setAutoCancel(true);
// Mostramos la notificación
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(2, builder.build());Cambios respecto a la notificación básica:
- Utilización de PendingIntent https://developer.android.com/reference/android/app/PendingIntent, https://android.jlelse.eu/intent-vs-pendingintent-8ef2ad5824ed.
Con botón de acción
Intent snoozeIntent = new Intent(this, Main2Activity.class);
snoozeIntent.setAction("Botón");
snoozeIntent.putExtra("extra", 0);
PendingIntent snoozePendingIntent =
PendingIntent.getActivity(this, 0, snoozeIntent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_android_black_24dp)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.addAction(R.drawable.ic_android_black_24dp, "Botón",
snoozePendingIntent)
// podemos añadir hasta 3 botones, en este caso botón 2 utiliza el mismo pending intent,
// por lo que tendrá la misma funcionalidad de botón 1
.addAction(R.drawable.ic_android_black_24dp, "Botón2",
snoozePendingIntent);
// Mostramos la notificación
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(3, builder.build());Cambios respecto a la acción con toque:
- Observa la instancia de
intenty la llamada a.addAction().
Acción con respuesta directa
En este caso debemos incluir también código en la actividad que recibe el mensaje.
1. Creación de la notificación:
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
.setLabel("Etiqueta1")
.build();
// Build a PendingIntent for the reply action to trigger.
Intent intent = new Intent(this, Main3Activity.class);
//intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
intent, 0);
// Create the reply action and add the remote input.
NotificationCompat.Action action =
new NotificationCompat.Action.Builder(R.drawable.ic_android_black_24dp,
"Etiqueta2", pendingIntent)
.addRemoteInput(remoteInput)
.build();
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_android_black_24dp)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.addAction(action)
.setAutoCancel(true);
// Issue the notification.
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(4, builder.build());2. Código de la actividad receptora:
public class Main3Activity extends AppCompatActivity {
private static final String KEY_TEXT_REPLY = "key_text_reply";
static final String CHANNEL_ID = "ID_CANAL";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
String mensaje = getMessageText(getIntent()).toString();
Toast.makeText(this, mensaje, Toast.LENGTH_SHORT).show();
// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_android_black_24dp);
// Issue the new notification.
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(4, builder.build());
}
private CharSequence getMessageText(Intent intent) {
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
if (remoteInput != null) {
return remoteInput.getCharSequence(KEY_TEXT_REPLY);
}
return null;
}
}
Es en el método `getMessageText()` donde se recupera el mensaje. Además, se debe de devolver un `notify()` a la notificación con una id concreta para responder. Cambios respecto a las notificaciones anteriores:
- Utilización de la clase RemoteInput.
Notification.Action.Builder().addRemoteInput().build()- Debemos de recibir el mensaje y responder.
Barra de progreso
Es una notificación más simple que las anteriores. La dividiremos en varias partes.
1. Creación:
public void notifiacionBarra(View v) {
notificationManagerProgreso = NotificationManagerCompat.from(this);
builderProgreso = new NotificationCompat.Builder(this, CHANNEL_ID);
builderProgreso.setContentTitle("Picture Download")
.setContentText("Download in progress")
.setSmallIcon(R.drawable.ic_android_black_24dp)
.setPriority(NotificationCompat.PRIORITY_LOW);
// Issue the initial notification with zero progress
int PROGRESS_MAX = 100;
int PROGRESS_CURRENT = 0;
builderProgreso.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
notificationManagerProgreso.notify(5, builderProgreso.build());
}2. Aumentar la barra de progreso:
public void notificacionUp(View v) {
// Si estamos por debajo del máximo
if (PROGRESS_CURRENT < PROGRESS_MAX) {
builderProgreso.setProgress(PROGRESS_MAX, PROGRESS_CURRENT += 10, false);
notificationManagerProgreso.notify(5, builderProgreso.build());
}
// Si llegamos al máximo
else {
builderProgreso.setContentText("Download complete")
.setProgress(0, 0, false);
notificationManagerProgreso.notify(5, builderProgreso.build());
}
}3. Disminuir la barra de progreso:
public void notificacionDown(View v) {
builderProgreso.setProgress(PROGRESS_MAX, PROGRESS_CURRENT-=10, false);
notificationManagerProgreso.notify(5, builderProgreso.build());
}- Proyecto GitHub: https://github.com/Manuel-Ag/PMD_19-20/tree/master/Notificaciones