Tworzenie powiadomienia

Powiadomienia zawierają krótkie, aktualne informacje o zdarzeniach w aplikacji, gdy nie jest ona używana. Z tego dokumentu dowiesz się, jak utworzyć powiadomienie z różnymi funkcjami. Wprowadzenie do sposobu wyświetlania powiadomień na Androidzie znajdziesz w omówieniu powiadomień. Przykładowy kod, który korzysta z powiadomień, znajdziesz w przykładzie SociaLite w GitHubie.

Kod na tej stronie korzysta z interfejsów API NotificationCompat z biblioteki AndroidX. Te interfejsy API umożliwiają dodawanie funkcji dostępnych tylko w nowszych wersjach Androida, a jednocześnie zapewniają zgodność z Androidem 9 (poziom API 28). Jednak niektóre funkcje, takie jak odpowiadanie w tekście, w starszych wersjach nie działają.

Dodawanie biblioteki podstawowej AndroidX

Większość projektów utworzonych w Android Studio zawiera niezbędne zależności do korzystania z NotificationCompat. Sprawdź jednak, czy plik build.gradle na poziomie modułu zawiera tę zależność:

Groovy

dependencies {
    implementation "androidx.core:core-ktx:1.16.0"
}

Kotlin

dependencies {
    implementation("androidx.core:core-ktx:1.16.0")
}
.

Tworzenie podstawowego powiadomienia

Powiadomienie w najprostszej i najbardziej kompaktowej formie, zwanej też zwiniętą, zawiera ikonę, tytuł i niewielką ilość tekstu. W tej sekcji dowiesz się, jak utworzyć powiadomienie, które użytkownik może kliknąć, aby uruchomić aktywność w aplikacji.

Rysunek 1. Powiadomienie z ikoną, tytułem i tekstem.

Więcej informacji o poszczególnych elementach powiadomienia znajdziesz w artykule Anatomia powiadomienia.

Deklarowanie uprawnień czasu działania

Android 13 (API na poziomie 33) i nowsze wersje obsługują uprawnienia w czasie działania do publikowania powiadomień z aplikacji, które nie są zwolnione z tego obowiązku (w tym usług działających na pierwszym planie).

Uprawnienie, które musisz zadeklarować w pliku manifestu aplikacji, jest widoczne w tym fragmencie kodu:

<manifest ...>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <application ...>
        ...
    </application>
</manifest>

Więcej informacji o uprawnieniach czasu działania znajdziesz w artykule Uprawnienia czasu działania dotyczące powiadomień.

Ustawianie treści powiadomienia

Aby rozpocząć, ustaw treść i kanał powiadomienia za pomocą obiektu NotificationCompat.Builder. Poniższy przykład pokazuje, jak utworzyć powiadomienie z tymi elementami:

  • Mała ikona ustawiona przez setSmallIcon(). To jedyna wymagana treść widoczna dla użytkowników.

  • Tytuł ustawiony przez setContentTitle().

  • Tekst główny ustawiony przez element setContentText().

  • Priorytet powiadomienia ustawiony przez setPriority(). Priorytet określa, jak natrętne jest powiadomienie na urządzeniach z Androidem 7.1 i starszym. W przypadku Androida 8.0 i nowszych ustaw ważność kanału zgodnie z instrukcjami w następnej sekcji.

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

Konstruktor NotificationCompat.Builder wymaga podania identyfikatora kanału. Jest to wymagane w przypadku zgodności z Androidem 8.0 (poziom API 26) i nowszymi wersjami, ale jest ignorowane przez starsze wersje.

Domyślnie tekst powiadomienia jest obcinany, aby zmieścił się w jednym wierszu. Dodatkowe informacje możesz wyświetlać, tworząc powiadomienie rozwijane.

Rysunek 2. Rozwijane powiadomienie w formie zwiniętej i rozwiniętej.

Jeśli chcesz, aby powiadomienie było dłuższe, możesz włączyć powiadomienie rozwijane, dodając szablon stylu z elementem setStyle(). Na przykład ten kod tworzy większy obszar tekstowy:

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Much longer text that cannot fit one line...")
        .setStyle(NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Much longer text that cannot fit one line...")
        .setStyle(new NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

Więcej informacji o innych stylach dużych powiadomień, w tym o dodawaniu obrazu i sterowaniu odtwarzaniem multimediów, znajdziesz w artykule Tworzenie powiadomienia z możliwością rozwinięcia.

Tworzenie kanału i ustawianie jego ważności

Zanim dostarczysz powiadomienie na urządzeniu z Androidem w wersji 8.0 lub nowszej, zarejestruj kanał powiadomień aplikacji w systemie, przekazując instancję NotificationChannel do createNotificationChannel(). Ten kod jest blokowany przez warunek w wersji SDK_INT:

Kotlin

private fun createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is not in the Support Library.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = getString(R.string.channel_name)
        val descriptionText = getString(R.string.channel_description)
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
            description = descriptionText
        }
        // Register the channel with the system.
        val notificationManager: NotificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

Java

private void createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is not in the Support Library.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = getString(R.string.channel_name);
        String description = getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
        channel.setDescription(description);
        // Register the channel with the system; you can't change the importance
        // or other notification behaviors after this.
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}

Kanał powiadomień musisz utworzyć przed opublikowaniem jakichkolwiek powiadomień w Androidzie 8.0 lub nowszym, dlatego ten kod należy wykonać natychmiast po uruchomieniu aplikacji. Możesz wywoływać tę funkcję wielokrotnie, ponieważ utworzenie istniejącego kanału powiadomień nie powoduje żadnej operacji.

Konstruktor NotificationChannel wymaga obiektu importance, który korzysta z jednej ze stałych z klasy NotificationManager. Ten parametr określa, jak przerywać użytkownikowi wyświetlanie powiadomień należących do tego kanału. Ustaw priorytet za pomocą setPriority(), aby obsługiwać Androida 7.1 i starsze wersje, jak pokazano w przykładzie powyżej.

Chociaż musisz ustawić ważność lub priorytet powiadomienia zgodnie z przykładem poniżej, system nie gwarantuje, że alert będzie się zachowywać w określony sposób. W niektórych przypadkach system może zmienić poziom ważności na podstawie innych czynników, a użytkownik zawsze może ponownie zdefiniować poziom ważności dla danego kanału.

Więcej informacji o tym, co oznaczają poszczególne poziomy, znajdziesz w artykule o poziomach ważności powiadomień.

Ustawianie działania po kliknięciu powiadomienia

Każde powiadomienie musi reagować na kliknięcie, zwykle otwierając w aplikacji aktywność odpowiadającą powiadomieniu. Aby to zrobić, określ intencję dotyczącą treści zdefiniowaną za pomocą obiektu PendingIntent i przekaż ją do funkcji setContentIntent().

Poniższy fragment kodu pokazuje, jak utworzyć podstawowy zamiar otwarcia działania, gdy użytkownik kliknie powiadomienie:

Kotlin

// Create an explicit intent for an Activity in your app.
val intent = Intent(this, AlertDetails::class.java).apply {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)

val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // Set the intent that fires when the user taps the notification.
        .setContentIntent(pendingIntent)
        .setAutoCancel(true)

Java

// Create an explicit intent for an Activity in your app.
Intent intent = new Intent(this, AlertDetails.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // Set the intent that fires when the user taps the notification.
        .setContentIntent(pendingIntent)
        .setAutoCancel(true);

Ten kod wywołuje funkcję setAutoCancel(), która automatycznie usuwa powiadomienie, gdy użytkownik je kliknie.

Flagi intencji w poprzednim przykładzie zachowują oczekiwany przez użytkownika sposób nawigacji po otwarciu aplikacji za pomocą powiadomienia. Możesz z niej skorzystać w zależności od typu rozpoczynanej aktywności, która może być jedną z tych opcji:

  • Działanie, które istnieje wyłącznie w celu odpowiedzi na powiadomienie. Podczas normalnego korzystania z aplikacji użytkownik nie ma powodu, aby przechodzić do tego działania, więc rozpoczyna ono nowe zadanie zamiast być dodawane do istniejącego zadania i stosu wstecznego aplikacji. Jest to typ intencji utworzony w poprzednim przykładzie.

  • Aktywność, która występuje w standardowym przepływie aplikacji. W takim przypadku rozpoczęcie aktywności tworzy stos wsteczny, dzięki czemu zachowane są oczekiwania użytkownika dotyczące przycisków Wstecz i W górę.

Więcej informacji o różnych sposobach konfigurowania intencji powiadomienia znajdziesz w artykule Uruchamianie aktywności z poziomu powiadomienia.

Wyświetlanie powiadomienia

Aby wyświetlić powiadomienie, wywołaj funkcję NotificationManagerCompat.notify(), przekazując jej unikalny identyfikator powiadomienia i wynik funkcji NotificationCompat.Builder.build(). Pokazuje to poniższy przykład:

Kotlin

with(NotificationManagerCompat.from(this)) {
    if (ActivityCompat.checkSelfPermission(
            this@MainActivity,
            Manifest.permission.POST_NOTIFICATIONS
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        // TODO: Consider calling
        // ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        // public fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>,
        //                                        grantResults: IntArray)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.

        return@with
    }
    // notificationId is a unique int for each notification that you must define.
    notify(NOTIFICATION_ID, builder.build())
}

Java

with(NotificationManagerCompat.from(this)) {
   if (ActivityCompat.checkSelfPermission(
           this@MainActivity,
           Manifest.permission.POST_NOTIFICATIONS
       ) != PackageManager.PERMISSION_GRANTED
   ) {
       // TODO: Consider calling
       // ActivityCompat#requestPermissions
       // here to request the missing permissions, and then overriding
       // public void onRequestPermissionsResult(int requestCode, String[] permissions,
       //                                        int[] grantResults)
       // to handle the case where the user grants the permission. See the documentation
       // for ActivityCompat#requestPermissions for more details.

       return
   }
   // notificationId is a unique int for each notification that you must define.
   notify(NOTIFICATION_ID, builder.build())
}

Zapisz identyfikator powiadomienia, który przekazujesz do NotificationManagerCompat.notify(), ponieważ będzie on potrzebny, gdy zechcesz zaktualizować lub usunąć powiadomienie.

Dodatkowo, aby przetestować podstawowe powiadomienia na urządzeniach z Androidem 13 lub nowszym, włącz powiadomienia ręcznie lub utwórz okno dialogowe z prośbą o ich włączenie.

Dodawanie przycisków działań

Powiadomienie może zawierać maksymalnie 3 przyciski działań, które umożliwiają użytkownikowi szybką reakcję, np. odłożenie przypomnienia lub odpowiedź na SMS-a. Jednak te przyciski działania nie mogą powielać działania wykonywanego, gdy użytkownik kliknie powiadomienie.

Rysunek 3. Powiadomienie z 1 przyciskiem działania.

Aby dodać przycisk działania, przekaż wartość PendingIntent do metody addAction(). Jest to podobne do konfigurowania domyślnej czynności wykonywanej po kliknięciu powiadomienia, z tym że zamiast uruchamiać aktywność, możesz wykonywać inne czynności, takie jak uruchamianie BroadcastReceiver, które wykonuje zadanie w tle, dzięki czemu działanie nie przerywa działania otwartej już aplikacji.

Na przykład poniższy kod pokazuje, jak wysłać transmisję do konkretnego odbiorcy:

Kotlin

val ACTION_SNOOZE = "snooze"

val snoozeIntent = Intent(this, MyBroadcastReceiver::class.java).apply {
    action = ACTION_SNOOZE
    putExtra(EXTRA_NOTIFICATION_ID, 0)
}
val snoozePendingIntent: PendingIntent =
    PendingIntent.getBroadcast(this, 0, snoozeIntent, 0)
val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent)

Java

String ACTION_SNOOZE = "snooze"

Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
snoozeIntent.setAction(ACTION_SNOOZE);
snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
PendingIntent snoozePendingIntent =
        PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent);

Więcej informacji o tworzeniu BroadcastReceiver do uruchamiania pracy w tle znajdziesz w omówieniu transmisji.

Jeśli chcesz utworzyć powiadomienie z przyciskami odtwarzania multimediów, np. do wstrzymywania i pomijania utworów, dowiedz się, jak utworzyć powiadomienie z elementami sterującymi multimediami.

Dodawanie działania bezpośredniej odpowiedzi

Funkcja bezpośredniej odpowiedzi, wprowadzona w Androidzie 7.0 (interfejs API na poziomie 24), umożliwia użytkownikom wpisywanie tekstu bezpośrednio w powiadomieniu. Tekst jest następnie dostarczany do aplikacji bez otwierania aktywności. Możesz na przykład użyć działania bezpośredniej odpowiedzi, aby umożliwić użytkownikom odpowiadanie na wiadomości tekstowe lub aktualizowanie list zadań z poziomu powiadomienia.

Rysunek 4. Kliknięcie przycisku „Odpowiedz” otwiera pole wpisywania tekstu.

Działanie bezpośredniej odpowiedzi pojawia się jako dodatkowy przycisk w powiadomieniu, który otwiera pole wpisywania tekstu. Gdy użytkownik skończy pisać, system dołącza tekst odpowiedzi do intencji określonej dla działania powiadomienia i wysyła intencję do aplikacji.

Dodawanie przycisku odpowiedzi

Aby utworzyć działanie powiadomienia, które obsługuje bezpośrednią odpowiedź, wykonaj te czynności:

  1. Utwórz instancję RemoteInput.Builder , którą możesz dodać do działania powiadomienia. Konstruktor tej klasy akceptuje ciąg znaków, który system wykorzystuje jako klucz do wprowadzania tekstu. Aplikacja używa później tego klucza do pobrania tekstu wejściowego.

    Kotlin

      // Key for the string that's delivered in the action's intent.
      private val KEY_TEXT_REPLY = "key_text_reply"
      var replyLabel: String = resources.getString(R.string.reply_label)
      var remoteInput: RemoteInput = RemoteInput.Builder(KEY_TEXT_REPLY).run {
          setLabel(replyLabel)
          build()
      }
      

    Java

      // Key for the string that's delivered in the action's intent.
      private static final String KEY_TEXT_REPLY = "key_text_reply";
    
      String replyLabel = getResources().getString(R.string.reply_label);
      RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
              .setLabel(replyLabel)
              .build();
      
  2. Utwórz PendingIntent dla działania związanego z odpowiedzią.

    Kotlin

      // Build a PendingIntent for the reply action to trigger.
      var replyPendingIntent: PendingIntent =
          PendingIntent.getBroadcast(applicationContext,
              conversation.getConversationId(),
              getMessageReplyIntent(conversation.getConversationId()),
              PendingIntent.FLAG_UPDATE_CURRENT)
      

    Java

      // Build a PendingIntent for the reply action to trigger.
      PendingIntent replyPendingIntent =
              PendingIntent.getBroadcast(getApplicationContext(),
                      conversation.getConversationId(),
                      getMessageReplyIntent(conversation.getConversationId()),
                      PendingIntent.FLAG_UPDATE_CURRENT);
      
  3. Dołącz obiekt RemoteInput do działania za pomocą addRemoteInput().

    Kotlin

      // Create the reply action and add the remote input.
      var action: NotificationCompat.Action =
          NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
              getString(R.string.label), replyPendingIntent)
              .addRemoteInput(remoteInput)
              .build()
      

    Java

      // Create the reply action and add the remote input.
      NotificationCompat.Action action =
              new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
                      getString(R.string.label), replyPendingIntent)
                      .addRemoteInput(remoteInput)
                      .build();
      
  4. Zastosuj działanie do powiadomienia i wyślij powiadomienie.

    Kotlin

      // Build the notification and add the action.
      val newMessageNotification = Notification.Builder(context, CHANNEL_ID)
              .setSmallIcon(R.drawable.ic_message)
              .setContentTitle(getString(R.string.title))
              .setContentText(getString(R.string.content))
              .addAction(action)
              .build()
    
      // Issue the notification.
      with(NotificationManagerCompat.from(this)) {
          notificationManager.notify(notificationId, newMessageNotification)
      }
      

    Java

      // Build the notification and add the action.
      Notification newMessageNotification = new Notification.Builder(context, CHANNEL_ID)
              .setSmallIcon(R.drawable.ic_message)
              .setContentTitle(getString(R.string.title))
              .setContentText(getString(R.string.content))
              .addAction(action)
              .build();
    
      // Issue the notification.
      NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
      notificationManager.notify(notificationId, newMessageNotification);
      

Gdy użytkownik wywoła działanie powiadomienia, system poprosi go o wpisanie odpowiedzi (rysunek 4).

Pobieranie danych wpisanych przez użytkownika z odpowiedzi

Aby otrzymać dane wejściowe użytkownika z interfejsu odpowiedzi powiadomienia, wywołaj RemoteInput.getResultsFromIntent(), przekazując mu Intent otrzymane przez BroadcastReceiver:

Kotlin

private fun getMessageText(intent: Intent): CharSequence? {
    return RemoteInput.getResultsFromIntent(intent)?.getCharSequence(KEY_TEXT_REPLY)
}

Java

private CharSequence getMessageText(Intent intent) {
    Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
    if (remoteInput != null) {
        return remoteInput.getCharSequence(KEY_TEXT_REPLY);
    }
    return null;
 }

Po przetworzeniu tekstu zaktualizuj powiadomienie, wywołując funkcję NotificationManagerCompat.notify() z tym samym identyfikatorem i tagiem (jeśli został użyty). Jest to konieczne, aby ukryć interfejs bezpośredniej odpowiedzi i potwierdzić użytkownikowi, że jego odpowiedź została otrzymana i prawidłowo przetworzona.

Kotlin

// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
val repliedNotification = Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build()

// Issue the new notification.
NotificationManagerCompat.from(this).apply {
    notificationManager.notify(notificationId, repliedNotification)
}

Java

// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
Notification repliedNotification = new Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build();

// Issue the new notification.
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, repliedNotification);

Podczas pracy z tym nowym powiadomieniem używaj kontekstu przekazywanego do metody onReceive() odbiorcy.

Dołącz odpowiedź na dole powiadomienia, wywołując setRemoteInputHistory(). Jeśli jednak tworzysz aplikację do obsługi wiadomości, utwórz powiadomienie w stylu wiadomości i dołącz do rozmowy nową wiadomość.

Więcej porad dotyczących powiadomień z aplikacji do przesyłania wiadomości znajdziesz w sekcji Sprawdzone metody dotyczące aplikacji do przesyłania wiadomości.

Wyświetlanie pilnej wiadomości

Aplikacja może potrzebować wyświetlenia pilnej wiadomości, która wymaga natychmiastowej reakcji, np. połączenia przychodzącego lub dzwoniącego alarmu. W takich sytuacjach możesz powiązać z powiadomieniem intencję pełnoekranową.

Gdy powiadomienie zostanie wywołane, użytkownicy zobaczą jedną z tych informacji w zależności od stanu blokady urządzenia:

  • Jeśli urządzenie użytkownika jest zablokowane, pojawi się aktywność w trybie pełnoekranowym, która zakryje ekran blokady.
  • Jeśli urządzenie użytkownika jest odblokowane, powiadomienie pojawia się w rozwiniętej formie, która zawiera opcje obsługi lub odrzucenia powiadomienia.

Poniższy fragment kodu pokazuje, jak powiązać powiadomienie z intencją pełnoekranową:

Kotlin

val fullScreenIntent = Intent(this, ImportantActivity::class.java)
val fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
    fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setFullScreenIntent(fullScreenPendingIntent, true)

Java

Intent fullScreenIntent = new Intent(this, ImportantActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
        fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setFullScreenIntent(fullScreenPendingIntent, true);

Ustawianie widoczności na ekranie blokady

Aby określić poziom szczegółowości powiadomienia widocznego na ekranie blokady, wywołaj setVisibility() i określ jedną z tych wartości:

  • VISIBILITY_PUBLIC: pełna treść powiadomienia jest widoczna na ekranie blokady.

  • VISIBILITY_SECRET: żadna część powiadomienia nie jest wyświetlana na ekranie blokady.

  • VISIBILITY_PRIVATE: na ekranie blokady wyświetlane są tylko podstawowe informacje, takie jak ikona powiadomienia i tytuł treści. Pełna treść powiadomienia nie jest wyświetlana.

Gdy ustawisz wartość VISIBILITY_PRIVATE, możesz też podać alternatywną wersję treści powiadomienia, która ukrywa niektóre szczegóły. Na przykład aplikacja do SMS-ów może wyświetlać powiadomienie „Masz 3 nowe wiadomości tekstowe”, ale ukrywać treść wiadomości i nadawców. Aby wysłać to powiadomienie alternatywne, najpierw utwórz je w NotificationCompat.Builder w zwykły sposób. Następnie załącz alternatywne powiadomienie do zwykłego powiadomienia za pomocą ikony setPublicVersion().

Pamiętaj, że użytkownik zawsze ma pełną kontrolę nad tym, czy powiadomienia są widoczne na ekranie blokady, i może nimi zarządzać na podstawie kanałów powiadomień aplikacji.

Aktualizowanie powiadomienia

Aby zaktualizować powiadomienie po jego wysłaniu, ponownie wywołaj funkcję NotificationManagerCompat.notify(), przekazując jej ten sam identyfikator, którego użyto wcześniej. Jeśli poprzednie powiadomienie zostanie odrzucone, zamiast niego utworzymy nowe.

Opcjonalnie możesz wywołać setOnlyAlertOnce() tak, aby powiadomienie przerywało użytkownikowi pracę – dźwiękiem, wibracjami lub wskazówkami wizualnymi – tylko przy pierwszym wyświetleniu, a nie przy późniejszych aktualizacjach.

Usuwanie powiadomienia

Powiadomienia pozostają widoczne do momentu wystąpienia jednego z tych zdarzeń:

  • Użytkownik odrzuci powiadomienie.
  • Użytkownik klika powiadomienie, jeśli wywołasz funkcję setAutoCancel() podczas tworzenia powiadomienia.
  • Wywołujesz cancel() dla konkretnego identyfikatora powiadomienia. Ta metoda usuwa też bieżące powiadomienia.
  • Wywołujesz funkcję cancelAll(), która usuwa wszystkie wcześniej wysłane powiadomienia.
  • Określony czas trwania upłynie, jeśli podczas tworzenia powiadomienia ustawisz limit czasu za pomocą funkcji setTimeoutAfter(). W razie potrzeby możesz anulować powiadomienie przed upływem określonego czasu oczekiwania.

Sprawdzone metody dotyczące aplikacji do przesyłania wiadomości

Tworząc powiadomienia w aplikacjach do przesyłania wiadomości i na czacie, weź pod uwagę sprawdzone metody wymienione poniżej.

Używanie MessagingStyle

Od Androida 7.0 (interfejs API na poziomie 24) Android udostępnia szablon stylu powiadomień przeznaczony specjalnie do treści wiadomości. Za pomocą klasy NotificationCompat.MessagingStyle możesz zmienić kilka etykiet wyświetlanych w powiadomieniu, w tym tytuł wątku, dodatkowe wiadomości i widok treści powiadomienia.

Poniższy fragment kodu pokazuje, jak dostosować styl powiadomienia za pomocą klasy MessagingStyle.

Kotlin

val user = Person.Builder()
    .setIcon(userIcon)
    .setName(userName)
    .build()

val notification = NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("2 new messages with $sender")
    .setContentText(subject)
    .setSmallIcon(R.drawable.new_message)
    .setStyle(NotificationCompat.MessagingStyle(user)
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
        .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
    )
    .build()

Java

Person user = new Person.Builder()
    .setIcon(userIcon)
    .setName(userName)
    .build();

Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("2 new messages with " + sender)
    .setContentText(subject)
    .setSmallIcon(R.drawable.new_message)
    .setStyle(new NotificationCompat.MessagingStyle(user)
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
        .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
    )
    .build();

Począwszy od Androida 9.0 (interfejs API na poziomie 28), aby uzyskać optymalne renderowanie powiadomienia i jego awatarów, musisz też używać klasy Person.

Jeśli używasz NotificationCompat.MessagingStyle, wykonaj te czynności:

  • PołączenieMessagingStyle.setConversationTitle() umożliwia ustawienie tytułu czatów grupowych z więcej niż 2 osobami. Dobry tytuł rozmowy to nazwa czatu grupowego lub, jeśli nie ma nazwy, lista uczestników rozmowy. Bez tego oznaczenia wiadomość może zostać błędnie uznana za należącą do rozmowy 1:1 z nadawcą ostatniej wiadomości w rozmowie.
  • Użyj metody MessagingStyle.setData() do uwzględniania wiadomości z multimediami, np. obrazów. Obsługiwane są typy MIME wzorca image/*.

Korzystanie z bezpośredniej odpowiedzi

Funkcja bezpośredniej odpowiedzi umożliwia użytkownikowi odpowiadanie w tekście na wiadomość.

  • Gdy użytkownik odpowie za pomocą działania odpowiedzi w tekście, użyj MessagingStyle.addMessage() do zaktualizowania powiadomienia MessagingStyle. Nie wycofuj ani nie anuluj powiadomienia. Nieanulowanie powiadomienia umożliwia użytkownikowi wysłanie z niego wielu odpowiedzi.
  • Aby działanie odpowiedzi w tekście było zgodne z Wear OS, wywołaj Action.WearableExtender.setHintDisplayInlineAction(true).
  • Użyj metody addHistoricMessage() aby dodać kontekst do bezpośredniej odpowiedzi, dodając do powiadomienia historyczne wiadomości.

Włączanie Inteligentnej odpowiedzi

  • Aby włączyć Inteligentną odpowiedź, wywołaj setAllowGeneratedResponses(true) w odpowiedzi. Dzięki temu użytkownicy mogą korzystać z inteligentnych odpowiedzi, gdy powiadomienie jest przekazywane na urządzenie z Wear OS. Odpowiedzi w ramach funkcji Szybka odpowiedź są generowane przez model uczenia maszynowego działający w całości na zegarku, który wykorzystuje kontekst dostarczony przez NotificationCompat.MessagingStylepowiadomienie. Żadne dane nie są przesyłane do internetu w celu wygenerowania odpowiedzi.

Dodawanie metadanych powiadomienia