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.
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
, defaultMessage
i resumeIntent
.
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()
istopForeground()
. - 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ą funkcjiinitForegroundServiceManagerProvider()
. 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()
lubinitForegroundServiceManagerProvider()
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()
lubinitForegroundServiceManagerProvider()
, 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.