Android API düzeyi 26'dan itibaren, ön plan hizmetleri için kalıcı bildirimler gereklidir. Bu şart, özellikle pil olmak üzere sistem kaynaklarına aşırı yük bindirebilecek hizmetleri gizlemenizi engellemeyi amaçlar. Bu koşul potansiyel bir sorun yaratır: Birden fazla ön plan hizmeti olan bir uygulama, bildirimi tüm hizmetlerde paylaşılacak şekilde dikkatli bir şekilde yönetmezse kalıcı ve kapatılamayan birden fazla bildirim olabilir. Bu durum, etkin bildirimler listesinde istenmeyen bir karmaşaya yol açar.
Bu sorun, Navigation SDK gibi, uygulamadan bağımsız olarak ön plan hizmetleri çalıştıran ve kendi bağımsız kalıcı bildirimlerine sahip olan SDK'ları kullandığınızda daha da zorlaşır. Bu durumda, bildirimleri birleştirmek zorlaşır.
Navigation SDK v1.11, bu sorunları gidermek için SDK dahil olmak üzere uygulama genelinde kalıcı bildirimlerin yönetilmesine yardımcı olan basit bir API'yi kullanıma sundu.
Bileşenler
Ön plan hizmeti yöneticisi, Android ön plan hizmeti sınıfı ve kalıcı bildirim sınıfı için bir sarmalayıcı sağlar. Bu sarmalayıcının temel işlevi, bildirim yöneticisi kullanılarak tüm ön plan hizmetlerinde paylaşılması için bildirim kimliğinin yeniden kullanılmasını zorunlu kılmaktır.
Navigation SDK, ForegroundServiceManager
tekilini başlatmak ve almak için statik yöntemler içerir. Bu tekil öğe, Navigation SDK'nın kullanım ömrü boyunca yalnızca bir kez başlatılabilir. Dolayısıyla, başlatma çağrılarından birini (initForegroundServiceManagerMessageAndIntent()
veya initForegroundServiceManagerProvider()
) kullanırsanız bu yolun yeniden girilmesi ihtimaline karşı try-catch bloğuyla sarmalamanız gerekir. Navigation SDK, ForegroundServiceManager
ile ilgili tüm referansları önce temizlemediğiniz ve sonraki her çağrıdan önce clearForegroundServiceManager()
yöntemini çağırmadığınız sürece bu yöntemlerden birini birden fazla kez çağırdığınızda çalışma zamanı istisnası oluşturur.
initForegroundServiceManagerMessageAndIntent()
öğesinin dört parametresi application
, notificationId
, defaultMessage
ve resumeIntent
'dir. Son üç parametre boşsa bildirim, standart Navigation SDK bildirimidir. Uygulamadaki diğer ön plan hizmetlerini bu bildirimin arkasına gizlemek mümkündür. notificationId
parametresi, bildirim için kullanılması gereken bildirim kimliğini belirtir. Değer boşsa rastgele bir değer kullanılır. Diğer bildirimlerle (ör. başka bir SDK'dan gelen bildirimler) çakışmaları önlemek için bunu açıkça ayarlayabilirsiniz. defaultMessage
, sistemde gezinilmediği sırada gösterilen bir dizedir. resumeIntent
, bildirimin tıklandığında tetiklenen bir amaçtır. resumeIntent
değeri boşsa bildirimdeki tıklamalar yoksayılır.
initForegroundServiceManagerProvider()
işlevinin üç parametresi application
, notificationId
ve notificationProvider
'dür. Son iki parametre boşsa bildirim, standart Navigation SDK bildirimidir. notificationId
parametresi, bildirim için kullanılması gereken bildirim kimliğini belirtir. Değer boşsa rastgele bir değer kullanılır. Diğer bildirimlerle (ör. başka bir SDK'dan gelen bildirimler) çakışmaları önlemek için bunu açıkça ayarlayabilirsiniz. notificationProvider
ayarlanmışsa oluşturulacak bildirimi oluşturmaktan her zaman sağlayıcı sorumludur.
Navigation SDK'nın getForegroundServiceManager()
yöntemi, ön plan hizmeti yöneticisi tekilini döndürür. Henüz oluşturmadıysanız initForegroundServiceManagerMessageAndIntent()
, defaultMessage
ve resumeIntent
için boş parametrelerle notificationId
işlevini çağırmaya eşdeğerdir.
ForegroundServiceManager
üç basit yöntemle kullanılabilir. İlk ikisi, bir hizmeti ön plana ve arka plana taşımak için kullanılır ve genellikle oluşturulan hizmetin içinden çağrılır. Bu yöntemlerin kullanılması, hizmetlerin paylaşılan kalıcı bildirimle ilişkilendirilmesini sağlar. Son yöntem olan updateNotification()
, bildirimin değiştiğini ve yeniden oluşturulması gerektiğini belirten bir işaret ekler.
Paylaşılan kalıcı bildirimi tamamen kontrol etmeniz gerekiyorsa API, bildirim sağlayıcıyı tanımlamak için NotificationContentProvider
arayüzü sunar. Bu arayüz, mevcut içerikle bildirim almak için tek bir yöntem içerir. Ayrıca, sağlayıcıyı tanımlamanıza yardımcı olması için isteğe bağlı olarak kullanabileceğiniz bir temel sınıf da sağlar. Temel sınıfın temel amaçlarından biri, ForegroundServiceManager
'ye erişmeye gerek kalmadan updateNotification()
'yı çağırmanın bir yolunu sağlamaktır. Yeni bildirim mesajları almak için bildirim sağlayıcının bir örneğini kullanıyorsanız mesajı bildirimde oluşturmak için bu dahili yöntemi doğrudan çağırabilirsiniz.
Kullanım senaryoları
Bu bölümde, paylaşılan kalıcı bildirimlerin kullanım senaryoları ayrıntılı olarak açıklanmaktadır.
- Diğer uygulama ön plan hizmetlerinin kalıcı bildirimlerini gizleme
- En kolay senaryo, mevcut davranışı korumak ve yalnızca Navigation SDK bilgilerini oluşturmak için kalıcı bildirimi kullanmaktır. Diğer hizmetler, ön plan hizmeti yöneticisi
startForeground()
vestopForeground()
yöntemlerini kullanarak bu bildirimin arkasına gizlenebilir. - Diğer uygulama ön plan hizmetlerinin kalıcı bildirimlerini gizleyin ancak gezinme sırasında gösterilmeyen varsayılan metni ayarlayın.
- En kolay ikinci senaryo, mevcut davranışı korumak ve sistemde gezinme işlemi yapılmadığı durumlar hariç olmak üzere, yalnızca Navigation SDK bilgilerini oluşturmak için kalıcı bildirimi kullanmaktır. Sistemde navigasyon yapılmadığı zamanlarda,
initForegroundServiceManagerMessageAndIntent()
öğesine sağlanan dize, "Google Haritalar"dan bahseden varsayılan Navigation SDK dizesi yerine gösterilir. Bu çağrıyı, bildirimi tıkladığınızda tetiklenen devam ettirme amacını ayarlamak için de kullanabilirsiniz. - Kalıcı bildirimin oluşturulması üzerinde tam kontrol sahibi olma
- Son senaryoda, bir bildirim sağlayıcı tanımlayıp oluşturmanız
ve bunu
initForegroundServiceManagerProvider()
kullanarakForegroundServiceManager
öğesine iletmeniz gerekir.initForegroundServiceManagerProvider()
. Bu seçenek, bildirimde oluşturulan içerikler üzerinde tam kontrol sağlar ancak Navigasyon SDK'sı bildirim bilgilerini bildirimden ayırarak bildirimde gösterilen faydalı adım adım talimatları kaldırır. Google, bu bilgileri alıp bildirime eklemek için basit bir yöntem sunmaz.
Örnek bildirim sağlayıcı
Aşağıdaki kod örneğinde, basit bir bildirim içerik sağlayıcısı kullanarak bildirimlerin nasıl oluşturulacağı ve döndürüleceği gösterilmektedir.
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 "";
}
}
}
NotificationContentProviderImpl
oluşturduktan sonra aşağıdaki kodu kullanarak Navigation SDK'yı buna bağlarsınız:
ForegroundServiceManager f = NavigationApi.getForegroundServiceManager(getApplication());
mNotification = new NotificationContentProviderImpl(getApplication());
NavigationApi.clearForegroundServiceManager();
NavigationApi.initForegroundServiceManagerProvider(getApplication(), null, mNotification);
Uyarılar ve gelecek planları
- Beklenen kullanım senaryosunun iyi tanımlanması için
initForegroundServiceManagerMessageAndIntent()
veyainitForegroundServiceManagerProvider()
işlevini erken çağırdığınızdan emin olun. Yeni bir Navigator oluşturmadan önce bu yöntemi çağırmanız gerekir. - Kod yolu birden fazla kez girilirse
initForegroundServiceManagerMessageAndIntent()
veyainitForegroundServiceManagerProvider()
çağrılarındaki istisnaları yakaladığınızdan emin olun. Navigation SDK 2.0 sürümünde bu yöntemin birden fazla kez çağrılması, çalışma zamanı istisnası yerine kontrol edilen bir istisna oluşturur. - Google'ın, bildirim ömrü boyunca başlık stiline uygun tutarlı bir stil elde etmek için yapması gereken çalışmalar olabilir.
- Bildirim sağlayıcı tanımladığınızda, öncelik ile heads-up davranışını kontrol edebilirsiniz.
- Google, bildirim sağlayıcının bildirime ekleyebileceği adım adım yol tarifi bilgilerini almak için basit bir yöntem sunmaz.