Dieses Codelab ist Teil des Kurses „Advanced Android in Kotlin“. Sie profitieren von diesem Kurs, wenn Sie die Codelabs nacheinander durcharbeiten. Das ist aber nicht zwingend erforderlich. Alle Kurs-Codelabs finden Sie auf der Landingpage für Codelabs auf Android-Geräten für Fortgeschrittene.
Einführung
Benachrichtigungen sind Nachrichten, die Nutzern außerhalb der App angezeigt werden. Benachrichtigungen werden oben auf dem Bildschirm angezeigt, wenn das Gerät entsperrt ist. Je nach Sicherheitseinstellungen wird der Sperrbildschirm auf dem Sperrbildschirm angezeigt.
Eine typische Benachrichtigung besteht aus einem Titel, einer Beschreibung und einem Symbol. Eine Benachrichtigung kann auch anklickbare Aktionen, eine schnelle Antwort, erweiterbare Inhalte und Bilder enthalten.
Benachrichtigungen können rechtzeitig versendet werden und über Schaltflächen verfügen, über die Nutzer schnell Aktionen ausführen können, wie etwa als Antwort senden oder die Schlummerfunktion für Wecker aktivieren. Durch Klicken auf eine Benachrichtigung wird der Nutzer zu einer Ansicht in Ihrer App weitergeleitet, in der es um den Benachrichtigungsinhalt geht.
Benachrichtigungen sind eine gute Möglichkeit, um Nutzer an eine wichtige Aufgabe zu erinnern, sie darüber zu informieren oder etwas Wichtiges zu vermitteln, während Ihre App im Hintergrund ausgeführt wird. Sie sollten Benachrichtigungen sparsam verwenden. Dadurch wird nicht nur die Wahrnehmung von Nutzern gewahrt, sondern auch die Wahrscheinlichkeit erhöht, dass ihre Benachrichtigung die Aufmerksamkeit erhält, die sie verdient.
In diesem Codelab lernen Sie, wie Sie Benachrichtigungen in einer Android-App erstellen und verwenden.
Was Sie bereits wissen sollten
Sie sollten mit Folgendem vertraut sein:
- Android-Apps in Kotlin erstellen Das ist insbesondere mit dem Android SDK möglich.
- Hier erfahren Sie, wie Sie Anwendungen mithilfe der Architekturkomponenten und der Datenbindung erstellen.
- Grundlegendes Verständnis von BroadcastReceiver
- Grundlegendes Verständnis von AlarmManager
Lerninhalte
- Benachrichtigungen erstellen, gestalten und senden
- Benachrichtigungen kündigen
- Benachrichtigungskanäle erstellen
- Schnellaktionen für Benachrichtigungen hinzufügen
- Benachrichtigungslogos auf dem App-Symbol anzeigen
Aufgaben
- Benachrichtigung zur Starter-App hinzufügen
- Brechen Sie die zuvor gesendete Benachrichtigung ab.
- Kanäle für verschiedene Arten von Benachrichtigungen erstellen
- Benutzerdefinierte Benachrichtigungen in der App starten
- Füge Kurzaktionen hinzu, um deine Benachrichtigung interaktiv zu gestalten.
- Benachrichtigungslogos deaktivieren
Das Kochen von Eiern ist ganz einfach, aber schwierig, wenn man die Zeit nicht verfolgt. In diesem Codelab arbeitest du an einer Ei-Timer-App und kreiere sie genau wie deine zukünftigen Eier. Du beginnst mit einer funktionierenden Ei-Timer-App, mit der der Nutzer verschiedene Einstellungen für die Kochzeit verschiedener Eierarten festlegen kann. Der Timer zählt vom ausgewählten Zeitintervall ab und zeigt eine Toast-Nachricht an, wenn die Eier bereit sind.
Auf den ersten Blick scheint das sicher zu sein, doch er ist alles andere als perfekt und nicht wirklich nutzerfreundlich. Die Toast-Meldung erscheint anfangs nur für kurze Zeit, sodass sie leicht übersehen werden kann. Wenn sich die App nicht im Vordergrund befindet oder das Gerät gesperrt ist, wird der Timer-Status durch eine visuelle Anzeige nicht mehr angezeigt.
Idealerweise sollten die Eiuhr per Benachrichtigung benachrichtigt werden, wenn die Zeit um ist. Der Nutzer muss sofort wissen, dass die Eier bereit sind. Benachrichtigungen sind gut sichtbar, können Töne enthalten und können das Gerät vibrieren lassen. So kannst du auf jeden Fall die Aufmerksamkeit des Nutzers erregen. So kannst du perfekte Eier und zufriedene Nutzer ernähren.
Sie haben folgende Möglichkeiten, die Beispiel-App abzurufen:
Klonen Sie das Repository aus GitHub und wechseln Sie zum Zweig starter.
$ git clone https://github.com/googlecodelabs/android-kotlin-notifications
Alternativ können Sie das Repository als ZIP-Datei herunterladen, entpacken und in Android Studio öffnen.
- Öffne die App und führe sie in Android Studio aus.
Sie sehen ein Ei-Bild und ein Drop-down-Menü mit einer Liste vordefinierter Zeitintervalle, in denen ein Ei zubereitet wird. Klicke auf das Dreieck für das Drop-down-Menü Soft Soiled. Die erste Option in der Liste ist zu Testzwecken gedacht und stellt den Wecker auf nur zehn Sekunden. Neben der Liste befindet sich ein Schalter, der den Ei-Timer startet. Mit diesem Schalter können Sie den Ei-Timer jederzeit starten und stoppen. Der Starter-Code ist voll funktionsfähig. Sie können also den Ei-Timer einrichten und sehen, dass er auf null zurückgesetzt wird. Sobald der Timer abgeschlossen ist, wird eine Toast-Meldung angezeigt, wie unten dargestellt.
- Prüfen Sie den Quellcode. Die Starter-App besteht aus einer einzelnen Aktivität namens
MainActivity
. Es gibt drei Unterpakete namensreceiver
,ui
undutil
.
- /empfänger: Das Paket
receiver
enthält zwei Übertragungsempfänger:AlarmReceiver
undSnoozeReceiver
.AlarmReceiver
wird vonAlarmManager
ausgelöst, um die Benachrichtigung zu senden, wenn der benutzerdefinierte Timer abgelaufen ist.SnoozeReceiver
behandelt den Klick des Nutzers, um die Benachrichtigung zurückzustellen. - /ui: Enthält den
EggTimerFragment
, der Teil der UI der App ist.EggTimerViewModel
ist dafür verantwortlich, den Timer zu starten und abzubrechen und andere Lebenszyklus-App-Aufgaben auszuführen. - /util: Dieses Paket enthält zwei Dateien.
BindingUtils.kt
hat Bindungsadapter, um die Datenbindung zwischen der App-UI und derViewModel
zu aktivieren.NotificationUtils.kt
hat Erweiterungsmethoden für dasNotificationManager
.
Benachrichtigungen sind eine gute Möglichkeit, die Aufmerksamkeit der Nutzer auf Ihre App zu lenken. Ob Ihre App nicht im Vordergrund ausgeführt wird oder nicht, stattdessen zeigt eine Benachrichtigung oben im Bildschirm ein Pop-up-Fenster an, das möglicherweise Ton oder Vibrationen enthält. Zum Erstellen einer Benachrichtigung müssen Sie ein Benachrichtigungs-Builder verwenden und einen Titeltext, einen Inhaltstext und ein Symbol angeben. Sobald alle relevanten Felder im Tool erstellt wurden, können Sie mithilfe des Systemdienstes NotificationManager
diesen Inhalt anzeigen. NotificationManager
ist dafür verantwortlich, eine Benachrichtigung zu senden, deren Inhalt zu aktualisieren und die Benachrichtigung abzubrechen. In den folgenden Schritten fügen Sie die Erweiterungsmethoden in NotificationManager
hinzu. So können Sie bei jeder Verwendung von NotificationManager
diese Erweiterungsfunktionen verwenden, um die erforderlichen Funktionen zu nutzen.
Schritt 1: Grundlegende Benachrichtigung erstellen
In dieser Aufgabe erstellen Sie eine neue Benachrichtigung, legen eine Nachricht für Ihren Nutzer fest und senden die Benachrichtigung.
- Öffnen Sie den Kurs
NotificationUtils.kt
und suchen Sie nachTODO: Step 1.1
. In diesem Codelab und im App-Code finden Sie passende Aufgaben. - Sehen Sie sich die angegebene
sendNotification()
-Funktion an. Erweitern Sie diese Erweiterungsfunktion aufNotificationManager
, um Benachrichtigungen zu senden.
//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) {
- Erstelle eine Instanz des Builders für Benachrichtigungen, übergib den App-Kontext und eine Kanal-ID. Die Kanal-ID ist ein Stringwert für den Kanal.
Über Benachrichtigungskanäle lassen sich Benachrichtigungen gruppieren. Durch die Gruppierung ähnlicher Benachrichtigungen können Entwickler und Nutzer alle Benachrichtigungen im Kanal verwalten. Sobald ein Kanal erstellt wurde, kann er für beliebig viele Benachrichtigungen verwendet werden.
//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)
)
- Legen Sie das Benachrichtigungssymbol fest, das Ihre App, einen Titel und den Inhaltstext für die Mitteilung darstellt, die Sie dem Nutzer vermitteln möchten. Im Codelab sehen Sie weitere Optionen, mit denen Sie Ihre Benachrichtigung weiter anpassen können. Das ist aber die Mindestmenge an Daten, die festgelegt werden muss, bevor eine Benachrichtigung gesendet werden kann.
//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)
- Als Nächstes rufen Sie
notify()
mit einer eindeutigen ID für die Benachrichtigung und demNotification
-Objekt Ihres Builders auf.
Die ID stellt die aktuelle Benachrichtigungsinstanz dar. Sie wird benötigt, um diese Benachrichtigung zu aktualisieren oder abzubrechen. Da Ihre App immer nur eine aktive Benachrichtigung hat, können Sie für alle Benachrichtigungen dieselbe ID verwenden. Sie haben bereits eine Konstante mit dem Namen NOTIFICATION_ID
in NotificationUtils.kt
erhalten. Sie können notify()
direkt aufrufen, da Sie den Aufruf über eine Erweiterungsfunktion in derselben Klasse ausführen.
//NotificationUtils.kt
// TODO: Step 1.4 call notify to send the notification
// Deliver the notification
notify(NOTIFICATION_ID, builder.build())
- Öffne
ui/EggTimerViewModel.kt
und suche die FunktionstartTimer()
. Diese Funktion erstellt einen Alarm mit dem ausgewählten Zeitintervall, wenn der Nutzer den Ei-Timer aktiviert. - Sie lösen in dieser Funktion eine Benachrichtigung aus, wenn der Nutzer den Timer startet. Zum Aufrufen der zuvor implementierten Funktion
sendNotification()
benötigst du eine Instanz vonNotificationManager
.NotificationManager
ist ein Systemdienst, der alle Funktionen bereitstellt, die für die Notifications API verfügbar sind. Dazu gehören auch die von Ihnen hinzugefügten Erweiterungsfunktionen. Wenn Sie eine Benachrichtigung senden, stornieren oder aktualisieren möchten, müssen Sie jederzeit eine Instanz vonNotificationManager
anfordern. Rufe die FunktionsendNotification()|
mit der Benachrichtigung und mit dem Kontext auf.
// 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)
Du hast es fast geschafft. Wenn du deine App jetzt startest und den Timer stellst, erhältst du keine Benachrichtigung.
- Öffne
logcat
und suche nach"No Channel found"
. Es wird eine Fehlermeldung angezeigt, dassegg_channel
nicht vorhanden ist. In den folgenden Schritten erfährst du mehr über Benachrichtigungskanäle und kannst das Problem beheben.
Schritt 2: Benachrichtigungskanäle
Ab API-Level 26 müssen alle Benachrichtigungen einem Kanal zugewiesen werden. Wenn Sie das App Launcher-Symbol berühren und halten, die App-Info auswählen und auf „Benachrichtigungen“ tippen, sehen Sie eine Liste der mit der App verknüpften Benachrichtigungskanäle. Derzeit ist die Liste leer, da für Ihre App keine Kanäle erstellt wurden.
Kanäle stellen eine Art von Benachrichtigung dar. Beispielsweise kann Ihr Ei-Timer eine Benachrichtigung erhalten, wenn das Ei gekocht wird. Über einen anderen Kanal können Sie sich auch täglich mit Erinnerungen benachrichtigen, damit Sie Eier beim Frühstück erhalten. Alle Benachrichtigungen von Channels werden gruppiert und Nutzer können Benachrichtigungseinstellungen für einen gesamten Kanal konfigurieren. So können Nutzer ihre Benachrichtigungseinstellungen personalisieren, indem sie festlegen, welche Benachrichtigungen sie interessieren. Beispielsweise können Nutzer die Frühstücksbenachrichtigungen deaktivieren, aber dennoch die Benachrichtigungen des Timers sehen.
Entwickler legen die Anfangseinstellungen, die Wichtigkeit und das Verhalten auf alle Benachrichtigungen eines Kanals fest. Nachdem Sie die Ersteinstellungen festgelegt haben, können Nutzer die Einstellungen überschreiben.
In Schritt 1.1 hast du egg_notification_channel_id
als Benachrichtigungskanal verwendet. Jetzt musst du die Benachrichtigungseinstellungen und das Verhalten dieses Kanals tatsächlich erstellen und anpassen.
- Öffne
EggTimerFragment.kt
und suche die FunktioncreateChannel()
. - Übergib die eindeutige Kanal-ID an den Konstruktor von
NotificationChannel
. - Übergeben Sie den Namen des Benachrichtigungskanals, den Nutzer auch auf dem Bildschirm Einstellungen sehen.
- Übergeben Sie als letzten Parameter die Wichtigkeitsstufe für den Benachrichtigungskanal. Die Wichtigkeitsstufen werden später in diesem Codelab behandelt. Bis dahin können Sie also
NotificationManag
er.IMPORTANCE_LOW
verwenden. - Setzen Sie für das
notificationChannel
-ObjektenableLights
auf „true“. Bei dieser Einstellung wird das Licht eingeschaltet, wenn eine Benachrichtigung angezeigt wird. - Setzen Sie
notificationChannel
auf das ObjektlightColor
auf Rot, um bei Benachrichtigung ein rotes Licht anzuzeigen. - Setzen Sie für das
notificationChannel
-ObjektenableVibration
auf „true“, um die Vibration zu aktivieren. - Legen Sie für das
notificationChannel
-Objekt die Kanalbeschreibung auf‘Time for breakf
ast' fest. - Rufen Sie eine Instanz von
NotificationManager
ab, indem SiegetSystemService()
aufrufen. - Rufen Sie
createNotificationChannel()
inNotificationManager
auf und übergeben Sie dasnotificationChannel
-Objekt, das Sie im vorherigen Schritt erstellt haben.
//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
}
- Der nächste Schritt besteht darin, den Channel
createChannel()
zu erstellen (Schritt 1.7). Für diese Funktion sind zwei Parameter erforderlich: die Kanal-ID und der Kanalname. Suche nach der Kanal-ID und dem Kanalnamen aus den String-Ressourcen, die bereits in deinem Projekt vorhanden sind.
// EggTimerFragment.kt
// TODO: Step 1.7 call createChannel
createChannel(
getString(R.string.egg_notification_channel_id),
getString(R.string.egg_notification_channel_name)
)
- Du musst die Kanal-ID an das Builder für Benachrichtigungen übergeben. Dies haben Sie bereits in Schritt 1.2 getan. Wenn Sie einen falschen Wert als Kanal-ID festlegen, schlägt die Benachrichtigung fehl. Öffne
NotificationUtils.kt
, um zu prüfen, ob die zuvor festgelegte Kanal-ID korrekt ist.
// NotificationUtils.kt
val builder = NotificationCompat.Builder(
applicationContext,
// TODO: Step 1.8 verify the notification channel name
applicationContext.getString(R.string.egg_notification_channel_id)
)
- Wenn Sie die App ausführen, erhalten Sie bei jedem Start des Timers eine Benachrichtigung.
- Prüfen Sie, ob der Titel, der Inhalt und das Symbol der Benachrichtigung korrekt sind.
- Wenn Sie den neu erstellten Kanal bestätigen möchten, schließen Sie die App und suchen Sie das App-Symbol. Lange auf das App-Symbol tippen und App-Info auswählen
- Wählen Sie aus der Liste der Einstellungen Benachrichtigungen aus. Direkt unter der Einstellung Benachrichtigungen anzeigen sollte der neue Kanal Ei angezeigt werden.
Wenn Sie die App ausführen, wird die Benachrichtigung angezeigt. Sowohl du als der App-Entwickler als auch deine Nutzer können die Einstellungen und das Verhalten für alle auf diesem Kanal gesendeten Benachrichtigungen anpassen. Glückwunsch, Sie haben eine Benachrichtigung erstellt.
Schritt 3: Benachrichtigungen zu Ihrer App hinzufügen
Bisher wird die grundlegende Verwendung der Notifications API veranschaulicht. Es ist jedoch nicht sinnvoll, eine Benachrichtigung direkt nach dem Starten des Timers zu senden. Nutzer werden lieber benachrichtigt, wenn das Ei bereit ist. Im folgenden Teil des Codelabs beheben Sie das Problem und ändern die Toast-Nachricht zu einer Benachrichtigung.
Sie haben die Benachrichtigung bereits gesendet und beobachtet, wie sie den Nutzern angezeigt wird. Das war aber nur der erste Schritt. In diesem Schritt ändern Sie Ihre Benachrichtigung so, dass sie zu einem besseren Zeitpunkt gesendet wird.
Deine App nutzt AlarmManager
, um einen Wecker einzurichten. Der Code für AlarmManager
ist bereits im Starter-Code enthalten und wird verwendet, um die Toast-Meldung anzuzeigen. AlarmManager
zeichnet die gewünschte Zeitauswahl auf und löst die onReceive()
-Funktion von AlarmReceiver.kt
aus, wenn die Zeit abgelaufen ist. Wenn Sie AlarmReceiver.kt
öffnen und onReceive()
aufrufen, sollte die Toast-Meldung angezeigt werden, die jedes Mal angezeigt wird, wenn Sie einen Ei-Timer einrichten.
- Öffnen Sie
AlarmReceiver.kt
als Instanz vonNotificationManager
und rufen Sie die FunktionsendNotification()
mit dem Nachrichtentext und Kontextparametern auf.
// 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
)
- Sie können den Toast auch entfernen, weil Ihre App bei Ablauf des Timers eine Benachrichtigung sendet.
// AlarmReceiver.kt
// TODO: Step 1.10 [Optional] remove toast
// Toast.makeText(
// context,
// context.getText(R.string.eggs_ready),
// Toast.LENGTH_SHORT
// ).show()
- Führe deine App aus . Du solltest jedes Mal eine Benachrichtigung sehen, wenn du den Timer startest oder wenn der Timer abgelaufen ist.
Das ist nicht ideal. Sie möchten nicht zu viele Benachrichtigungen an Nutzer senden. Sie können die erste Benachrichtigung entfernen, die gesendet wird, wenn der Nutzer den Timer startet.
- Öffnen Sie
EggTimerFragment.kt
und entfernen Sie den Benachrichtigungscode für Schritt 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)
- Führen Sie Ihre App noch einmal aus.
- Sie können einen Timer stellen, ihn im Hintergrund platzieren und warten, bis er abgeschlossen ist. Eine Benachrichtigung wird angezeigt. Diese Benachrichtigung ist viel nützlicher.
Schritt 4: Intent hinzufügen
- Führe die App noch einmal aus, falls sie noch nicht ausgeführt wird.
- Klicken Sie auf die Benachrichtigung. Es passiert nichts.
Es ist toll, die Benachrichtigung anzuzeigen und den Nutzer zu informieren. Wenn ein Nutzer jedoch auf eine Benachrichtigung klickt, erwartet er, zur entsprechenden App zurückzukehren. In diesem Teil des Codelabs fügst du deiner Benachrichtigung einen Intent hinzu, um den Nutzer zurück zum Timer-Bildschirm zu bringen.
Ein Intent
ist ein Nachrichtenobjekt, mit dem Sie eine Aktion aus einer anderen App-Komponente anfordern können. Intents können zum Starten einer Aktivität, eines Dienstes oder zum Senden einer Übertragung verwendet werden. In diesem Fall teilen Sie dem System mit, dass MainActivity
geöffnet werden soll, wenn der Nutzer auf die Benachrichtigung tippt. Da Ihre App nur aus einer einzigen Ansicht besteht, stehen Ihnen hier nicht viele Optionen zur Verfügung. In einer größeren App sollte die Benachrichtigung jedoch ein nahtloses Erlebnis bieten, da der Nutzer auf einen Bildschirm weitergeleitet wird, der für die Interaktion mit der Benachrichtigung sinnvoll ist.
- Öffnen Sie
NotificationUtils.kt
und suchen Sie die ErweiterungsfunktionsendNotification()
. - Erstelle eine
Intent
mit deinerapplicationContext
und der Aktivität, die gestartet werden soll,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)
Sie haben den Intent erstellt, aber die Benachrichtigung wird außerhalb Ihrer App angezeigt. Wenn Sie einen Intent außerhalb der App funktionieren möchten, müssen Sie ein neues PendingIntent
erstellen.
PendingIntent
gewährt einer anderen App oder dem System Rechte, um im Namen Ihrer App einen Vorgang auszuführen. Ein PendingIntent
selbst ist einfach ein Verweis auf ein Token, das vom System verwaltet wird und eine Beschreibung der ursprünglichen Daten enthält, mit denen es abgerufen wurde. Das bedeutet, dass die PendingIntent
selbst von anderen Prozessen weiterhin verwendet werden kann, selbst wenn der eigene Prozess beendet wird. In diesem Fall verwendet das System den ausstehenden Intent, um die App in Ihrem Namen zu öffnen, unabhängig davon, ob die Timer-App ausgeführt wird oder nicht.
- Erstellen Sie eine
PendingIntent
mitapplicationContext
,NOTIFICATION_ID
, dercontentIntent
im vorherigen Schritt und dem FlagPendingIntent
. Das FlagPendingIntent
gibt die Option zum Erstellen eines neuenPendingIntent
oder zur Verwendung eines vorhandenen an. Sie müssenPendingIntent.FLAG_UPDATE_CURRENT
als Flag festlegen, da Sie keine neue Benachrichtigung erstellen möchten, wenn bereits eine vorhanden ist. Auf diese Weise ändern Sie den aktuellenPendingIntent
, der mit dem bereitgestellten Intent verknüpft ist.
// NotificationUtils.kt
// TODO: Step 1.12 create PendingIntent
val contentPendingIntent = PendingIntent.getActivity(
applicationContext,
NOTIFICATION_ID,
contentIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
- Gib
PendingIntent
an deine Benachrichtigung weiter. Rufen Sie dazusetContentIntent()
inNotificationBuilder
auf. Wenn Sie jetzt auf die Benachrichtigung klicken, wirdPendingIntent
ausgelöst, wodurch IhrMainActivity
geöffnet wird. - Setzen Sie
setAutoCancel()
außerdem auftrue
, damit die Benachrichtigung geschlossen wird, wenn der Nutzer auf die Benachrichtigung tippt.
// NotificationUtils.kt
// TODO: Step 1.13 set content intent
.setContentIntent(contentPendingIntent)
.setAutoCancel(true)
- Führen Sie die App noch einmal aus.
- Stellen Sie einen Timer ein, platzieren Sie die App im Hintergrund und warten Sie, bis die Benachrichtigung angezeigt wird.
- Sobald Sie die Benachrichtigung sehen, können Sie auf die Benachrichtigung klicken, indem Sie die Statusleiste nach unten ziehen. Jetzt sehen Sie, wie die App in den Vordergrund gebracht wird.
Schritt 5: Benachrichtigung stornieren
Sie haben einen funktionsfähigen Ei-Timer mit Benachrichtigungen. Es gibt jedoch ein kleines Problem. Wenn Sie den Timer stellen, eine Benachrichtigung erhalten und den Timer noch einmal stellen, bleibt die vorherige Benachrichtigung in der Statusleiste, während der neue Timer läuft. Das kann für den Nutzer verwirrend sein, wenn die App im Hintergrund ausgeführt wird, was zu ungenauen Eiern führen kann.
Wenn Sie einen neuen Timer starten möchten, müssen Sie die vorherige Benachrichtigung löschen. Erstellen Sie zuerst eine weitere Erweiterungsfunktion in der NotificationUtils.kt
. NotificationManager
hat eine API, mit der alle aktiven Benachrichtigungen namens cancelAll
()
abgebrochen werden.
- Öffnen Sie
NotificationsUtil.kt
. - Fügen Sie unter
NotificationManager
eine Erweiterungsfunktion hinzu, diecancelAll()
aufruft.
// NotificationUtils.kt
// TODO: Step 1.14 Cancel all notifications
/**
* Cancels all notifications.
*
*/
fun NotificationManager.cancelNotifications() {
cancelAll()
}
- Öffnen Sie
EggTimerViewModel.kt
und gehen Sie zur FunktionstartTimer()
. - Rufen Sie in
startTimer()
eine Instanz vonNotificationManager
aus dem System ab und rufen SiecancelNotifications()
auf.
// EggTimerViewModel.kt
//TODO Step 1.15 call cancel notification
val notificationManager =
ContextCompat.getSystemService(
app,
NotificationManager::class.java
) as NotificationManager
notificationManager.cancelNotifications()
- Führe die App aus und starte den Timer.
- Starten Sie den Timer erneut, um zu sehen, wie die vorherige Benachrichtigung automatisch von der Statusleiste gelöscht wird.
Das Benachrichtigungs-Framework bietet eine Vielzahl von Anpassungsoptionen, mit denen Entwickler benutzerdefinierte Aktionen festlegen und ihre Benachrichtigungen nach Bedarf gestalten können. In dieser Aufgabe erfahren Sie, wie Sie die Benachrichtigungen zum Ei-Timer anpassen können.
Schritt 1: Benachrichtigung gestalten
Wenn Sie die Benachrichtigung an die Anforderungen und den Inhalt der Benachrichtigung anpassen, heben sie sich von der Masse ab. Das Benachrichtigungs-Framework umfasst verschiedene integrierte Stile, die Sie verwenden können, und Sie können jederzeit eigene Designs erstellen.
NotificationCompat
bietet integrierte Stile für:
BigTextStyle
, die einen großen Textblock anzeigen können, beispielsweise den Inhalt einer E-Mail, wenn der Text maximiert istBigPictureStyle
, die Benachrichtigungen im großen Format enthalten, die einen großen Bildanhang enthaltenInboxStyle
mit einem Textinhalt für eine Unterhaltung.MediaStyle
zur Steuerung der Medienwiedergabe.MessagingStyle
, die Benachrichtigungen im großen Format enthalten, die mehrere Nachrichten von einer beliebigen Person enthalten
In der Dokumentation unter Expandable-Benachrichtigungen erstellen finden Sie Informationen zu weiteren Stilen. In diesem Schritt erstellen Sie mit NotificationCompat.BigPictureStyle
eine erweiterbare Benachrichtigung, in der ein großes Ei-Bild angezeigt wird.
- Öffne
NotificationUtils.kt
und suche die FunktionsendNotification()
. - Lade zuerst ein Bild aus
resources
mithilfe vonBitmapFactory
.
// NotificationUtils.kt
// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
applicationContext.resources,
R.drawable.cooked_egg
)
- Erstellen Sie eine neue
BigPictureStyle
und legen Sie das Bild fest. - Setzen Sie
bigLargeIcon()
aufnull
, damit das große Symbol ausgeblendet wird, wenn die Benachrichtigung maximiert wird.
// 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)
- Setze den Stil mit
setStyle()
aufbigPicStyle
. - Setzen Sie das große Symbol mit
setLargeIcon()
aufeggImage
, damit das Bild beim Minimieren der Benachrichtigung als kleineres Symbol angezeigt wird.
// NotificationUtils.kt
// TODO: Step 2.1 add style to builder
.setStyle(bigPicStyle)
.setLargeIcon(eggImage)
- App ausführen und Timer einstellen Wenn die Benachrichtigung zum ersten Mal angezeigt wird, ist sie in der minimierten Benachrichtigungsleiste minimiert. Wenn Sie die Benachrichtigung maximieren, wird im erweiterten Benachrichtigungsbereich ein großes Bild angezeigt.
Schritt 2: Benachrichtigungsaktionen
Benachrichtigungsaktionen sind eine weitere Anpassung, die Sie Ihren Benachrichtigungen hinzufügen können. Ihre Benachrichtigungen werden derzeit an Ihre App weitergeleitet, wenn Nutzer darauf klicken. Zusätzlich zu dieser Standardaktion können Sie Aktionsschaltflächen hinzufügen, mit denen eine App-bezogene Aktion in der Benachrichtigung ausgeführt wird.
Eine Benachrichtigung kann bis zu drei Aktionsschaltflächen enthalten, mit denen der Nutzer schnell reagieren kann. So kann er beispielsweise eine Erinnerung zurückstellen oder auf eine SMS antworten. Durch diese Schaltflächen sollte die Aktion nicht dupliziert werden, auf die der Nutzer auf die Benachrichtigung tippt.
Übergeben Sie ein PendingIntent
an die addAction()
-Funktion im Builder, um eine Aktionsschaltfläche hinzuzufügen. Das ist wie beim Einrichten der Standard-Touch-Aktion für die Benachrichtigung, indem setContentIntent()
aufgerufen wird. Anstatt eine Aktivität zu starten, kannst du verschiedene Aktionen ausführen. So kannst du beispielsweise eine BroadcastReceiver
starten, die einen Job im Hintergrund ausführt, sodass die App, die bereits geöffnet ist, nicht unterbrochen wird.
In diesem Codelab haben Sie bereits ein BoadcastReceiver
-Objekt mit dem Namen SnoozeReceiver
. Sie verwenden SnoozeReceiver
, um den Nutzer auf die Benachrichtigungsaktion zu erhalten. In den folgenden Schritten fügen Sie Code hinzu, um die Benachrichtigung zum Ei-Timer 60 Sekunden lang zu pausieren, wenn der Nutzer auf die Schaltfläche zum Zurückstellen der Aktion klickt. Wenn auf die Aktion zum Zurückstellen geklickt wird, erhält die SnoozeReceiver
eine Intent und erstellt nach 60 Sekunden einen neuen Wecker, um eine neue Benachrichtigung zu senden.
- Öffnen Sie
SnoozeReceiver.kt
. Dieser Kurs ähnelt demAlarmReceiver
, den Sie zuvor verwendet haben. Mit den folgenden Schritten wird Code hinzugefügt, der die FunktiononReceive()
vonSnoozeReceiver
auslöst. Kurz gesagt: Durch den Code inSnoozeReceiver
wird ein neuer Wecker erstellt, um eine Minute später eine neue Benachrichtigung zu senden. Scrollen Sie in der Funktion „onReceive“ nach unten, rufen Sie eine „notificationManager“-Instanz aus und rufen Sie „cancelAll“ auf.
// SnoozeReceiver.kt
val notificationManager = ContextCompat.getSystemService(
context,
NotificationManager::class.java
) as NotificationManager
notificationManager.cancelAll()
- Öffnen Sie
NotificationUtils.kt
, umSnoozeReceiver
zu verwenden. - Erstellen Sie eine neue
Intent
snoozeIntent
für dieSnoozeReceiver
kurz nach dem Stil in dersendNotification()
-Funktion. - Erstellen Sie einen ausstehenden Intent, indem Sie die Methode
getBroadcast()
fürPendingIntent
aufrufen, die in den folgenden Schritten die Parameter erwartet.PendingIntent
verwendet das System, um nach 60 Sekunden eine neue Benachrichtigung einzurichten, damit der Nutzer eine neue Benachrichtigung senden kann, wenn er auf die Schlummertaste klickt. - Der erste Parameter ist der Anwendungskontext, in dem dieser
PendingIntent
die Aktivität starten soll. - Der zweite Parameter ist der Anfragecode, d. h. der Anfragecode für diesen ausstehenden Intent. Wenn Sie diesen ausstehenden Intent aktualisieren oder abbrechen möchten, müssen Sie mit diesem Code auf den ausstehenden Intent zugreifen.
- Als Nächstes fügen Sie das Objekt
snoozeIntent
hinzu. Dies ist der Zweck der Aktivität, die gestartet werden soll. - Fügen Sie schließlich den Flag-Wert
#FLAG_ONE_SHOT
hinzu, da der Intent nur einmal verwendet wird. Die Schnellaktion und die Benachrichtigung verschwinden nach dem ersten Antippen, weshalb der Intent nur einmal verwendet werden kann.
// 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
)
- Rufen Sie als Nächstes die Funktion
addAction()
fürnotificationBuilder
auf. Diese Funktion erwartet ein Symbol und einen Text, um deine Aktion dem Nutzer zu beschreiben. Sie müssen auch diesnoozeIntent
hinzufügen. Dieser Intent wird verwendet, um den richtigenboadcastReceiver
auszulösen, wenn auf Ihre Aktion geklickt wird.
// NotificationUtils.kt
// TODO: Step 2.3 add snooze action
.addAction(
R.drawable.egg_icon,
applicationContext.getString(R.string.snooze),
snoozePendingIntent
)
- Führe die Ei-Timer-App aus, um die Schlummerfunktion zu testen.
- Den Timer ausführen und die App im Hintergrund platzieren Wenn der Timer abgelaufen ist, maximieren Sie die Benachrichtigung. Die Benachrichtigung enthält jetzt eine Schaltfläche zum Zurückstellen der Eieruhr.
Schritt 3: Wichtigkeit der Benachrichtigung
Die Wichtigkeit legt fest, wie stark die Benachrichtigung den Nutzer visuell und akustisch unterbrechen soll. Benachrichtigungen mit höherer Wichtigkeit sind für den Nutzer störender.
Sie müssen die Wichtigkeitsstufe im NotificationChannel
-Konstruktor angeben. Du hast ursprünglich eine niedrige Wichtigkeit für die Ei-Timer-App festgelegt. Du kannst eine von fünf Wichtigkeitsstufen auswählen, von IMPORTANCE_NONE(0)
bis IMPORTANCE_HIGH(4)
. Die Wichtigkeitsstufe, die du einem Kanal zuweist, gilt für alle Benachrichtigungen, die du auf diesem Kanal postest.
Wichtigkeitsstufen von Kanälen
Für Nutzer sichtbare Wichtigkeitsstufe | Wichtigkeit (Android 8.0 und höher) | Priorität (Android 7.1 und niedriger) |
akustische Signale, die als „Vorsicht“-Benachrichtigung angezeigt werden (am oberen Rand des Bildschirms) | ||
Hat einen Ton | ||
Kein Ton | ||
Kein Ton und erscheint nicht in der Statusleiste |
Informationen zur Auswahl einer passenden Prioritätsstufe finden Sie im Leitfaden zum Erstellen von Benachrichtigungen. Du solltest vorsichtig sein, wenn du eine Wichtigkeitsstufe für die Benachrichtigungen in deiner App auswählst. Die Wichtigkeit des Kanals sollte unter Berücksichtigung der Zeit und Aufmerksamkeit des Nutzers ausgewählt werden. Wenn eine unwichtige Benachrichtigung als dringend getarnt ist, kann dies zu unnötigem Alarm führen und ablenken. Die Nutzer bestimmen selbst, wie wichtig Benachrichtigungen sind. Wenn du also eine lästige Benachrichtigung erstellst, kann sie deinen Benachrichtigungskanal vollständig deaktivieren.
Als Sie die Benachrichtigung in Schritt 1.6 erstellt haben, wurde der Ei-Timer so eingerichtet, dass Benachrichtigungen mit niedriger Priorität gesendet werden, da er Nutzer mit Benachrichtigungen nicht stören soll. Es kann jedoch sinnvoll sein, die Aufmerksamkeit des Nutzers zu erhalten, bevor das Ei zu kochen. Wenn du die Wichtigkeitsstufe der Benachrichtigung ändern möchtest, beginne mit den Kanaleinstellungen. Die Wichtigkeit eines Kanals wirkt sich auf die Unterbrechungsstufe aller Benachrichtigungen aus, die auf dem Kanal gepostet werden. Sie muss im NotificationChannel
-Konstruktor angegeben werden.
- Wenn du die Wichtigkeitsstufe deiner Benachrichtigungskanal ändern möchtest, öffne
EggTimerFragment.kt
und rufecreateChannel()
auf. Ändern Sie die Wichtigkeitsstufe vonIMPORTANCE_LOW
inIMPORTANCE_HIGH
.
// EggTimerFragment.kt
val notificationChannel = NotificationChannel(
channelId,
channelName,
// TODO: Step 2.4 change importance
NotificationManager.IMPORTANCE_HIGH
)
Um Geräte mit Android 7.1 (API-Level 25) oder niedriger zu unterstützen, müssen Sie auch setPriority()
für jede Benachrichtigung mit einer Prioritätskonstante aus der NotificationCompat
-Klasse aufrufen.
- Öffnen Sie
NotificationUtils.kt
und fügen Sie dem Benachrichtigungs-Builder-Objekt das folgende hinzu.
// 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)
- Bevor Sie die App ausführen, müssen Sie auf Ihrem Gerät oder Emulator lange auf das App-Symbol klicken und „Deinstallieren“ auswählen, um die vorherigen Kanaleinstellungen zu löschen. Wenn du die App nicht deinstallierst, werden die Einstellungen für die Kanalpriorität nicht geändert. Dadurch ändert sich auch das Verhalten der Benachrichtigung nicht.
- Führe die App noch einmal aus und starte den Timer. Bei der Übermittlung der Benachrichtigung sollte dieses Mal ein Pop-up oben auf dem Bildschirm angezeigt werden, unabhängig davon, ob Ihre App im Vordergrund oder im Hintergrund ausgeführt wird.
Schritt 4: Benachrichtigungslogos
Benachrichtigungslogos sind kleine Punkte, die auf dem Launcher-Symbol der verknüpften App angezeigt werden, wenn die App eine aktive Benachrichtigung hat. Drücken Sie lange auf das App-Symbol, um die Benachrichtigungen aufzurufen.
Diese Punkte, sogenannte Logos, werden standardmäßig angezeigt. Sie brauchen nichts weiter zu tun. Aber es gibt Situationen, in denen Logos keine Benachrichtigungen ergeben. Wenn du möchtest, kannst du sie für einzelne Kanäle deaktivieren. Rufe dazu setShowBadge(false)
in deinem NotificationChannel
-Objekt auf. Da die Ei-Timer jeweils nur eine aktive Benachrichtigung haben, zeigt das Logo auf Ihrem App-Symbol Ihren Nutzern keinen großen Vorteil. In den folgenden Schritten wird das Logo deaktiviert und es wird nur eine Benachrichtigung für den Ei-Timer angezeigt.
- Füge
setShowBadge(false)
zum Kanalerstellungscode für den Ei-Timer hinzu, um Logos zu deaktivieren.
// EggTimerFragment.kt
).apply {
// TODO: Step 2.6 disable badges for this channel
setShowBadge(false)
}
- Führe die App noch einmal aus, starte den Timer und sieh dir das App-Symbol an. Es sollten keine Logos auf dem App-Symbol angezeigt werden.
Der Lösungscode befindet sich im Master-Branch des heruntergeladenen Codes.
- Mit der Klasse NotificationManager können Sie Benachrichtigungen erstellen, senden, aktualisieren und abbrechen.
- Verwenden Sie ein NotificationChannel-Objekt mit der Methode createNotificationChannel, um einen Kanal für die Benachrichtigung festzulegen.
- Verwenden Sie addAction(), um Schnellaktionen zu einer Benachrichtigung hinzuzufügen.
- Verwenden Sie setShowBadge(), um Logos zu aktivieren oder zu deaktivieren.
- Hier kannst du Stile für Benachrichtigungen festlegen, die über Notification.Style hinausgehen
- Wichtigkeitsstufe mit NotificationChannel.setImportance() festlegen
Udacity-Kurs:
Android-Entwicklerdokumentation:
Links zu weiteren Codelabs in diesem Kurs finden Sie auf der Landingpage des erweiterten Android-Tools in Kotlin.