Skonsoliduj powiadomienia na urządzeniach mobilnych

Począwszy od interfejsu API na poziomie 26 Androida, w przypadku usług na pierwszym planie wymagane są powiadomienia trwałe. Ten wymóg ma na celu zapobieganie ukrywaniu usług, które mogą nadmiernie obciążać zasoby systemowe, w tym zwłaszcza baterię. To wymaganie powoduje potencjalny problem: jeśli aplikacja z wieloma usługami na pierwszym planie nie zarządza powiadomieniami w sposób, który umożliwia ich udostępnianie wszystkim usługom, może się zdarzyć, że będzie wyświetlać wiele nieusuwanych powiadomień, co spowoduje niechciany bałagan na liście aktywnych powiadomień.

Ten problem staje się bardziej złożony, gdy używasz pakietów SDK, takich jak pakiet SDK nawigacji, które uruchamiają usługi na pierwszym planie niezależnie od aplikacji i mają własne powiadomienia trwałe, co utrudnia ich konsolidację. Aby rozwiązać te problemy, w pakiecie SDK Navigation SDK w wersji 1.11 wprowadziliśmy prosty interfejs API, ułatwiają zarządzanie trwałymi powiadomieniami w całej aplikacji, w tym w pakiecie SDK.

Konsolidacja trwałych powiadomień

Komponenty

Menedżer usługi na pierwszym planie udostępnia element opakowujący dla klasy usługi na pierwszym planie Androida i klasy powiadomienia trwałego. Główny kod tego kodu jest wymuszanie ponownego użycia identyfikatora powiadomienia, tak aby powiadomienie udostępniane we wszystkich usługach na pierwszym planie przy użyciu menedżera.


Pakiet SDK nawigacji zawiera metody statyczne służące do inicjowania i uzyskiwania obiektu ForegroundServiceManager singleton. Ten obiekt singleton może zostać zainicjowany tylko raz w cyklu życia pakietu SDK nawigacji. Dlatego, jeśli korzystasz z jednej z wywołania inicjujące (initForegroundServiceManagerMessageAndIntent() lub initForegroundServiceManagerProvider()), musisz otoczyć za pomocą bloku try-catch na wypadek ponownego wprowadzenia tej ścieżki. Pakiet SDK do nawigacji zgłasza wyjątek środowiska wykonawczego, jeśli wywołasz jedną z metod więcej niż raz, chyba że najpierw usuń wszystkie odwołania do ForegroundServiceManager i wywołaj clearForegroundServiceManager() przed każdym kolejnym połączeniem.

Cztery parametry parametru initForegroundServiceManagerMessageAndIntent() to application, notificationId, defaultMessage i resumeIntent. Jeśli 3 ostatnie parametry są puste, powiadomienie jest standardowym powiadomieniem pakietu SDK nawigacji. Nadal możesz ukryć inny pierwszy plan usług w aplikacji, której dotyczy powiadomienie. Parametr notificationId określa identyfikator powiadomienia, którego należy użyć w powiadomieniu. Jeśli tak null, używana jest wartość arbitralna. Możesz go ustawić wyraźnie, aby uniknąć konfliktów z innymi powiadomieniami, np. z innego pakietu SDK. defaultMessage to ciąg znaków wyświetlany, gdy system nie jest nawigowany. resumeIntent to intencja, która jest wywoływana po kliknięciu powiadomienia. Jeśli resumeIntent ma wartość null, klika powiadomienie. są ignorowane.

initForegroundServiceManagerProvider() to 3 parametry: application, notificationId i notificationProvider. Jeśli 2 ostatnie parametry są puste, powiadomienie jest standardowym powiadomieniem z pakietu SDK nawigacji. Parametr notificationId określa identyfikator powiadomienia, którego należy użyć do powiadomienia. Jeśli ma wartość null, używana jest dowolna wartość. Możesz skonfigurować ją w taki sposób, aby obchodziła konflikty z innymi , np. powiadomień z innego pakietu SDK. Jeśli notificationProvider to to usługodawca jest zawsze odpowiedzialny za które ma generować powiadomienia, które mają być renderowane.

Metoda getForegroundServiceManager() pakietu SDK Nawigacji zwraca pojedynczy obiekt menedżera usług na pierwszym planie. Jeśli nie masz jeszcze wygenerowanego klucza, jest to równoznaczne z wywołaniem funkcji initForegroundServiceManagerMessageAndIntent() z parametrami null dla parametrów notificationId, defaultMessageresumeIntent.

ForegroundServiceManager udostępnia 3 proste metody. Pierwsze 2 są przeznaczone do przenoszenia usługi na pierwszy lub z pierwszego planu i są one zwykle wywoływane z ram utworzonej usługi. Użycie tych metod zapewnia, że usługi są powiązane ze współdzielonym trwałym powiadomieniem. Ostatnia metoda, updateNotification(), sygnalizuje menedżerowi, że powiadomienie zostało zmienione i należy je ponownie wyrenderować.

Jeśli chcesz mieć pełną kontrolę nad udostępnionym trwałym powiadomieniem, interfejs API udostępnia interfejs NotificationContentProvider do definiowania dostawcy powiadomień, który zawiera jedną metodę pobierania powiadomienia z bieżącą zawartością. Zapewnia też klasę bazową, którą można mogą być opcjonalnie używane do zdefiniowania dostawcy. Jedna z głównych klasy bazowej jest to, że umożliwia wywołanie funkcji updateNotification() bez muszą uzyskać dostęp do: ForegroundServiceManager. Jeśli używasz instancji dostawcy powiadomień, aby otrzymywać nowe powiadomienia, możesz zadzwonić pod ten numer bezpośrednio do renderowania wiadomości w powiadomieniu.

Scenariusze użycia

W tej sekcji opisujemy scenariusze użycia udostępnionych powiadomień trwałych.

Ukryj trwałe powiadomienia innych usług działających na pierwszym planie aplikacji
Najprostszym rozwiązaniem jest zachowanie obecnego zachowania i używanie powiadomienia trwałego tylko do renderowania informacji z Navigation SDK. Inne usługi może ukryć się za tym powiadomieniem przy użyciu menedżera usługi na pierwszym planie Metody startForeground() i stopForeground().
Ukrywanie trwałych powiadomień z innych usług na pierwszym planie aplikacji, ale ustawianie domyślnego tekstu wyświetlanego, gdy nie ma nawigacji
Drugi najprostszy scenariusz to zachowanie bieżących informacji i używanie wyłącznie trwałe powiadomienie o renderowaniu informacji z pakietu Navigation SDK, z wyjątkiem gdy system nie jest włączony. Gdy system nie działa, ciąg został przekazany do funkcji initForegroundServiceManagerMessageAndIntent() zamiast domyślnego ciągu tekstowego pakietu Navigation SDK, który zawiera wzmiankę „Mapy Google”. Możesz też użyć tego wywołania, aby ustawić intencję wznawiania, która uruchamia się po kliknięciu powiadomienia.
mieć pełną kontrolę nad renderowaniem trwałego powiadomienia;
Ostatni scenariusz wymaga zdefiniowania i utworzenia dostawcy powiadomień oraz przekazania go do ForegroundServiceManager za pomocą funkcji initForegroundServiceManagerProvider(). Ta opcja daje pełną kontrolę nad tym, co jest renderowane w powiadomieniu, ale powoduje też odłączenie informacji z powiadomienia pakietu SDK nawigacji od powiadomienia, co powoduje usunięcie przydatnych promptów wyświetlanych w powiadomieniu. Google nie udostępnia prostego sposobu na pobranie tych informacji i wstawienie ich w powiadomieniu.

Przykładowy dostawca powiadomień

Poniższy przykładowy kod pokazuje, jak tworzyć i zwracać powiadomienia za pomocą prostego dostawcy treści powiadomień.

public class NotificationContentProviderImpl
   extends NotificationContentProviderBase
   implements NotificationContentProvider {
 private String channelId;
 private Context context;
 private String message;

 /** Constructor */
 public NotificationContentProviderImpl(Application application) {
   super(application);
   message = "-- uninitialized --";
   channelId = null;
   this.context = application;
 }

 /**
  * Sets message to display in the notification. Calls updateNotification
  * to display the message immediately.
  *
  * @param msg The message to display in the notification.
  */
 public void setMessage(String msg) {
   message = msg;
   updateNotification();
 }

 /**
  * Returns the notification as it should be rendered.
  */
 @Override
 public Notification getNotification() {
   Notification notification;

   if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
     Spanned styledText = Html.fromHtml(message, FROM_HTML_MODE_LEGACY);
     String channelId = getChannelId(context);
     notification =
         new Notification.Builder(context, channelId)
             .setContentTitle("Notifications Demo")
             .setStyle(new Notification.BigTextStyle()
                 .bigText(styledText))
             .setSmallIcon(R.drawable.ic_navigation_white_24dp)
             .setTicker("ticker text")
             .build();
   } else {
     notification = new Notification.Builder(context)
         .setContentTitle("Notification Demo")
         .setContentText("testing non-O text")
         .build();
   }

   return notification;
 }

 // Helper to set up a channel ID.
 private String getChannelId(Context context) {
   if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
     if (channelId == null) {
       NotificationManager notificationManager =
           (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
       NotificationChannel channel = new NotificationChannel(
           "default", "navigation", NotificationManager.IMPORTANCE_DEFAULT);
       channel.setDescription("For navigation persistent notification.");
       notificationManager.createNotificationChannel(channel);
       channelId = channel.getId();
     }
     return channelId;
   } else {
     return "";
   }
 }
}

Po utworzeniu NotificationContentProviderImpl możesz połączyć z nim pakiet SDK nawigacji za pomocą tego kodu:

ForegroundServiceManager f = NavigationApi.getForegroundServiceManager(getApplication());
mNotification = new NotificationContentProviderImpl(getApplication());
NavigationApi.clearForegroundServiceManager();
NavigationApi.initForegroundServiceManagerProvider(getApplication(), null, mNotification);

Zastrzeżenia i plany na przyszłość

  • Zadzwoń pod numer initForegroundServiceManagerMessageAndIntent() lub initForegroundServiceManagerProvider() wcześniej, jest dobrze zdefiniowany. Musisz wywołać tę metodę przed utworzeniem nowego Nawigatora.
  • Pamiętaj, aby wykrywać wyjątki od wywołań funkcji initForegroundServiceManagerMessageAndIntent() lub initForegroundServiceManagerProvider(), jeśli ścieżka kodu to wprowadzono więcej niż raz. Wywołanie tej metody w pakiecie SDK Navigation w wersji 2.0 zgłasza sprawdzony wyjątek, a nie wyjątek środowiska wykonawczego.
  • Nadal możemy jednak pracować nad spójnością stylu czas trwania powiadomienia pasującego do stylu nagłówka.
  • Gdy zdefiniujesz dostawcę powiadomień, możesz sterować działaniem powiadomień z poprzednim wyświetleniem, korzystając z priorytetu.
  • Google nie zapewnia prostego dostępu do szczegółowych informacji jakie dostawca powiadomień może wstawić do powiadomienia.