Utilizzare le notifiche Android

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.

Scarica zip

  1. 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.

  1. Esamina il codice sorgente. L'app iniziale è costituita da una singola attività denominata MainActivity. Esistono tre pacchetti secondari denominati receiver, ui e util.

  • /receiver: il pacchetto receiver contiene due ricevitori di trasmissione denominati AlarmReceiver e SnoozeReceiver. AlarmReceiver viene attivato da AlarmManager 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 e ViewModel. NotificationUtils.kt dispone di metodi di estensione su NotificationManager.

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.

  1. Apri il corso NotificationUtils.kt e trova TODO: Step 1.1. Troverai attività corrispondenti in questo codelab e nel codice dell'app.
  2. Esamina la funzione sendNotification() fornita. Stai estendendo questa funzione di estensione a NotificationManager 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) {
  1. 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)
)
  1. 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)
  1. Successivamente, devi chiamare notify() con un ID univoco per la notifica e con l'oggetto Notification 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())
  1. Apri ui/EggTimerViewModel.kt e trova la funzione startTimer(). Questa funzione crea una sveglia con l'intervallo di tempo selezionato quando l'utente attiva il timer per uova.
  2. 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 di NotificationManager. 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 di NotificationManager dal sistema. Chiama la funzione sendNotification()| 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.

  1. Apri logcat e cerca "No Channel found". Dovresti visualizzare un messaggio di errore che indica che egg_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.

  1. Apri EggTimerFragment.kt e trova la funzione createChannel().
  2. Passa l'ID canale univoco al costruttore di NotificationChannel.
  3. Passa il nome del canale di notifica, che gli utenti vedranno anche nella schermata Impostazioni.
  4. 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 NotificationManager.IMPORTANCE_LOW.
  5. Nell'oggetto notificationChannel imposta enableLights su true. Questa impostazione attiva le luci quando viene visualizzata una notifica.
  6. Imposta l'notificationChannel oggetto lightColor su rosso per visualizzare una luce rossa quando viene mostrata una notifica.
  7. Nell'oggetto notificationChannel imposta enableVibration su true per attivare la vibrazione.
  8. Nell'oggetto notificationChannel imposta la descrizione del canale su ‘Time for breakfast'.
  9. Ottieni un'istanza di NotificationManager chiamando il numero getSystemService().
  10. Chiama createNotificationChannel() su NotificationManager e passa l'oggetto notificationChannel 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
}
  1. 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)
    )
  1. 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)
)
  1. Esegui l'app e vedrai che invia una notifica ogni volta che avvii il timer.
  2. Trascina la barra di stato e osserva che il titolo, i contenuti e l'icona della notifica sono quelli impostati nei passaggi precedenti.
  3. 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.

  1. 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.

  1. Apri AlarmReceiver.kt, un'istanza di NotificationManager, e chiama la funzione sendNotification() 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
   )
  1. (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()
  1. 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.

  1. 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)
  1. Esegui di nuovo l'app.
  2. 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

  1. Esegui di nuovo l'app, se non è già in esecuzione.
  2. 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.

  1. Apri NotificationUtils.kt e trova la funzione di estensione sendNotification().
  2. Crea un Intent con il tuo applicationContext 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.

  1. Crea un PendingIntent con applicationContext, NOTIFICATION_ID, il contentIntent che hai creato nel passaggio precedente e il flag PendingIntent. Il flag PendingIntent specifica l'opzione per creare un nuovo PendingIntent o utilizzarne uno esistente. Devi impostare PendingIntent.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
    )
  1. Passa PendingIntent alla notifica. Per farlo, chiama setContentIntent() su NotificationBuilder. Ora, quando fai clic sulla notifica, viene attivato PendingIntent, che apre MainActivity.
  2. Imposta anche setAutoCancel() su true, 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)
  1. Esegui di nuovo l'app.
  2. Imposta un timer, metti l'app in background e attendi la visualizzazione della notifica.
  3. 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().

  1. Apri NotificationsUtil.kt.
  2. Aggiungi una funzione di estensione su NotificationManager che chiama cancelAll().
// NotificationUtils.kt

// TODO: Step 1.14 Cancel all notifications
/**
 * Cancels all notifications.
 *
 */
fun NotificationManager.cancelNotifications() {
    cancelAll()
}
  1. Apri EggTimerViewModel.kt e vai alla funzione startTimer().
  2. All'interno di startTimer(), recupera un'istanza di NotificationManager dal sistema e chiama cancelNotifications().
//  EggTimerViewModel.kt
   //TODO Step 1.15 call cancel notification
    val notificationManager =
       ContextCompat.getSystemService(
            app,
            NotificationManager::class.java
        ) as NotificationManager
    notificationManager.cancelNotifications()       
  1. Esegui l'app e avvia il timer.
  2. 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.

  1. Apri NotificationUtils.kt e trova la funzione sendNotification().
  2. Inizia caricando un'immagine da resources utilizzando BitmapFactory.
// NotificationUtils.kt

// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
     applicationContext.resources, 
     R.drawable.cooked_egg
)
  1. Crea un nuovo BigPictureStyle e imposta l'immagine.
  2. Imposta bigLargeIcon() su null 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)
  1. Imposta lo stile con setStyle() su bigPicStyle.
  2. Imposta l'icona grande con setLargeIcon() su eggImage, 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)
  1. 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.

  1. Apri SnoozeReceiver.kt. Questo corso è simile a AlarmReceiver che hai utilizzato in precedenza. Nei passaggi seguenti aggiungerai il codice che attiverà la funzione onReceive() di SnoozeReceiver. In breve, il codice in SnoozeReceiver 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()
  1. Per utilizzare SnoozeReceiver, apri NotificationUtils.kt.
  2. Crea un nuovo Intent snoozeIntent per SnoozeReceiver subito dopo lo stile nella funzione sendNotification().
  3. Crea un intent in attesa chiamando il metodo getBroadcast() su PendingIntent, che prevede i parametri nei passaggi successivi. Questo PendingIntent verrà utilizzato dal sistema per impostare una nuova sveglia per pubblicare una nuova notifica dopo 60 secondi quando l'utente tocca il pulsante Posticipa.
  4. Il primo parametro è il contesto dell'applicazione in cui questo PendingIntent deve avviare l'attività.
  5. 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.
  6. Successivamente, aggiungi l'oggetto snoozeIntent, che è l'intent dell'attività da avviare.
  7. 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
)
  1. Successivamente, chiama la funzione addAction() su notificationBuilder. Questa funzione prevede un'icona e un testo per descrivere l'azione all'utente. Devi anche aggiungere il snoozeIntent. Questo intent verrà utilizzato per attivare il boadcastReceiver 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
)
  1. Esegui l'app timer per testare l'azione di posticipo.
  2. 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)

IMPORTANCE_HIGH

PRIORITY_HIGH / PRIORITY_MAX

Emette un suono

IMPORTANCE_DEFAULT

PRIORITY_DEFAULT

Nessun suono

IMPORTANCE_LOW

PRIORITY_LOW

Nessun suono e non appare nella barra di stato

IMPORTANCE_MIN

PRIORITY_MIN

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.

  1. Per modificare il livello di importanza del canale di notifica della tua app, apri EggTimerFragment.kt e vai a createChannel(). Modifica il livello di importanza da IMPORTANCE_LOW a IMPORTANCE_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.

  1. 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)
  1. 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.
  2. 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.

  1. 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)
    }
  1. 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.

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.