Gli utenti Android sono abituati a ricevere notifiche. Si manifestano con una piccola icona che appare nella cosiddetta “Notification Area” e se ne può consultare il contenuto aprendo il “Notification drawer”, una zona “a scomparsa” sul display. Oltre alla semplicità comunicativa che le contraddistingue e alla familiarità dell'utente con questo meccanismo, vale la pena trattarle in un corso di questo tipo perché offrono un esempio di segnalazione che esula dall'interfaccia dell'applicazione.
Se si osserva la figura (dalla documentazione ufficiale Android) si possono riconoscere i vari elementi che costituiscono una comune notifica. Facciamoci guidare dai numeri indicati:
- icona piccola (small icon) che di norma appare anche nella barra del display. Viene impostata con il metodo
setSmallIcon
; - nome dell'app, impostata dal sistema;
- ora della notifica impostata di default dal sistema ma modificabile dal programmatore con il metodo
setWhen
.
Eventualmente, può essere rimossa passando l'argomentofalse
al metodosetShowWhen
; - icona grande (large icon), elemento opzionale;
- titolo della notifica (content title), anch'esso opzionale impostabile con
setContentTitle
; - contenuto della notifica, il testo (opzionale), da impostare con
setContentText
.
La prima notifica
Visto che le notifiche appaiono in zone del display non gestite dall'applicazione, dovremo interagire con il sistema mediante un apposito servizio: il NotificationManager. Ne recuperiamo un riferimento:
NotificationManager notificationManager = getSystemService(NotificationManager.class);
A partire dalla versione 8 di Android (API di livello 26), è obbligatorio associare una notifica ad un Channel. Ogni Channel è identificato da
un ID di tipo stringa ed ha associato un profilo audio/visuale da usare per essa. Il seguente codice mostra come attivare una notifica
con tanto di channel:
String CHANNEL_ID="my_channel_id";
String channel_name="channel_name";
String channel_description="channel_description";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
channel_name,
NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription(channel_description);
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(android.R.drawable.star_on)
.setContentTitle("Nuova notifica!!")
.setContentText("Sappi che è successo questo nel tuo sistema: ...")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
notificationManager.notify(0, builder.build());
In questo modo, abbiamo creato un Channel e definito la notifica con un Builder per poi
attivarla mediante il NotificationManager ottenendo quanto si vede in figura:
Collegare un'azione alla notifica
Far apparire notifiche non soddisfa le necessità dell'utente però. Egli è abituato a cliccarvi sopra per ottenere una reazione da parte dell'applicazione. Noi, proseguendo l'esempio, faremo in modo che il click sulla notifica provochi l'apertura di un'altra Activity denominata MessageActivity
.
La preparazione dell'Activity non verrà ripetuta in questa sede considerato lo spazio dedicatole nei capitoli precedenti. Ricordiamo comunque che si dovranno seguire due step fondamentali: creare la classe MessageActivity
estendendo Activity
oltre all'eventuale layout ed inserire un nodo di configurazione del nuovo componente nell'AndroidManifest.xml.
L'apertura dell'Activity avverrà mediante Intent
ma non sarà attivata subito con il metodo startActivity
bensì sarà predisposta per “usi futuri” mediante la classe PendingIntent
. Si tratta di una classe che, per così dire, conserva l'Intent e la descrizione dell'azione che esso porta con sé per poterlo attivare successivamente. Ciò che faremo sarà:
- predisporre un normale
Intent
per l'apertura dellaMessageActivity
; - creazione del
PendingIntent
sfruttando l'Intent
del punto precedente; - assegnazione del
PendingIntent
alla notifica mediante il metodosetContentIntent
delNotificationCompat.Builder
.
Di seguito le modifiche da apportare al codice precedente:
Intent i=new Intent(this,MessageActivity.class);
PendingIntent pi=PendingIntent.getActivity(this, 0, i, 0);
...
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
...
...
.setAutoCancel(true)
.setContentIntent(pi);
notificationManager.notify(0, builder.build());
Ora, dopo l'apertura del “Notification drawer”, si potrà cliccare sulla notifica e ciò comporterà l'esecuzione dell'azione contenuta nel PendingIntent
con conseguente avvio della MessageActivity
. La notifica scomparirà dalla barra dell'applicazione non appena selezionata, merito dell'invocazione al metodo setAutoCancel
().
Notifiche con avviso sonoro
Le notifiche che appaiono sui dispositivi spesso attirano la nostra attenzione con segnalazioni sonore. Con l'applicazione del profilo indotta dal Channel, la notifica acquisisce una sonorità che può essere in generale manipolata. Per farlo dobbiamo recuperare l'Uri del suono che ci interessa:
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
e collegarlo alla notifica in costruzione:
NotificationCompat.Builder n = new NotificationCompat.Builder(this)
. . .
.setSound(sound);
A questo punto il suono della modifica sarà stato ulteriormente personalizzato.