Usare le notifiche di Android

Questo codelab fa parte del corso Advanced Android in Kotlin. Otterrai il massimo valore da questo corso se lavori in sequenza nei codelab, ma non è obbligatorio. Tutti i codelab del corso sono elencati nella pagina di destinazione avanzata per i codelab di Android in Kotlin.

Introduzione

Le notifiche sono messaggi che vengono mostrati all'utente al di fuori dell'interfaccia utente della tua app. Le notifiche vengono mostrate nella parte superiore dello schermo se il dispositivo è sbloccato o, a seconda delle impostazioni di sicurezza, nella schermata di blocco quando il dispositivo è bloccato.

In genere una notifica è composta da un titolo, una descrizione e un'icona. Una notifica può anche contenere azioni cliccabili, una risposta rapida, contenuti espandibili e immagini.

Le notifiche possono inviare materiale tempestivo e possono includere pulsanti che consentono all'utente di eseguire azioni rapide, come inviare una risposta o posticipare la sveglia. Quando fa clic su una notifica, l'utente viene indirizzato a una visualizzazione della tua app correlata ai contenuti della notifica.

Le notifiche sono un modo utile per ricordare agli utenti un'attività importante, far loro sapere che si è verificata un'attività o comunicare informazioni importanti di cui hanno bisogno immediatamente quando la tua app è in background. Utilizza le notifiche con moderazione. In questo modo, non solo vengono rispettati gli utenti, ma è anche più probabile che le notifiche della tua app ricevano l'attenzione che merita.

In questo codelab, imparerai a creare e utilizzare le notifiche in un'app Android.

Informazioni importanti

Dovresti acquisire familiarità con:

  • Come creare app Android in Kotlin. In particolare, puoi usare l'SDK Android.
  • Come creare architetture di app utilizzando i componenti dell'architettura e l'associazione di dati.
  • Nozioni di base su BroadcastReceiver
  • Conoscenza di base di AlarmManager

Obiettivi didattici

  • Come creare, modificare lo stile e inviare una notifica.
  • Come annullare le notifiche.
  • Come creare canali di notifica.
  • Come aggiungere azioni rapide alle notifiche.
  • Come mostrare i badge di notifica sull'icona dell'app.

In questo lab proverai a:

  • Aggiungi una notifica all'app iniziale.
  • Annulla la notifica inviata in precedenza.
  • Creare canali per diversi tipi di notifiche.
  • Personalizza le notifiche nell'app iniziale.
  • Aggiungi Azioni rapide per rendere interattiva la tua notifica.
  • Disattiva i badge di notifica.

Preparare le uova è semplice, ma può risultare un compito difficile se non monitori il tempo. In questo codelab, lavorerai a un'app timer per le uova e la renderai perfetta, proprio come le tue uova future. Inizierai con un'app per timer delle uova che funziona, che consente all'utente di impostare diverse impostazioni dei tempi di cottura per diversi stili di uova. Il timer esegue il conto alla rovescia dall'intervallo di tempo selezionato e mostra un messaggio toast quando le uova sono pronte.

Può sembrare funzionale, ma non è affatto perfetto e non è davvero 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 c'è alcun indicatore visivo per lo stato del timer una volta che il messaggio toast scompare.

Idealmente, il timer per le uova deve utilizzare le notifiche per comunicare agli utenti quando scade il tempo. L'utente deve sapere che le uova sono pronte immediatamente, altrimenti le uova saranno cotte troppo a lungo. Le notifiche sono visive, possono includere suoni e possono far vibrare il dispositivo: sono tutti modi per catturare l'attenzione dell'utente. In questo modo puoi raggiungere uova perfette e utenti soddisfatti e felici.

Per scaricare l'app di esempio, puoi:

Clona il repository da GitHub e passa al ramo 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 dell'uovo e un menu a discesa con un elenco di intervalli di tempo predefiniti per cucinare un uovo. Fai clic sul triangolo del menu a discesa Bollate. La prima opzione nell'elenco viene fornita a scopo di test e imposta la sveglia su soli 10 secondi. Accanto all'elenco c'è un interruttore che avvia il timer delle uova. Puoi usare questo sensore per avviare e interrompere il timer quando vuoi. Il codice di avvio è completamente funzionale, il che significa che puoi impostare il timer per le uova e guardare il conto alla rovescia fino a 0. Al termine del timer, viene visualizzato un messaggio di avviso, come mostrato di seguito.

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

  • /recipientr: il pacchetto receiver contiene due ricevitori broadcast denominati AlarmReceiver e SnoozeReceiver. AlarmReceiver viene attivato da AlarmManager per inviare una notifica allo scadere del timer definito dall'utente. SnoozeReceiver gestisce l'utente con un clic per posticipare la notifica.
  • /ui: contiene la EggTimerFragment che fa parte della parte dell'app dell'app. EggTimerViewModel è responsabile dell'avvio e dell'annullamento del timer e di altre attività delle app correlate al ciclo di vita.
  • /util: in questo pacchetto sono presenti due file. BindingUtils.kt dispone di adattatori di associazione per consentire l'associazione di dati tra l'interfaccia utente dell'app e ViewModel. NotificationUtils.kt offre metodi di estensione in NotificationManager.

L'utilizzo delle notifiche è un ottimo modo per attirare l'attenzione degli utenti sulla tua app. Se la tua app non è in esecuzione o 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 uno strumento per la creazione di notifiche e fornire un testo del titolo, un testo dei contenuti e un'icona. Se lo strumento di creazione ha tutti i campi necessari, NotificationManager, che è un servizio di sistema, ti aiuta a mostrare questi contenuti sotto forma di notifica. NotificationManager è responsabile di inviare una notifica, aggiornarne i contenuti e annullarla. Nei seguenti passaggi, aggiungerai metodi di estensione a NotificationManager. In questo modo, ogni volta che devi utilizzare NotificationManager, sarai in grado di utilizzare queste funzioni di estensione per ottenere la funzionalità necessaria.

Passaggio 1: crea una notifica di base

In questa attività dovrai creare una nuova notifica, impostare un messaggio per l'utente e inviare la notifica.

  1. Apri il corso NotificationUtils.kt e trova TODO: Step 1.1. In questo codelab e nel codice dell'app troverai le cose da fare corrispondenti.
  2. Esamina la funzione sendNotification() specificata. Puoi estendere 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, trasmetti 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 di notifiche simili, gli sviluppatori e gli 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 per rappresentare la tua app, un titolo e il testo dei contenuti del messaggio che vuoi inviare all'utente. Vedrai più opzioni per personalizzare ulteriormente la notifica nel codelab, ma questa è la quantità minima di dati che devi impostare per poter 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 ha una sola notifica attiva alla volta, puoi utilizzare lo stesso ID per tutte le notifiche. Hai già una costante per questo scopo chiamata NOTIFICATION_ID in NotificationUtils.kt. Tieni presente che puoi chiamare direttamente notify() dato che stai eseguendo la chiamata da una funzione di estensione della 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 in cui l'utente attiva il timer per le uova.
  2. Quando l'utente avvia il timer, viene attivata una notifica in questa funzione. Per chiamare la funzione sendNotification() che hai implementato in precedenza, è necessaria un'istanza di NotificationManager. NotificationManager è un servizio di sistema che fornisce tutte le funzioni esposte per l'API Notifications, inclusa la funzione estensione aggiunta. Ogni volta che vuoi inviare, annullare o aggiornare una notifica, devi richiedere al sistema un'istanza di NotificationManager. Chiama la funzione sendNotification()|con il messaggio di notifica e 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)

Hai quasi finito. Tuttavia, se esegui l'app adesso e imposti il timer, non riceverai una notifica.

  1. Apri logcat e cerca "No Channel found". Dovrebbe essere visualizzato un messaggio di errore che indica che egg_channel non esiste. Nei passaggi che seguono puoi scoprire di più sui Canali di notifica e risolvere 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 in Avvio applicazioni, seleziona Informazioni sull'app e tocca Notifiche, viene visualizzato un elenco di canali di notifica associati all'app. Al momento l'elenco è vuoto perché la tua app non ha creato canali.

I canali rappresentano una notifica "ad esempio", ad esempio il tuo timer delle uova può inviare una notifica quando l'uovo è cotto e un altro canale può inviarti notifiche giornaliere per ricordarti di bere uova con la tua colazione. Tutte le notifiche di un canale vengono 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 di loro interesse. Ad esempio, i tuoi utenti possono disattivare le notifiche relative alla colazione, ma scegliere comunque di riceverle dal timer.

Gli sviluppatori definiscono le impostazioni iniziali, l'importanza e il comportamento, da applicare a tutte le notifiche di un canale. Dopo che hai configurato le impostazioni iniziali, gli utenti possono ignorarle.

Nel passaggio 1.1 hai utilizzato egg_notification_channel_id come canale di notifica, pertanto 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. Trasmettere il nome del canale di notifica, che verrà visualizzato anche nella schermata Impostazioni.
  4. Come ultimo parametro, trasmetti il livello di importanza per il canale di notifica. I livelli di importanza saranno illustrati in seguito in questo codelab, quindi per ora puoi utilizzare NotificationManager.IMPORTANCE_LOW.
  5. Nell'oggetto notificationChannel è impostato enableLights su true. Questa impostazione abilita le luci quando viene mostrata una notifica.
  6. Sull'oggetto notificationChannel imposta lightColor su rosso per mostrare una luce rossa quando viene visualizzata una notifica.
  7. Sull'oggetto notificationChannel è impostato enableVibration true per attivare la vibrazione.
  8. Nell'oggetto notificationChannel imposta la descrizione del canale su ‘Time for breakfast'.
  9. Ricevi un'istanza di NotificationManager chiamando 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. Il passaggio successivo consiste nel creare un canale, richiamare la funzione createChannel() appena scritta (Passaggio 1.7). Questa funzione prevede due parametri: l'ID e il nome del canale. Devi cercare l'ID e il nome del canale nelle risorse stringa già fornite nel tuo 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. Hai già eseguito questa operazione nel passaggio 1.2. Se imposti un valore errato come ID canale, la notifica avrà esito negativo. 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: ogni volta che avvii il timer, l'app invia una notifica.
  2. Trascina la barra di stato e osserva che il titolo, il contenuto e l'icona della notifica sono quelli che hai impostato nei passaggi precedenti.
  3. Per verificare il canale appena creato, chiudi l'app e cerca l'icona dell'app. Tocca a lungo l'icona dell'app e seleziona Informazioni app.

  1. Seleziona Notifiche dall'elenco delle impostazioni. Dovresti vedere un nuovo canale chiamato Uovo, subito sotto l'impostazione Mostra notifiche.

Quando esegui l'app, viene visualizzata la notifica. Sia tu che lo sviluppatore dell'app sia i vostri utenti potete personalizzare le impostazioni e il comportamento per tutte le notifiche inviate su questo canale. Complimenti, hai creato una notifica.

Passaggio 3: aggiungi notifiche all'app

Finora mostra l'utilizzo di base dell'API Notifications, ma l'invio di una notifica subito dopo l'avvio del timer non ha molto senso. È probabile che gli utenti preferiscano ricevere una notifica quando l'uovo è pronto. Nella parte seguente del codelab, correggi questo problema e modifichi il messaggio di toast in una notifica.

Hai già inviato la notifica e hai osservato come viene visualizzata dagli utenti, ma questo è stato solo il primo passaggio per creare notifiche efficaci. In questo passaggio modificherai la notifica inviata per renderla più appropriata.

La tua app utilizza AlarmManager per configurare una sveglia. Il codice correlato a AlarmManager è già fornito nel codice di avvio e viene utilizzato per mostrare il messaggio toast. AlarmManager tiene traccia della selezione dell'ora desiderata e attiverà la funzione onReceive() di AlarmReceiver.kt allo scadere del tempo. Se apri AlarmReceiver.kt e accedi a onReceive(), dovresti vedere il messaggio toast visualizzato ogni volta che configuri un timer per le 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 toast perché l'app invierà una notifica allo scadere del timer.
// AlarmReceiver.kt
     // TODO: Step 1.10 [Optional] remove toast
//   Toast.makeText(
//       context, 
//       context.getText(R.string.eggs_ready),
//       Toast.LENGTH_SHORT
//   ).show()
  1. Esegui la tua app . Ogni volta che avvii il timer, dovrebbe essere visualizzata una notifica ogni volta che viene avviato.

Non è l'ideale. Non vuoi inviare troppe notifiche ai tuoi utenti. Puoi rimuovere la prima notifica che viene inviata quando l'utente avvia il timer.

  1. Apri EggTimerFragment.kt e rimuovi il codice di notifica del 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, inseriscilo in background e attendi il termine dell'operazione. Visualizzerai una notifica. Questa è una notifica molto più utile.

Passaggio 4: aggiungi un intent per i contenuti

  1. Esegui di nuovo l'app, se non è già in esecuzione.
  2. Fai clic sulla notifica. Non succede niente!

È meglio mostrare la notifica e informare l'utente, ma quando un utente fa clic su una notifica, si aspetta di tornare all'app corrispondente. In questa parte del codelab aggiungerai un'intenzione alla tua notifica per riportare l'utente alla schermata del timer.

Un Intent è un oggetto di messaggistica che puoi utilizzare per richiedere un'azione da un altro componente dell'app. Gli intent possono essere utilizzati per avviare un'attività, un servizio o l'invio di un broadcast. In questo caso, devi utilizzare questo intento per indicare al sistema di aprire MainActivity quando l'utente tocca la notifica. Poiché l'app è composta da un'unica vista, non hai molte opzioni. Tuttavia, in un'app più grande, la notifica dovrebbe creare un'esperienza fluida, portando l'utente su uno schermo appropriato per l'interazione.

  1. Apri NotificationUtils.kt e individua la funzione dell'estensione sendNotification().
  2. Crea un Intent con il tuo applicationContext e l'attività da lanciare, 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 all'esterno dell'app. Per far funzionare un intent all'esterno dell'app, devi creare una nuova PendingIntent.

PendingIntent concede diritti a un'altra applicazione o al sistema per eseguire un'operazione per conto della tua applicazione. Un PendingIntent stesso è semplicemente un riferimento a un token gestito dal sistema che descrive i dati originali utilizzati per recuperarlo. Ciò significa che, anche se il processo della sua applicazione viene interrotto, il 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, 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'elemento PendingIntent corrente associato all'intent fornito.
// NotificationUtils.kt
   // TODO: Step 1.12 create PendingIntent
    val contentPendingIntent = PendingIntent.getActivity(
        applicationContext, 
        NOTIFICATION_ID,
        contentIntent,
        PendingIntent.FLAG_UPDATE_CURRENT
    )
  1. Passa il PendingIntent alla tua notifica. Per farlo, chiama setContentIntent() al numero NotificationBuilder. Ora, quando fai clic sulla notifica, verrà attivato PendingIntent, che apre MainActivity.
  2. Imposta inoltre setAutoCancel() su true, in modo che, quando l'utente tocca la notifica, la notifica si concluda man mano che si sposta nell'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. Quando vedi la notifica, fai clic sulla notifica tirando verso il basso la barra di stato e osserva come l'app viene portata in primo piano.

Passaggio 5: annulla la notifica

Hai un timer funzionale per le uova con le 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. Ciò può confondere l'utente se l'app è in background e le uova potrebbero essere poco cotte.

Per risolvere il problema, devi cancellare la notifica precedente quando avvii un nuovo timer. Inizia creando un'altra funzione di estensione nel tuo NotificationUtils.kt. NotificationManager dispone di un'API per annullare tutte le notifiche attive chiamate cancelAll().

  1. Apri NotificationsUtil.kt.
  2. Aggiungi una funzione estensione su NotificationManager che chiami 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. Quando ricevi 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 notifiche offre diverse opzioni di personalizzazione per consentire agli sviluppatori di impostare azioni personalizzate e modificare le proprie notifiche secondo necessità. Durante questa attività, imparerai a personalizzare le notifiche del timer delle uova.

Passaggio 1: applica uno stile alla notifica

Gli stili della notifica in base alle tue esigenze e i contenuti della notifica contraddistinguono la tua attività e assomigliano a un'estensione della tua applicazione. Il framework di notifiche è dotato di diversi stili integrati che ti permettono di crearne uno personalizzato.

NotificationCompat offre stili incorporati per:

  • BigTextStyle, che può mostrare un blocco di testo di grandi dimensioni, ad esempio può mostrare i contenuti di un'email quando viene espansa.
  • BigPictureStyle, che mostra notifiche di grande formato che includono un allegato con un'immagine di grandi dimensioni.
  • InboxStyle, che mostra un contenuto testuale in stile conversazione.
  • MediaStyle, che mostra i controlli per la riproduzione di contenuti multimediali.
  • MessagingStyle, che mostra notifiche di grande formato che includono più messaggi tra un numero di persone qualsiasi.

Puoi trovare ulteriori informazioni su altri stili nella documentazione relativa alla creazione di una notifica espandibile. In questo passaggio, utilizzerai NotificationCompat.BigPictureStyle per creare una notifica espandibile che mostra 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 elemento BigPictureStyle e imposta la tua 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 viene compressa la notifica.
// 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 mostrata per la prima volta, si trova nello stato compresso nel riquadro di notifica. Se espandi la notifica, nell'area di notifica estesa viene visualizzata un'immagine grande.

Passaggio 2: azioni di notifica

Le azioni di notifica sono un'altra personalizzazione che puoi aggiungere alle notifiche. Le notifiche attualmente reindirizzano alla tua app quando gli utenti 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 SMS. Questi pulsanti di azione non devono duplicare l'azione eseguita quando l'utente tocca la notifica.

Per aggiungere un pulsante di azione, passa un elemento PendingIntent alla funzione addAction() nel generatore. È simile alla configurazione dell'azione predefinita relativa alle notifiche tramite tocco chiamando setContentIntent(), ad eccezione del fatto che viene avviata un'attività, ad esempio puoi avviare una BroadcastReceiver che esegue un lavoro in background in modo che l'azione non interrompa l'app già aperta.

In questo codelab, ti è già stato assegnato un nome BoadcastReceiver (SnoozeReceiver). Utilizzerai il dispositivo SnoozeReceiver per ricevere il clic dell'utente sull'azione di notifica. Nei passaggi seguenti, puoi aggiungere codice per posticipare la notifica del timer 60 secondi quando l'utente fa clic sul pulsante di azione. Quando viene fatto clic sull'azione, la 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 codice che attiverà la funzione onReceive() di SnoozeReceiver. In breve, il codice di SnoozeReceiver creerà una nuova sveglia per inviare una nuova notifica un minuto dopo. Scorri verso il basso della funzione onReceive, attiva l'istanza di notificationManager dal sistema e chiama callAll.
// 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 seguenti. Questo PendingIntent verrà utilizzato dal sistema per impostare una nuova sveglia in modo da pubblicare una nuova notifica dopo 60 secondi quando l'utente tocca il pulsante per posticipare la sveglia.
  4. Il primo parametro è il contesto dell'applicazione in cui questo PendingIntent dovrebbe avviare l'attività.
  5. Il secondo parametro è il codice di richiesta, ovvero il codice di richiesta per questo intent in sospeso. Se devi aggiornare o annullare questo intent in sospeso, devi utilizzare questo codice per accedere all'intent in attesa.
  6. A questo punto, aggiungi l'oggetto snoozeIntent, che è lo scopo dell'attività da avviare.
  7. Infine, aggiungi il valore 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 snoozeIntent. Questo intent verrà utilizzato per attivare il boadcastReceiver giusto quando viene fatto clic sulla tua 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 uova per testare l'azione di posticipazione.
  2. Avvia il timer e inserisci l'app in background. Una volta scaduto il timer, espandi la notifica e vedrai che la notifica ora include un pulsante di azione che posticipa il timer di un altro minuto.

Passaggio 3: importanza delle notifiche

L'importanza determina in che misura la notifica dovrebbe interrompere l'utente in modo visivo e udibile. Le notifiche con maggiore importanza saranno più fastidiose per gli utenti.

Devi specificare il livello di importanza nel costruttore NotificationChannel. Hai impostato un'importanza bassa per l'app Timer uova. Puoi utilizzare uno dei cinque livelli di importanza compresi tra IMPORTANCE_NONE(0) e IMPORTANCE_HIGH(4). Il livello di importanza assegnato 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 visualizzato come notifica (compare nella parte superiore dello schermo)

IMPORTANCE_HIGH

PRIORITY_HIGH/PRIORITY_MAX

Viene riprodotto un suono

IMPORTANCE_DEFAULT

PRIORITY_DEFAULT

Nessun suono

IMPORTANCE_LOW

PRIORITÀ_BASSA

Nessun suono e non viene visualizzato nella barra di stato

IMPORTANCE_MIN

PRIORITÀ_MIN

Per informazioni sulla scelta di un livello di priorità appropriato, consulta "Livelli di priorità" nella guida alla progettazione delle notifiche. Presta attenzione quando selezioni un livello di importanza per le notifiche nella tua app. L'importanza del canale deve essere scelta tenendo in considerazione il tempo e l'attenzione dell'utente. Quando una notifica non importante viene nascosta come urgente, può produrre un allarme non necessario 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 nel passaggio 1.6, il timer dell'uovo è stato impostato per inviare notifiche con priorità bassa, in quanto è stato progettato per non disturbare l'utente. Tuttavia, potrebbe essere una buona idea attirare l'attenzione dell'utente prima che le uova si finiscano. Per modificare il livello di importanza della notifica, inizia dalle 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 dell'app, apri EggTimerFragment.kt e vai a createChannel(). Cambia 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 precedenti, devi anche chiamare 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 disinstalli l'app, le impostazioni della priorità dei canali non subiranno modifiche e questo non comporterà alcun cambiamento al comportamento della notifica.
  2. Ora esegui di nuovo l'app e avvia il timer. Questa volta, quando la notifica viene recapitata, 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 di notifica

I badge di notifica sono piccoli puntini che vengono visualizzati sull'icona di Avvio app 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 è necessaria alcuna azione da parte dell'app. Tuttavia, potrebbero verificarsi situazioni in cui i badge non hanno senso per le tue notifiche, pertanto puoi disattivarle in base al canale chiamando setShowBadge(false) sul tuo oggetto NotificationChannel. Dal momento che il timer delle uova ha una sola notifica attiva alla volta, il badge sull'icona dell'app non è molto utile per gli utenti. Nei passaggi seguenti disattiverai il badge e visualizzerai solo una notifica per il timer dell'uovo.

  1. Aggiungi setShowBadge(false) al codice di creazione del canale per il timer uova per disattivare i badge.
// EggTimerFragment.kt

    ).apply {
        // TODO: Step 2.6 disable badges for this channel
        setShowBadge(false)
    }
  1. Esegui di nuovo l'app, avvia il timer e controlla l'icona dell'app. Non dovresti visualizzare alcun badge sull'icona dell'app.

Il codice della soluzione si trova nel ramo master del codice scaricato.

Corso Udacity:

Documentazione per gli sviluppatori Android:

Per i link ad altri codelab in questo corso, consulta la pagina di destinazione Advanced Android in Kotlin.