Mobil bildirimleri birleştirme

Android API düzeyi 26'dan itibaren, ön plan hizmetleri için kalıcı bildirimler gereklidir. Bu şart, özellikle pil olmak üzere sistem kaynaklarını aşırı derecede zorlayabilecek hizmetleri gizlemenizi engellemek içindir. Bu şart, olası bir soruna yol açar: Birden fazla ön plan hizmetine sahip bir uygulama, bildirimi tüm hizmetlerde paylaşılacak şekilde dikkatli bir şekilde yönetmezse birden fazla kalıcı, kapatılamaz bildirim olabilir. Bu da etkin bildirim listesinde istenmeyen dağınıklığa neden olur.

Bu sorun, Navigation SDK'sı gibi ön plan hizmetlerini uygulamadan bağımsız olarak çalıştıran ve kendi bağımsız kalıcı bildirimlerine sahip olan SDK'lar kullanıldığında daha da zorlaşır. Bu da bildirimlerin birleştirilmesini zorlaştırır. Bu sorunları gidermek için Navigation SDK'sı 1.11 sürümü, SDK dahil olmak üzere uygulama genelinde kalıcı bildirimleri yönetmeye yardımcı olacak basit bir API kullanıma sundu.

Kalıcı bildirimleri birleştirme

Bileşenler

Ön plan hizmet yöneticisi, Android ön plan hizmet sınıfı ve kalıcı bildirim sınıfı için bir sarmalayıcı sağlar. Bu sarmalayıcının ana işlevi, bildirimin yöneticiyi kullanarak tüm ön plan hizmetlerinde paylaşılması için bildirim kimliğinin yeniden kullanılmasını zorunlu kılmaktır.


Navigasyon SDK'sı, ForegroundServiceManager tekil nesneyi başlatmak ve almak için statik yöntemler içerir. Bu tekil nesne, Navigation SDK'sının ömrü boyunca yalnızca bir kez başlatılabilir. Bu nedenle, başlatma çağrılarından birini (initForegroundServiceManagerMessageAndIntent() veya initForegroundServiceManagerProvider()) kullanıyorsanız bu yol yeniden girilebileceği için bu çağrıyı bir try-catch bloğuyla çevrelemeniz gerekir. Navigation SDK'sı, önce ForegroundServiceManager ile ilgili tüm referansları temizlemedikçe ve sonraki her çağrıdan önce clearForegroundServiceManager()'ı çağırmadıysanız iki yöntemden birini birden fazla kez çağırırsanız çalışma zamanında istisna oluşturur.

initForegroundServiceManagerMessageAndIntent()'ün dört parametresi application, notificationId, defaultMessage ve resumeIntent'tir. Son üç parametre null ise bildirim, standart Navigation SDK bildirimidir. Uygulamadaki diğer ön plan hizmetlerini bu bildirimin arkasına gizlemek yine de mümkündür. notificationId parametresi, bildirim için kullanılması gereken bildirim kimliğini belirtir. Boşsa rastgele bir değer kullanılır. Başka bir SDK'dan gelenler gibi diğer bildirimlerle olan çakışmaları önlemek için bu özelliği açıkça ayarlayabilirsiniz. defaultMessage, sistem gezinme yapmadığında gösterilen bir dizedir. resumeIntent, bildirim tıklandığında tetiklenen bir intent'tir. resumeIntent null ise bildirim tıklamaları yoksayılır.

initForegroundServiceManagerProvider()'nin üç parametresi application, notificationId ve notificationProvider'tır. Son iki parametre null ise bildirim, standart Navigation SDK bildirimidir. notificationId parametresi, bildirim için kullanılması gereken bildirim kimliğini belirtir. Değer null ise rastgele bir değer kullanılır. Başka bir SDK'dan gelenler gibi diğer bildirimlerle çakışmaları önlemek için bu ayarı açıkça ayarlayabilirsiniz. notificationProvider ayarlanmışsa oluşturulacak bildirimi oluşturmaktan her zaman sağlayıcı sorumludur.

Navigasyon SDK'sı getForegroundServiceManager() yöntemi, ön plan hizmet yöneticisi tekil nesnesi döndürür. Henüz oluşturmadıysanız bu, notificationId, defaultMessage ve resumeIntent için null parametrelerle initForegroundServiceManagerMessageAndIntent() çağrılmasına eşdeğerdir.

ForegroundServiceManager için üç basit yöntem vardır. İlk ikisi, bir hizmeti ön plana taşımak ve ön plandan çıkarmak içindir ve genellikle oluşturulan hizmetten çağrılır. Bu yöntemleri kullanmak, hizmetlerin paylaşılan kalıcı bildirimle ilişkilendirilmesini sağlar. Son yöntem olan updateNotification(), yöneticiye bildirimin değiştiğini ve yeniden oluşturulması gerektiğini işaret eder.

Paylaşılan kalıcı bildirim üzerinde tam kontrole ihtiyacınız varsa API, bildirim sağlayıcıyı tanımlamak için bir NotificationContentProvider arayüzü sağlar. Bu arayüzde, mevcut içeriğe sahip bir bildirim almak için tek bir yöntem bulunur. 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'a erişmek zorunda kalmadan updateNotification()'ü çağırma yöntemi sunmasıdır. Yeni bildirim mesajları almak için bildirim sağlayıcısının bir örneğini kullanıyorsanız mesajı bildirimde oluşturmak için doğrudan bu dahili yöntemi ç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 hizmet yöneticisi startForeground() ve stopForeground() yöntemlerini kullanarak bu bildirimin arkasına gizlenebilir.
Diğer uygulama ön plan hizmetlerinin kalıcı bildirimlerini gizleyin ancak gezinme
İkinci en kolay senaryo, mevcut davranışı korumak ve sistem gezinmediğinde hariç olmak üzere yalnızca Navigation SDK bilgilerini oluşturmak için kalıcı bildirimi kullanmaktır. Sistem navigasyonda değilken "Google Haritalar"dan bahseden varsayılan Navigasyon SDK'sı dizesi yerine initForegroundServiceManagerMessageAndIntent() için sağlanan dize gösterilir. Bu çağrıyı, bildirim tıklandığında tetiklenen devam ettirme intent'ini ayarlamak için de kullanabilirsiniz.
Kalıcı bildirimin oluşturulmasını tam olarak kontrol etme
Son senaryoda, bir bildirim sağlayıcı tanımlayıp oluşturmak ve initForegroundServiceManagerProvider() kullanarak ForegroundServiceManager'e iletmek gerekir. Bu seçenek, bildirimde nelerin oluşturulacağı konusunda tam kontrol sahibi olmanızı sağlar ancak aynı zamanda Gezinme SDK'sı bildirim bilgilerinin bildirimle bağlantısını keserek bildirimde gösterilen yol tarifi istemlerini kaldırır. Google, bu bilgileri almak ve bildirime eklemek için basit bir yol sağlamaz.

Örnek bildirim sağlayıcı

Aşağıdaki kod örneğinde, basit bir bildirim içerik sağlayıcısı kullanılarak 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'yi oluşturduktan sonra aşağıdaki kodu kullanarak Navigasyon SDK'sını ona 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() veya initForegroundServiceManagerProvider()'ü erken çağırdığınızdan emin olun. Yeni bir Gezgin oluşturmadan önce bu yöntemi çağırmanız gerekir.
  • Kod yolunun birden fazla kez girilmesi ihtimaline karşı initForegroundServiceManagerMessageAndIntent() veya initForegroundServiceManagerProvider() çağrılarına yönelik istisnaları yakaladığınızdan emin olun. Navigation SDK v2.0'da bu yöntemin birden çok kez çağrılması, çalışma zamanında istisna yerine kontrollü istisna oluşturur.
  • Google'ın, bildirimin kullanım süresi boyunca başlık stiliyle eşleşen tutarlı bir stil elde etmek için yapması gereken çalışmalar olabilir.
  • Bir bildirim sağlayıcı tanımladığınızda öncelikle uyarı davranışını kontrol edebilirsiniz.
  • Google, bir bildirim sağlayıcının bildirime ekleyebileceği adım adım yol bilgisini almak için basit bir yöntem sağlamaz.