Questo codelab fa parte del corso Advanced Android in Kotlin. Per ottenere il massimo valore da questo corso, ti consigliamo di seguire i codelab in sequenza, ma non è obbligatorio. Tutti i codelab del corso sono elencati nella pagina di destinazione dei codelab Advanced Android in Kotlin.
Introduzione
Le notifiche sono messaggi mostrati all'utente al di fuori dell'interfaccia utente dell'app. Le notifiche vengono visualizzate nella parte superiore dello schermo se il dispositivo è sbloccato o, a seconda delle impostazioni di sicurezza, nella schermata di blocco quando il dispositivo è bloccato.
Una notifica tipica è composta da un titolo, una descrizione e un'icona. Una notifica può anche avere azioni cliccabili, una risposta rapida, contenuti estendibili e immagini.
Le notifiche possono fornire materiale tempestivo e possono avere pulsanti per consentire all'utente di eseguire azioni rapide, come inviare una risposta o posticipare una sveglia. Se fa clic su una notifica, l'utente viene indirizzato a una visualizzazione nella tua app correlata ai contenuti della notifica.
Le notifiche sono un modo utile per ricordare agli utenti un'attività importante, informarli di un evento o comunicare informazioni importanti di cui hanno bisogno immediatamente mentre la tua app è in background. Utilizza le notifiche con parsimonia. In questo modo, non solo rispetti gli utenti, ma aumenti anche le probabilità che la notifica della tua app riceva l'attenzione che merita.
In questo codelab imparerai a creare e utilizzare le notifiche in un'app per Android.
Cosa devi già sapere
Devi avere familiarità con:
- Come creare app per Android in Kotlin. In particolare, lavora con l'SDK Android.
- Come progettare app utilizzando i componenti dell'architettura e il data binding.
- Conoscenza di base dei BroadcastReceiver
- Conoscenza di base di AlarmManager
Obiettivi didattici
- Come creare, formattare e inviare una notifica.
- Come annullare le notifiche.
- Come creare canali di notifica.
- Come aggiungere azioni rapide alle notifiche.
- Come visualizzare i badge di notifica sull'icona dell'app.
In questo lab proverai a:
- Aggiungi una notifica all'app iniziale.
- Annulla la notifica che hai inviato in precedenza.
- Crea canali per diversi tipi di notifiche.
- Personalizza le notifiche nell'app iniziale.
- Aggiungi azioni rapide per rendere interattiva la notifica.
- Disattiva i badge delle notifiche.
Cuocere le uova è semplice, ma può essere un compito difficile se non tieni traccia del tempo. In questo codelab, lavorerai su un'app per la cottura delle uova e la perfezionerai, proprio come le tue uova future. Inizierai con un'app timer per uova funzionante che consente all'utente di impostare tempi di cottura diversi per diversi tipi di uova. Il timer esegue il conto alla rovescia dall'intervallo di tempo selezionato e mostra un messaggio di notifica quando le uova sono pronte.
Potrebbe sembrare funzionale, ma è tutt'altro che perfetto e non è molto facile da usare. Per iniziare, il messaggio toast viene visualizzato solo per un breve periodo di tempo ed è quindi facile da perdere. Inoltre, se l'app non è in primo piano o il dispositivo è bloccato, non è presente alcun indicatore visivo dello stato del timer una volta che il messaggio toast scompare.
Idealmente, il timer per uova dovrebbe utilizzare le notifiche per comunicare agli utenti quando il tempo è scaduto. L'utente ha davvero bisogno di sapere subito che le uova sono pronte, altrimenti saranno troppo cotte. Le notifiche sono visive, possono includere suoni e possono far vibrare il dispositivo, tutti modi per attirare l'attenzione dell'utente. In questo modo, puoi ottenere uova perfette e utenti felici e ben nutriti.
Per ottenere l'app di esempio, puoi:
Clona il repository da GitHub e passa al branch starter.
$ git clone https://github.com/googlecodelabs/android-kotlin-notifications
In alternativa, puoi scaricare il repository come file ZIP, decomprimerlo e aprirlo in Android Studio.
- Apri ed esegui l'app in Android Studio.
Vedrai un'immagine di un uovo e un menu a discesa con un elenco di intervalli di tempo predefiniti per cuocere un uovo. Fai clic sul triangolo del menu a discesa Alla coque. La prima opzione dell'elenco viene fornita a scopo di test e imposta la sveglia su soli 10 secondi. Accanto all'elenco si trova un interruttore che avvia il timer. Puoi utilizzare questo interruttore per avviare e interrompere il timer per uova in qualsiasi momento. Il codice iniziale è completamente funzionante, il che significa che puoi impostare il timer per le uova e guardarlo fare il conto alla rovescia fino a 0. Al termine del timer, viene visualizzato un messaggio di notifica, come mostrato di seguito.
- Esamina il codice sorgente. L'app iniziale è costituita da una singola attività denominata
MainActivity
. Esistono tre pacchetti secondari denominatireceiver
,ui
eutil
.
- /receiver: il pacchetto
receiver
contiene due ricevitori di trasmissione denominatiAlarmReceiver
eSnoozeReceiver
.AlarmReceiver
viene attivato daAlarmManager
per inviare la notifica quando il timer definito dall'utente è scaduto.SnoozeReceiver
gestisce il clic dell'utente per posticipare la notifica. - /ui: contiene
EggTimerFragment
, che fa parte della sezione dell'interfaccia utente dell'app.EggTimerViewModel
è responsabile dell'avvio e dell'annullamento del timer e di altre attività dell'app correlate al ciclo di vita. - /util: in questo pacchetto sono presenti due file.
BindingUtils.kt
dispone di adattatori di binding per attivare il binding dei dati tra la UI dell'app eViewModel
.NotificationUtils.kt
dispone di metodi di estensione suNotificationManager
.
L'utilizzo delle notifiche è un ottimo modo per attirare l'attenzione degli utenti sulla tua app. Indipendentemente dal fatto che l'app non sia in esecuzione o sia in esecuzione in primo piano, una notifica mostrerà una finestra popup nella parte superiore dello schermo e potrebbe includere suoni o vibrazioni. Per creare una notifica, devi utilizzare un generatore di notifiche e fornire un testo del titolo, un testo del contenuto e un'icona. Una volta che il builder dispone di tutti i campi necessari, NotificationManager
, un servizio di sistema, ti aiuta a visualizzare questi contenuti come notifica. NotificationManager
è responsabile dell'invio di una notifica, dell'aggiornamento dei relativi contenuti e dell'annullamento della notifica. Nei passaggi successivi, aggiungerai i metodi di estensione a NotificationManager
. In questo modo, ogni volta che devi utilizzare NotificationManager
, potrai utilizzare queste funzioni di estensione per ottenere la funzionalità che ti serve.
Passaggio 1: crea una notifica di base
In questa attività, creerai una nuova notifica, imposterai un messaggio per l'utente e invierai la notifica.
- Apri il corso
NotificationUtils.kt
e trovaTODO: Step 1.1
. Troverai attività corrispondenti in questo codelab e nel codice dell'app. - Esamina la funzione
sendNotification()
fornita. Stai estendendo questa funzione di estensione aNotificationManager
per inviare notifiche.
//NotificationUtils.kt
// TODO: Step 1.1 extension function to send messages (GIVEN)
/**
* Builds and delivers a notification.
*
* @param messageBody, notification text.
* @param context, activity context.
*/
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
- Recupera un'istanza del generatore di notifiche, passa il contesto dell'app e un ID canale. L'ID canale è un valore stringa per il canale.
I canali di notifica sono un modo per raggruppare le notifiche. Raggruppando tipi simili di notifiche, sviluppatori e utenti possono controllare tutte le notifiche nel canale. Una volta creato, un canale può essere utilizzato per inviare un numero qualsiasi di notifiche.
//NotificationUtils.kt
// TODO: Step 1.2 get an instance of NotificationCompat.Builder
val builder = NotificationCompat.Builder(
applicationContext,
applicationContext.getString(R.string.egg_notification_channel_id)
)
- Imposta l'icona di notifica in modo che rappresenti la tua app, un titolo e il testo dei contenuti del messaggio che vuoi inviare all'utente. Nel codelab vedrai altre opzioni per personalizzare ulteriormente la notifica, ma questa è la quantità minima di dati che devi impostare per inviare una notifica.
//NotificationUtils.kt
// TODO: Step 1.3 set title, text and icon to builder
.setSmallIcon(R.drawable.cooked_egg)
.setContentTitle(applicationContext.getString(R.string.notification_title))
.setContentText(messageBody)
- Successivamente, devi chiamare
notify()
con un ID univoco per la notifica e con l'oggettoNotification
del builder.
Questo ID rappresenta l'istanza di notifica corrente ed è necessario per aggiornare o annullare questa notifica. Poiché la tua app avrà una sola notifica attiva in un determinato momento, puoi utilizzare lo stesso ID per tutte le notifiche. A questo scopo, in NotificationUtils.kt
è già disponibile una costante denominata NOTIFICATION_ID
. Tieni presente che puoi chiamare direttamente notify()
poiché stai eseguendo la chiamata da una funzione di estensione nella stessa classe.
//NotificationUtils.kt
// TODO: Step 1.4 call notify to send the notification
// Deliver the notification
notify(NOTIFICATION_ID, builder.build())
- Apri
ui/EggTimerViewModel.kt
e trova la funzionestartTimer()
. Questa funzione crea una sveglia con l'intervallo di tempo selezionato quando l'utente attiva il timer per uova. - Attiverai una notifica in questa funzione quando l'utente avvia il timer. Per chiamare la funzione
sendNotification()
che hai implementato in precedenza, devi disporre di un'istanza diNotificationManager
.NotificationManager
è un servizio di sistema che fornisce tutte le funzioni esposte per l'API Notifications, inclusa la funzione di estensione che hai aggiunto. Ogni volta che vuoi inviare, annullare o aggiornare una notifica, devi richiedere un'istanza diNotificationManager
dal sistema. Chiama la funzionesendNotification()|
con il messaggio di notifica e con il contesto.
// EggTimerViewModel.kt
// TODO: Step 1.5 get an instance of NotificationManager
// and call sendNotification
val notificationManager = ContextCompat.getSystemService(
app,
NotificationManager::class.java
) as NotificationManager
notificationManager.sendNotification(app.getString(R.string.timer_running), app)
Ci siamo quasi. Tuttavia, se esegui l'app ora e imposti il timer, non riceverai una notifica.
- Apri
logcat
e cerca"No Channel found"
. Dovresti visualizzare un messaggio di errore che indica cheegg_channel
non esiste. Nei passaggi successivi scoprirai di più sui canali di notifica e risolverai il problema.
Passaggio 2: canali di notifica
A partire dal livello API 26, tutte le notifiche devono essere assegnate a un canale. Se tocchi e tieni premuta l'icona del launcher delle app, seleziona Informazioni app e tocca Notifiche, vedrai un elenco di canali di notifica associati all'app. Al momento l'elenco è vuoto perché l'app non ha creato alcun canale.
I canali rappresentano un "tipo" di notifica. Ad esempio, il timer per le uova può inviare una notifica quando le uova sono cotte e utilizzare un altro canale per inviare notifiche giornaliere per ricordarti di mangiare le uova a colazione. Tutte le notifiche di un canale sono raggruppate e gli utenti possono configurare le impostazioni di notifica per un intero canale. In questo modo, gli utenti possono personalizzare le impostazioni di notifica in base al tipo di notifica che li interessa. Ad esempio, gli utenti possono disattivare le notifiche per la colazione, ma continuare a visualizzare le notifiche del timer.
Gli sviluppatori impostano le impostazioni iniziali, l'importanza e il comportamento da applicare a tutte le notifiche di un canale. Dopo aver impostato le impostazioni iniziali, gli utenti possono ignorarle.
Nel passaggio 1.1 hai utilizzato egg_notification_channel_id
come canale di notifica, quindi ora devi creare e personalizzare le impostazioni e il comportamento delle notifiche di questo canale.
- Apri
EggTimerFragment.kt
e trova la funzionecreateChannel()
. - Passa l'ID canale univoco al costruttore di
NotificationChannel
. - Passa il nome del canale di notifica, che gli utenti vedranno anche nella schermata Impostazioni.
- Come ultimo parametro, trasmetti il livello di importanza per il canale di notifica. I livelli di importanza verranno trattati più avanti in questo codelab, quindi per ora puoi utilizzare
NotificationManag
er.IMPORTANCE_LOW
. - Nell'oggetto
notificationChannel
impostaenableLights
su true. Questa impostazione attiva le luci quando viene visualizzata una notifica. - Imposta l'
notificationChannel
oggettolightColor
su rosso per visualizzare una luce rossa quando viene mostrata una notifica. - Nell'oggetto
notificationChannel
impostaenableVibration
su true per attivare la vibrazione. - Nell'oggetto
notificationChannel
imposta la descrizione del canale su‘Time for breakf
ast'. - Ottieni un'istanza di
NotificationManager
chiamando il numerogetSystemService()
. - Chiama
createNotificationChannel()
suNotificationManager
e passa l'oggettonotificationChannel
che hai creato nel passaggio precedente.
//EggTimerFragment.kt
private fun createChannel(channelId: String, channelName: String) {
// TODO: Step 1.6 START create a channel
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(
channelId,
channelName,
// TODO: Step 2.4 change importance
NotificationManager.IMPORTANCE_LOW
)
// TODO: Step 2.6 disable badges for this channel
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.RED
notificationChannel.enableVibration(true)
notificationChannel.description = "Time for breakfast"
val notificationManager = requireActivity().getSystemService(
NotificationManager::class.java
)
notificationManager.createNotificationChannel(notificationChannel)
}
// TODO: Step 1.6 END create channel
}
- Successivamente, per creare un canale, devi chiamare la funzione
createChannel()
che hai appena scritto (passaggio 1.7). Questa funzione accetta due parametri: l'ID canale e il nome del canale. Devi cercare l'ID e il nome del canale nelle risorse stringa già presenti nel progetto.
// EggTimerFragment.kt
// TODO: Step 1.7 call createChannel
createChannel(
getString(R.string.egg_notification_channel_id),
getString(R.string.egg_notification_channel_name)
)
- Devi trasmettere l'ID canale al generatore di notifiche. L'hai già fatto nel passaggio 1.2. Se imposti un valore errato come ID canale, la notifica non andrà a buon fine. Apri
NotificationUtils.kt
per verificare che l'ID canale che hai impostato in precedenza sia corretto.
// NotificationUtils.kt
val builder = NotificationCompat.Builder(
applicationContext,
// TODO: Step 1.8 verify the notification channel name
applicationContext.getString(R.string.egg_notification_channel_id)
)
- Esegui l'app e vedrai che invia una notifica ogni volta che avvii il timer.
- Trascina la barra di stato e osserva che il titolo, i contenuti e l'icona della notifica sono quelli impostati nei passaggi precedenti.
- Per verificare il canale appena creato, chiudi l'app e trova l'icona dell'app. Tocca a lungo l'icona dell'app e seleziona Informazioni app.
- Seleziona Notifiche dall'elenco delle impostazioni. Dovresti visualizzare un nuovo canale denominato Egg, subito sotto l'impostazione Mostra notifiche.
Quando esegui l'app, la notifica viene visualizzata. Sia tu, in qualità di sviluppatore di app, sia i tuoi utenti potete personalizzare le impostazioni e il comportamento di tutte le notifiche inviate su questo canale. Congratulazioni, hai creato una notifica.
Passaggio 3: aggiungi le notifiche all'app
Finora abbiamo mostrato l'utilizzo di base dell'API Notifications, ma inviare una notifica subito dopo aver avviato il timer non ha molto senso. Gli utenti probabilmente preferiscono ricevere una notifica quando l'uovo è pronto. Nella parte successiva del codelab, risolverai questo problema e modificherai il messaggio di notifica in una notifica.
Hai già inviato la notifica e osservato come viene mostrata agli utenti, ma questo è solo il primo passo per creare notifiche efficaci. In questo passaggio, modificherai la notifica in modo che venga inviata in un momento più opportuno.
La tua app utilizza AlarmManager
per impostare una sveglia. Il codice relativo a AlarmManager
è già presente nel codice iniziale e viene utilizzato per mostrare il messaggio di notifica. AlarmManager
tiene traccia della selezione dell'ora desiderata e attiva la funzione onReceive()
di AlarmReceiver.kt
quando il tempo è scaduto. Se apri AlarmReceiver.kt
e vai a onReceive()
, dovresti visualizzare il messaggio di notifica che viene visualizzato ogni volta che imposti un timer per uova.
- Apri
AlarmReceiver.kt
, un'istanza diNotificationManager
, e chiama la funzionesendNotification()
con il testo del messaggio e i parametri di contesto.
// AlarmReceiver.kt
// TODO: Step 1.9 add call to sendNotification
val notificationManager = ContextCompat.getSystemService(
context,
NotificationManager::class.java
) as NotificationManager
notificationManager.sendNotification(
context.getText(R.string.eggs_ready).toString(),
context
)
- (Facoltativo) Rimuovi il messaggio di notifica temporaneo, poiché la tua app invierà una notifica quando il timer è scaduto.
// AlarmReceiver.kt
// TODO: Step 1.10 [Optional] remove toast
// Toast.makeText(
// context,
// context.getText(R.string.eggs_ready),
// Toast.LENGTH_SHORT
// ).show()
- Esegui l'app . Dovresti visualizzare una notifica ogni volta che avvii il timer e ogni volta che il timer scade.
Non è l'ideale. Non vuoi inviare troppe notifiche ai tuoi utenti. Puoi rimuovere la prima notifica inviata quando l'utente avvia il timer.
- Apri
EggTimerFragment.kt
e rimuovi il codice di notifica per il passaggio 1.5.
// EggTimeViewModel.kt
// TODO: Step 1.5 get an instance of NotificationManager
// and call sendNotification
// val notificationManager = ContextCompat.getSystemService(
// app,
// NotificationManager::class.java
// ) as NotificationManager
// notificationManager.sendNotification(app.getString(R.string.eggs_ready), app)
- Esegui di nuovo l'app.
- Imposta un timer, mettilo in background e attendi che il tempo scada. Vedrai una notifica. Questa è una notifica molto più utile.
Passaggio 4: aggiungi un intento dei contenuti
- Esegui di nuovo l'app, se non è già in esecuzione.
- Fai clic sulla notifica. Non succede nulla.
Mostrare la notifica e informare l'utente è un ottimo modo per comunicare, ma quando un utente fa clic su una notifica, si aspetta di tornare all'app corrispondente. In questa parte del codelab aggiungerai un intent alla notifica per riportare l'utente alla schermata del timer.
Un Intent
è un oggetto di messaggistica che puoi utilizzare per richiedere un'azione a un altro componente dell'app. Gli intent possono essere utilizzati per avviare un'attività, un servizio o trasmettere una trasmissione. In questo caso, utilizzi questo intent per indicare al sistema di aprire MainActivity
quando l'utente tocca la notifica. Poiché la tua app è costituita da una sola vista, non hai molte opzioni a disposizione. Tuttavia, in un'app più grande, la notifica dovrebbe creare un'esperienza fluida portando l'utente a una schermata che abbia senso quando interagisce con la notifica.
- Apri
NotificationUtils.kt
e trova la funzione di estensionesendNotification()
. - Crea un
Intent
con il tuoapplicationContext
e l'attività da avviare,MainActivity::class.java
.
// NotificationUtils.kt
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
// Create the content intent for the notification, which launches
// this activity
// TODO: Step 1.11 create intent
val contentIntent = Intent(applicationContext, MainActivity::class.java)
Hai creato l'intent, ma la notifica viene visualizzata al di fuori della tua app. Per far funzionare un intent al di fuori della tua app, devi creare un nuovo PendingIntent
.
PendingIntent
concede a un'altra applicazione o al sistema i diritti per eseguire un'operazione per conto della tua applicazione. Un PendingIntent
è semplicemente un riferimento a un token gestito dal sistema che descrive i dati originali utilizzati per recuperarlo. Ciò significa che, anche se il processo dell'applicazione proprietaria viene interrotto, l'PendingIntent
stesso rimarrà utilizzabile da altri processi a cui è stato assegnato. In questo caso, il sistema utilizzerà l'intent in attesa per aprire l'app per tuo conto, indipendentemente dal fatto che l'app timer sia in esecuzione o meno.
- Crea un
PendingIntent
conapplicationContext
,NOTIFICATION_ID
, ilcontentIntent
che hai creato nel passaggio precedente e il flagPendingIntent
. Il flagPendingIntent
specifica l'opzione per creare un nuovoPendingIntent
o utilizzarne uno esistente. Devi impostarePendingIntent.FLAG_UPDATE_CURRENT
come flag perché non vuoi creare una nuova notifica se ne esiste già una. In questo modo, modificherai l'PendingIntent
corrente associato all'intent che stai fornendo.
// NotificationUtils.kt
// TODO: Step 1.12 create PendingIntent
val contentPendingIntent = PendingIntent.getActivity(
applicationContext,
NOTIFICATION_ID,
contentIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
- Passa
PendingIntent
alla notifica. Per farlo, chiamasetContentIntent()
suNotificationBuilder
. Ora, quando fai clic sulla notifica, viene attivatoPendingIntent
, che apreMainActivity
. - Imposta anche
setAutoCancel()
sutrue
, in modo che quando l'utente tocca la notifica, questa si chiuda mentre lo indirizza all'app.
// NotificationUtils.kt
// TODO: Step 1.13 set content intent
.setContentIntent(contentPendingIntent)
.setAutoCancel(true)
- Esegui di nuovo l'app.
- Imposta un timer, metti l'app in background e attendi la visualizzazione della notifica.
- Una volta visualizzata la notifica, fai clic su di essa tirando giù la barra di stato e osserva come l'app viene portata in primo piano.
Passaggio 5: annulla la notifica
Hai un timer per uova funzionale con notifiche, ma c'è un piccolo problema. Se imposti il timer, ricevi una notifica e lo imposti di nuovo, la notifica precedente rimane sulla barra di stato mentre il nuovo timer è in esecuzione. Questo può confondere l'utente se l'app è in background e potrebbe portare a uova poco cotte.
Per risolvere il problema, devi cancellare la notifica precedente quando avvii un nuovo timer. Inizia creando un'altra funzione di estensione in NotificationUtils.kt
. NotificationManager
ha un'API per annullare tutte le notifiche attive chiamata cancelAll
()
.
- Apri
NotificationsUtil.kt
. - Aggiungi una funzione di estensione su
NotificationManager
che chiamacancelAll()
.
// NotificationUtils.kt
// TODO: Step 1.14 Cancel all notifications
/**
* Cancels all notifications.
*
*/
fun NotificationManager.cancelNotifications() {
cancelAll()
}
- Apri
EggTimerViewModel.kt
e vai alla funzionestartTimer()
. - All'interno di
startTimer()
, recupera un'istanza diNotificationManager
dal sistema e chiamacancelNotifications()
.
// EggTimerViewModel.kt
//TODO Step 1.15 call cancel notification
val notificationManager =
ContextCompat.getSystemService(
app,
NotificationManager::class.java
) as NotificationManager
notificationManager.cancelNotifications()
- Esegui l'app e avvia il timer.
- Dopo aver visualizzato la notifica, avvia di nuovo il timer e osserva come la nostra app elimina automaticamente la notifica precedente dalla barra di stato.
Il framework di notifica offre una serie di opzioni di personalizzazione per consentire agli sviluppatori di impostare azioni personalizzate e definire lo stile delle notifiche in base alle esigenze. Durante questa attività, imparerai a personalizzare le notifiche del timer per uova.
Passaggio 1: personalizza la notifica
Se personalizzi lo stile della notifica in base alle tue esigenze e ai contenuti della notifica, quest'ultima risulterà più evidente e sembrerà un'estensione della tua applicazione. Il framework di notifica include diversi stili integrati per aiutarti e puoi sempre creare il tuo.
NotificationCompat
offre stili integrati per:
BigTextStyle
, che può visualizzare un blocco di testo di grandi dimensioni, ad esempio il contenuto di un'email quando viene espansa.BigPictureStyle
, che mostra notifiche di grande formato che includono un allegato di immagine di grandi dimensioni.InboxStyle
, che mostra un contenuto di testo in stile conversazione.MediaStyle
, che mostra i controlli per la riproduzione dei contenuti multimediali.MessagingStyle
, che mostra notifiche di grande formato che includono più messaggi tra un numero qualsiasi di persone.
Puoi trovare maggiori informazioni su altri stili nella documentazione relativa a Creare una notifica espandibile. In questo passaggio utilizzerai NotificationCompat.BigPictureStyle
per creare una notifica espandibile che mostri un'immagine grande dell'uovo quando viene espansa.
- Apri
NotificationUtils.kt
e trova la funzionesendNotification()
. - Inizia caricando un'immagine da
resources
utilizzandoBitmapFactory
.
// NotificationUtils.kt
// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
applicationContext.resources,
R.drawable.cooked_egg
)
- Crea un nuovo
BigPictureStyle
e imposta l'immagine. - Imposta
bigLargeIcon()
sunull
in modo che l'icona grande scompaia quando la notifica viene espansa.
// NotificationUtils.kt
// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
applicationContext.resources,
R.drawable.cooked_egg
)
val bigPicStyle = NotificationCompat.BigPictureStyle()
.bigPicture(eggImage)
.bigLargeIcon(null)
- Imposta lo stile con
setStyle()
subigPicStyle
. - Imposta l'icona grande con
setLargeIcon()
sueggImage
, in modo che l'immagine venga visualizzata come icona più piccola quando la notifica è compressa.
// NotificationUtils.kt
// TODO: Step 2.1 add style to builder
.setStyle(bigPicStyle)
.setLargeIcon(eggImage)
- Esegui l'app e imposta un timer. Quando la notifica viene visualizzata per la prima volta, si trova nello stato compresso nel riquadro a scomparsa delle notifiche. Se espandi la notifica, nell'area della notifica estesa viene visualizzata un'immagine di grandi dimensioni.
Passaggio 2: azioni di notifica
Le azioni di notifica sono un'altra personalizzazione che puoi aggiungere alle tue notifiche. Al momento, le notifiche reindirizzano gli utenti alla tua app quando fanno clic su di esse. Oltre a questa azione di notifica predefinita, puoi aggiungere pulsanti di azione che completano un'attività correlata all'app dalla notifica.
Una notifica può offrire fino a tre pulsanti di azione che consentono all'utente di rispondere rapidamente, ad esempio posticipare un promemoria o rispondere a un messaggio. Questi pulsanti di azione non devono duplicare l'azione eseguita quando l'utente tocca la notifica.
Per aggiungere un pulsante di azione, passa un PendingIntent
alla funzione addAction()
nel builder. Questa operazione è simile alla configurazione dell'azione di tocco predefinita della notifica tramite la chiamata di setContentIntent()
, tranne per il fatto che, anziché avviare un'attività, puoi fare una serie di altre cose, ad esempio avviare un BroadcastReceiver
che esegue un'attività in background in modo che l'azione non interrompa l'app già aperta.
In questo codelab, ti viene già fornito un BoadcastReceiver
denominato SnoozeReceiver
. Utilizzerai SnoozeReceiver
per ricevere il clic dell'utente sull'azione di notifica. Nei passaggi successivi aggiungerai il codice per posticipare la notifica del timer per uova di 60 secondi quando l'utente fa clic sul pulsante di azione di posticipo. Quando viene fatto clic sull'azione di posticipo, SnoozeReceiver
riceve un intent e crea una nuova sveglia per inviare una nuova notifica dopo 60 secondi.
- Apri
SnoozeReceiver.kt
. Questo corso è simile aAlarmReceiver
che hai utilizzato in precedenza. Nei passaggi seguenti aggiungerai il codice che attiverà la funzioneonReceive()
diSnoozeReceiver
. In breve, il codice inSnoozeReceiver
creerà un nuovo allarme per inviare una nuova notifica un minuto dopo. Scorri verso il basso fino alla fine della funzione onReceive, ottieni un'istanza di notificationManager dal sistema e chiama cancelAll.
// SnoozeReceiver.kt
val notificationManager = ContextCompat.getSystemService(
context,
NotificationManager::class.java
) as NotificationManager
notificationManager.cancelAll()
- Per utilizzare
SnoozeReceiver
, apriNotificationUtils.kt
. - Crea un nuovo
Intent
snoozeIntent
perSnoozeReceiver
subito dopo lo stile nella funzionesendNotification()
. - Crea un intent in attesa chiamando il metodo
getBroadcast()
suPendingIntent
, che prevede i parametri nei passaggi successivi. QuestoPendingIntent
verrà utilizzato dal sistema per impostare una nuova sveglia per pubblicare una nuova notifica dopo 60 secondi quando l'utente tocca il pulsante Posticipa. - Il primo parametro è il contesto dell'applicazione in cui questo
PendingIntent
deve avviare l'attività. - Il secondo parametro è il codice richiesta, ovvero il codice richiesta per questo intent in attesa. Se devi aggiornare o annullare questa intent in attesa, devi utilizzare questo codice per accedervi.
- Successivamente, aggiungi l'oggetto
snoozeIntent
, che è l'intent dell'attività da avviare. - Infine, aggiungi il valore del flag
#FLAG_ONE_SHOT
, poiché l'intent verrà utilizzato una sola volta. L'azione rapida e la notifica scompaiono dopo il primo tocco, motivo per cui l'intent può essere utilizzato una sola volta.
// NotificationUtils.kt
// TODO: Step 2.2 add snooze action
val snoozeIntent = Intent(applicationContext, SnoozeReceiver::class.java)
val snoozePendingIntent: PendingIntent = PendingIntent.getBroadcast(
applicationContext,
REQUEST_CODE,
snoozeIntent,
FLAGS
)
- Successivamente, chiama la funzione
addAction()
sunotificationBuilder
. Questa funzione prevede un'icona e un testo per descrivere l'azione all'utente. Devi anche aggiungere ilsnoozeIntent
. Questo intent verrà utilizzato per attivare ilboadcastReceiver
corretto quando viene fatto clic sull'azione.
// NotificationUtils.kt
// TODO: Step 2.3 add snooze action
.addAction(
R.drawable.egg_icon,
applicationContext.getString(R.string.snooze),
snoozePendingIntent
)
- Esegui l'app timer per testare l'azione di posticipo.
- Avvia il timer e metti l'app in background. Al termine del timer, espandi la notifica e vedrai che ora ha un pulsante di azione di posticipo che posticipa il timer per un altro minuto.
Passaggio 3: importanza delle notifiche
L'importanza determina il livello di interruzione visiva e uditiva della notifica per l'utente. Le notifiche con importanza maggiore saranno più intrusive per gli utenti.
Devi specificare il livello di importanza nel costruttore NotificationChannel
. Inizialmente hai impostato un livello di importanza basso per l'app timer. Puoi utilizzare uno dei cinque livelli di importanza, da IMPORTANCE_NONE(0)
a IMPORTANCE_HIGH(4)
. Il livello di importanza che assegni a un canale si applica a tutti i messaggi di notifica che pubblichi.
Livelli di importanza del canale
Livello di importanza visibile all'utente | Importanza (Android 8.0 e versioni successive) | Priorità (Android 7.1 e versioni precedenti) |
Emette un suono e viene visualizzata come notifica di avviso (nella parte superiore dello schermo) | ||
Emette un suono | ||
Nessun suono | ||
Nessun suono e non appare nella barra di stato |
Per informazioni sulla scelta di un livello di priorità appropriato, consulta la sezione "Livelli di priorità" nella Guida alla progettazione delle notifiche. Devi fare attenzione quando selezioni un livello di importanza per le notifiche nella tua app. L'importanza del canale deve essere scelta tenendo conto del tempo e dell'attenzione dell'utente. Quando una notifica non importante viene mascherata come urgente, può generare allarme inutile e distrarre. Gli utenti hanno il controllo completo del livello di importanza delle notifiche, quindi se crei una notifica fastidiosa, possono disattivare completamente il canale di notifica.
Quando hai creato la notifica per la prima volta nel passaggio 1.6, il timer era impostato per inviare notifiche con priorità bassa, in quanto progettato per non disturbare l'utente con le notifiche. Tuttavia, potrebbe essere una buona idea attirare l'attenzione dell'utente prima che l'uovo si cuocia troppo. Per modificare il livello di importanza della notifica, inizia con le impostazioni del canale. L'importanza del canale influisce sul livello di interruzione di tutte le notifiche pubblicate nel canale e deve essere specificata nel costruttore NotificationChannel
.
- Per modificare il livello di importanza del canale di notifica della tua app, apri
EggTimerFragment.kt
e vai acreateChannel()
. Modifica il livello di importanza daIMPORTANCE_LOW
aIMPORTANCE_HIGH
.
// EggTimerFragment.kt
val notificationChannel = NotificationChannel(
channelId,
channelName,
// TODO: Step 2.4 change importance
NotificationManager.IMPORTANCE_HIGH
)
Per supportare i dispositivi con Android 7.1 (livello API 25) o versioni precedenti, devi chiamare anche setPriority()
per ogni notifica, utilizzando una costante di priorità della classe NotificationCompat
.
- Apri
NotificationUtils.kt
e aggiungi quanto segue all'oggetto del generatore di notifiche.
// NotificationUtils.kt
.addAction(
R.drawable.common_google_signin_btn_icon_dark,
applicationContext.getString(R.string.snooze),
snoozePendingIntent
)
// TODO: Step 2.5 set priority
.setPriority(NotificationCompat.PRIORITY_HIGH)
- Prima di eseguire l'app, fai clic a lungo sull'icona dell'app sul dispositivo o sull'emulatore e seleziona Disinstalla per cancellare le impostazioni precedenti del canale. Se non riesci a disinstallare l'app, le impostazioni della priorità dei canali non cambieranno e non si verificherà alcuna modifica del comportamento quando la notifica viene pubblicata.
- Ora esegui di nuovo l'app e avvia il timer. Questa volta, quando la notifica viene inviata, dovresti vedere un popup nella parte superiore dello schermo, indipendentemente dal fatto che l'app sia in esecuzione in primo piano o in background.
Passaggio 4: badge delle notifiche
I badge delle notifiche sono piccoli puntini che vengono visualizzati sull'icona del launcher dell'app associata quando l'app ha una notifica attiva. Gli utenti possono premere a lungo l'icona dell'app per visualizzare le notifiche.
Questi punti, chiamati badge, vengono visualizzati per impostazione predefinita e non è necessario che la tua app faccia nulla. Tuttavia, potrebbero esserci situazioni in cui i badge non sono adatti alle tue notifiche, quindi puoi disattivarli per ogni canale chiamando setShowBadge(false)
sull'oggetto NotificationChannel
. Poiché il timer per uova ha una sola notifica attiva alla volta, il badge sull'icona dell'app non offre molti vantaggi per gli utenti. Nei passaggi successivi disattiverai il badge e mostrerai solo una notifica per il timer per uova.
- Aggiungi
setShowBadge(false)
al codice di creazione del canale per disattivare i badge del timer.
// EggTimerFragment.kt
).apply {
// TODO: Step 2.6 disable badges for this channel
setShowBadge(false)
}
- Esegui di nuovo l'app, avvia il timer e osserva l'icona dell'app. Non dovresti vedere badge sull'icona dell'app.
Il codice della soluzione si trova nel ramo master del codice scaricato.
- Utilizza la classe NotificationManager per creare, inviare, aggiornare e annullare una notifica.
- Utilizza un oggetto NotificationChannel con il metodo createNotificationChannel per impostare un canale per la notifica.
- Utilizza addAction() per aggiungere azioni rapide a una notifica.
- Utilizza setShowBadge() per attivare o disattivare i badge.
- Personalizza lo stile delle notifiche utilizzando stili che si estendono da Notification.Style
- Imposta il livello di importanza con NotificationChannel.setImportance().
Corso Udacity:
Documentazione per sviluppatori Android:
Per i link ad altri codelab di questo corso, consulta la pagina di destinazione dei codelab Advanced Android in Kotlin.