Devam Eden Etkinlik

Wear OS'te, devam eden bir aktivite devam eden bir bildirimle eşlendiğinde bu bildirim Wear OS kullanıcı arayüzündeki diğer yüzeylere eklenir. Bu, kullanıcıların uzun süreli etkinliklerle daha fazla etkileşim kurmasını sağlar.

Kesintisiz bildirimler genellikle bir bildirimin, kullanıcının aktif olarak etkileşimde bulunduğu veya bir şekilde beklemede olduğu ve dolayısıyla cihazı işgal ettiği bir arka plan görevi olduğunu belirtmek için kullanılır.

Örneğin, bir Wear OS kullanıcısı bir aktivitenin koşusunu kaydetmek için bir antrenman uygulaması kullanabilir, ardından bu uygulamadan ayrılıp başka bir görev başlatabilir. Kullanıcı antrenman uygulamasından ayrıldığında, uygulama, kullanıcıyı koşu sırasında bilgilendirmek için bazı arka plan işlerine bağlı devam eden bir bildirime geçiş yapıyor. Bildirim, kullanıcı güncellemelerinin yanı sıra uygulamayı tekrar kullanmaları için kolay bir yol sunar.

Ancak, bildirimi görüntülemek için kullanıcının, kadranın altındaki bildirim tepsisine kaydırarak doğru bildirimi bulması gerekir. Bu, diğer yüzeyler kadar kullanışlı değildir.

Onving Activity API ile bir uygulamanın devam eden bildirimleri, kullanıcının etkileşimde kalmasını sağlamak için bilgileri Wear OS'te birden çok yeni ve kullanışlı yüzeyde gösterebilir.

Örneğin, bu antrenman uygulamasında bilgi, kullanıcının kol saatinde dokunulabilir bir koşu simgesi olarak görünebilir:

çalışan-simgesi

Şekil 1. Etkinlik göstergesi.

Genel uygulama başlatıcının Son aramalar bölümünde devam eden etkinlikler de listelenir:

başlatıcı

2. Şekil. Global başlatıcı.

Aşağıda, devam eden bir etkinliğe bağlı devam eden bir bildirimin kullanılması için uygun durumlar verilmiştir:

zamanlayıcı

3. Şekil. Zamanlayıcı: Aktif olarak süreyi geri sayar ve zamanlayıcı duraklatıldığında veya durduğunda sona erer.

harita

4. Şekil. Adım adım navigasyon: Bir hedefe giden yol tarifini söyler. Kullanıcı hedefe ulaştığında veya navigasyonu durdurduğunda sona erer.

müzik

5. Şekil. Medya: Oturum boyunca müzik çalar. Kullanıcı oturumu duraklattıktan sonra hemen sona erer.

Wear, medya uygulamaları için devam eden etkinlikleri otomatik olarak oluşturur.

Diğer uygulama türleri için devam eden etkinlikler oluşturmaya ilişkin ayrıntılı bir örnek için Devam Eden Etkinlik codelab'ine bakın.

Kurulum

Uygulamanızda OnContinue Activity API'yi kullanmaya başlamak için aşağıdaki bağımlılıkları uygulamanızın build.gradle dosyasına ekleyin:

dependencies {
  implementation "androidx.wear:wear-ongoing:1.0.0"
  // Includes LocusIdCompat and new Notification categories for Ongoing Activity.
  implementation "androidx.core:core:1.6.0"
}

Devam eden bir etkinlik başlatma

Devam eden bir bildirim ve ardından devam eden etkinlik oluşturarak başlayın.

Devam eden bir bildirim oluşturma

Devam eden bir etkinlik, devam eden bir bildirimle yakından ilişkilidir. Aktif olarak etkileşimde bulunduğu bir görev veya bir şekilde beklemede olan ve dolayısıyla cihazı kaplayan bir görev hakkında kullanıcılara bilgi vermek için birlikte çalışırlar.

Devam eden bir etkinliği devam eden bir bildirimle eşlemeniz gerekir. Devam eden etkinliğinizi bir bildirime bağlamanın aşağıdakiler gibi birçok avantajı vardır:

  • Bildirimler, devam eden etkinlikleri desteklemeyen cihazların yedekleridir. Uygulamanızın arka planda çalışırken gösterdiği tek yüzey bildirimdir.
  • Android 11 ve sonraki sürümlerde uygulama başka yüzeylerde devam eden bir etkinlik olarak göründüğünde Wear OS, bildirim tepsisindeki bildirimi gizler.
  • Mevcut uygulama, iletişim mekanizması olarak Notification platformunu kullanmaktadır.

Bildirim.Builder.setOnbound dosyasını kullanarak devamlı bir bildirim oluşturun.

Devam eden bir etkinlik başlatma

Devam eden bir bildirim aldıktan sonra aşağıdaki örnekte gösterildiği gibi devam eden bir etkinlik oluşturun. Her bir mülkün davranışını anlamak için dahil edilen yorumları kontrol edin.

Kotlin

var notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
      …
      .setSmallIcon(..)
      .setOngoing(true)

val ongoingActivityStatus = Status.Builder()
    // Sets the text used across various surfaces.
    .addTemplate(mainText)
    .build()

val ongoingActivity =
    OngoingActivity.Builder(
        applicationContext, NOTIFICATION_ID, notificationBuilder
    )
        // Sets the animated icon that will appear on the watch face in
        // active mode.
        // If it isn't set, the watch face will use the static icon in
        // active mode.
        .setAnimatedIcon(R.drawable.ic_walk)
        // Sets the icon that will appear on the watch face in ambient mode.
        // Falls back to Notification's smallIcon if not set.
        // If neither is set, an Exception is thrown.
        .setStaticIcon(R.drawable.ic_walk)
        // Sets the tap/touch event so users can re-enter your app from the
        // other surfaces.
        // Falls back to Notification's contentIntent if not set.
        // If neither is set, an Exception is thrown.
        .setTouchIntent(activityPendingIntent)
        // Here, sets the text used for the Ongoing Activity (more
        // options are available for timers and stopwatches).
        .setStatus(ongoingActivityStatus)
        .build()

ongoingActivity.apply(applicationContext)

notificationManager.notify(NOTIFICATION_ID, builder.build())

Java

NotificationCompat.Builder notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
      …
      .setSmallIcon(..)
      .setOngoing(true);

OngoingActivityStatus ongoingActivityStatus = OngoingActivityStatus.Builder()
    // Sets the text used across various surfaces.
    .addTemplate(mainText)
    .build();

OngoingActivity ongoingActivity =
    OngoingActivity.Builder(
        applicationContext, NOTIFICATION_ID, notificationBuilder
    )
        // Sets the animated icon that will appear on the watch face in
        // active mode.
        // If it isn't set, the watch face will use the static icon in
        // active mode.
        .setAnimatedIcon(R.drawable.ic_walk)
        // Sets the icon that will appear on the watch face in ambient mode.
        // Falls back to Notification's smallIcon if not set.
        // If neither is set, an Exception is thrown.
        .setStaticIcon(R.drawable.ic_walk)
        // Sets the tap/touch event so users can re-enter your app from the
        // other surfaces.
        // Falls back to Notification's contentIntent if not set.
        // If neither is set, an Exception is thrown.
        .setTouchIntent(activityPendingIntent)
        // Here, sets the text used for the Ongoing Activity (more
        // options are available for timers and stopwatches).
        .setStatus(ongoingActivityStatus)
        .build();

ongoingActivity.apply(applicationContext);

notificationManager.notify(NOTIFICATION_ID, builder.build());

Aşağıdaki adımlarda, bir önceki örneğin en önemli kısmı belirtilmektedir:

  1. NotificationCompat.Builder'den .setOngoing(true) numaralı telefonu arayın ve isteğe bağlı alanları ayarlayın.

  2. Metni temsil etmek için bir OngoingActivityStatus veya aşağıdaki bölümde açıklandığı gibi başka bir durum seçeneği oluşturun.

  3. OngoingActivity oluşturun ve bildirim kimliği ayarlayın.

  4. OngoingActivity numaralı telefondan apply() ile iletişime geçerek bağlamı bildirin.

  5. notificationManager.notify() öğesini çağırın ve bunları birbirine bağlamak için devam eden etkinlikte ayarlanan bildirim kimliğini iletin.

Durum

OngoingActivity öğesinin mevcut canlı durumunu, başlatıcının Son Kullanılanlar bölümü gibi yeni yüzeylerde kullanıcıya göstermek için Status simgesini kullanırsınız. Özelliği kullanmak için Status.Builder alt sınıfını kullanın.

Çoğu durumda yalnızca uygulama başlatıcının Son aramalar bölümünde görünmesini istediğiniz metni temsil eden bir şablon eklemeniz gerekir.

Daha sonra addTemplate() yöntemini kullanarak ve metnin dinamik bölümlerini Status.Part olarak belirterek spans ile metnin görünümünü özelleştirebilirsiniz.

Aşağıdaki örnekte, "time" kelimesinin nasıl kırmızı renkte gösterileceği gösterilmektedir. Örnekte, uygulama başlatıcının Son Kullanılanlar bölümündeki bir kronometreyi temsil etmek için bir Status.StopwatchPart kullanılmıştır.

Kotlin

val htmlStatus =
        "<p>The <font color=\"red\">time</font> on your current #type# is #time#.</p>"

val statusTemplate =
        Html.fromHtml(
                htmlStatus,
                Html.FROM_HTML_MODE_COMPACT
        )

// Creates a 5 minute timer.
// Note the use of SystemClock.elapsedRealtime(), not System.currentTimeMillis().
val runStartTime = SystemClock.elapsedRealtime() + TimeUnit.MINUTES.toMillis(5)

val status = new Status.Builder()
   .addTemplate(statusTemplate)
   .addPart("type", Status.TextPart("run"))
   .addPart("time", Status.StopwatchPart(runStartTime)
   .build()

Java

String htmlStatus =
        "<p>The <font color=\"red\">time</font> on your current #type# is #time#.</p>";

Spanned statusTemplate =
        Html.fromHtml(
                htmlStatus,
                Html.FROM_HTML_MODE_COMPACT
        );

// Creates a 5 minute timer.
// Note the use of SystemClock.elapsedRealtime(), not System.currentTimeMillis().
Long runStartTime = SystemClock.elapsedRealtime() + TimeUnit.MINUTES.toMillis(5);

Status status = new Status.Builder()
   .addTemplate(statusTemplate)
   .addPart("type", new Status.TextPart("run"))
   .addPart("time", new Status.StopwatchPart(runStartTime)
   .build();

Şablondaki bir bölüme referans vermek için # ile başlayan adı kullanın. Çıkışta # oluşturmak için şablonda ## işlevini kullanın.

Önceki örnekte, şablona geçirilecek bir CharSequence oluşturmak için HTMLCompat kullanılmıştır. Bu yöntem, Spannable nesnesini manuel olarak tanımlamaktan daha kolaydır.

Ek özelleştirmeler

Status dışında, devam eden etkinliğinizi veya bildirimlerinizi aşağıdaki şekillerde özelleştirebilirsiniz. Ancak, OEM'nin uygulamasına bağlı olarak bu özelleştirmeler kullanılmayabilir.

Devam Eden Bildirim

  • Ayarlanan kategori, devam eden etkinliğin önceliğini belirler.
    • CATEGORY_CALL: Gelen sesli veya görüntülü görüşme ya da benzer bir eşzamanlı iletişim isteği
    • CATEGORY_NAVIGATION: harita veya adım adım navigasyon
    • CATEGORY_TRANSPORT: Oynatma için medya aktarımı kontrolü
    • CATEGORY_ALARM: alarm veya zamanlayıcı
    • CATEGORY_WORKOUT: antrenman (yeni kategori)
    • CATEGORY_LOCATION_SHARING: Geçici konum paylaşımı (yeni kategori)
    • CATEGORY_STOPWATCH: kronometre (yeni kategori)

Devam Eden Etkinlik

  • Animasyonlu simge: tercihen şeffaf bir arka plana sahip siyah beyaz bir vektör. Etkin modda saat yüzünde görüntülenir. Animasyonlu simge sağlanmazsa varsayılan bildirim simgesi kullanılır. (Varsayılan bildirim simgesi her uygulama için farklıdır.)

  • Statik simge: şeffaf arka plana sahip bir vektör simgesi. Ambiyans modunda saat kadranında gösterilir. Animasyonlu simge ayarlanmazsa etkin modda saat yüzünde statik simge kullanılır. Bu sağlanmamışsa bildirim simgesi kullanılır. İkisi de ayarlanmazsa bir istisna atılır. (Uygulama başlatıcıda uygulama simgesi kullanılmaya devam eder.)

  • OnvingActivityStatus: düz metin veya Chronometer. Uygulama başlatıcının Son aramalar bölümünde görüntülenir. Sağlanmazsa "bağlam metni" bildirim kullanılır.

  • Dokunma Amacı: Kullanıcı devam eden etkinlik simgesine dokunursa uygulamaya geri dönmek için kullanılan PendingIntent. Saat yüzünde veya başlatıcı öğesinde gösterilir. Uygulamayı başlatmak için kullanılan asıl amaçtan farklı olabilir. Sağlanmazsa bildirimin içerik amacı kullanılır. İkisi de ayarlanmazsa bir istisna atılır.

  • LocusId: Devam eden etkinliğin ilişkili olduğu başlatıcı kısayolunu atayan kimlik. Etkinlik devam ederken Son aramalar bölümündeki başlatıcıda görüntülenir. Sağlanmamışsa başlatıcı, Son Kullanılanlar bölümündeki tüm uygulama öğelerini aynı paketten gizler ve yalnızca devam eden etkinliği gösterir.

  • Devam Eden Etkinlik Kimliği: Bir uygulamanın birden fazla devam eden etkinliği olduğunda fromExistingOngoingActivity()'e yapılan çağrıları açıklığa kavuşturmak için kullanılan kimlik.

Devam eden bir etkinliği güncelleme

Çoğu durumda, geliştiriciler ekrandaki verileri güncellemeleri gerektiğinde yeni bir devam eden bildirim ve devam eden yeni bir etkinlik oluşturur. Bununla birlikte OnContinue Activity API, bir örneği yeniden oluşturmak yerine saklamak istiyorsanız OngoingActivity güncellemesi için yardımcı yöntemler de sunar.

Uygulama arka planda çalışıyorsa OnContinue Activity API'ye güncellemeler gönderebilir. Ancak güncelleme yöntemi birbirine çok yakın olan çağrıları yoksaydığı için bunu çok sık yapmayın. Dakikada birkaç güncelleme makul bir tutumdur.

Devam eden etkinliği ve yayınlanan bildirimi güncellemek için daha önce oluşturduğunuz nesneyi kullanın ve aşağıdaki örnekte gösterildiği gibi update() yöntemini çağırın:

Kotlin

ongoingActivity.update(context, newStatus)

Java

ongoingActivity.update(context, newStatus);

Kolaylık olması açısından, devam eden bir etkinlik oluşturmak için statik bir yöntem kullanılabilir.

Kotlin

OngoingActivity.recoverOngoingActivity(context)
               .update(context, newStatus)

Java

OngoingActivity.recoverOngoingActivity(context)
               .update(context, newStatus);

Devam eden bir etkinliği durdurma

Uygulamanın devam eden bir etkinlik olarak çalışması tamamlandığında, yalnızca devam eden bildirimi iptal etmesi gerekir.

Ayrıca, ön plana gelindiğinde bildirimi veya devam eden etkinliği iptal edip arka plana döndüklerinde bunları yeniden oluşturmayı da seçebilirsiniz, ancak bu zorunlu değildir.

Devam eden bir etkinliği duraklatma

Uygulamanızın açık bir durdurma işlemi varsa devam eden etkinliğe, duraklatma kaldırıldıktan sonra devam edin. Açık bir durdurma işlemi olmayan bir uygulama için duraklatıldığında etkinliği sonlandırın.

En iyi uygulamalar

Onving Activity API ile çalışırken aşağıdakileri göz önünde bulundurun:

  • notificationManager.notify(...) numaralı telefonu aramadan önce ongoingActivity.apply(context) numaralı telefonu arayın.
  • Devam Eden Etkinliğiniz için açıkça veya bildirim aracılığıyla yedek olarak statik bir simge ayarlayın. Aksi takdirde IllegalArgumentException kazanırsınız.

  • Saydam arka plana sahip siyah beyaz vektör simgeleri kullanın.

  • Devam eden etkinliğiniz için açıkça veya bildirimi kullanarak yedek olarak bir dokunma amacı ayarlayın. Aksi takdirde IllegalArgumentException kazanırsınız.

  • NotificationCompat için antrenman, kronometre ve konum paylaşımı için LocusIdCompat ile yeni kategorileri içeren Core AndroidX kitaplığını core:1.5.0-alpha05+ kullanın.

  • Uygulamanız manifest'te tanımlanmış birden fazla MAIN LAUNCHER etkinliği içeriyorsa dinamik kısayol yayınlayın ve bunu LocusId kullanarak devam eden etkinliğinizle ilişkilendirin.

Wear OS cihazlarda medya oynatırken medya bildirimleri yayınlayın

Bir Wear OS cihazda medya içeriği oynatılıyorsa bir medya bildirimi yayınlayın. Bu, sistemin ilgili devam eden etkinliği oluşturmasını sağlar.

Media3 kullanıyorsanız bildirim otomatik olarak yayınlanır. Bildirimi manuel olarak oluşturursanız bildirimde MediaStyleNotificationHelper.MediaStyle kullanılmalıdır ve ilgili MediaSession için oturum etkinliği doldurulmalıdır.