Devam Eden Etkinlik

Wear OS'te, devam eden bir etkinliği devam eden bir bildirimle eşleştirdiğinizde söz konusu bildirim, Wear OS kullanıcı arayüzündeki ek yüzeylere eklenir. Bu sayede kullanıcılar uzun süreli etkinliklerle daha fazla etkileşim kurabilir.

Devam eden 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 etkinlikteki koşuyu kaydetmek için antrenman uygulaması kullanabilir, ardından başka bir göreve başlamak için o uygulamadan ayrılabilir. Kullanıcı antrenman uygulamasından ayrıldığında uygulama, kullanıcıyı koşuyla ilgili bilgilendirmek için arka planda bir çalışmayla bağlantılı olarak sürekli bir bildirime geçiş yapar. Bu bildirim, kullanıcı güncellemelerini sağlar ve uygulamaya tekrar erişmenin kolay bir yolunu sunar.

Ancak bildirimi görmek için kullanıcının, kadranın altındaki bildirim tepsisinde kaydırması ve doğru bildirimi bulması gerekir. Bu, diğer yüzeylerde olduğu kadar kullanışlı değildir.

Devam Eden Activity API ile bir uygulamanın sürekli bildirimi, kullanıcının etkileşimde kalmasını sağlamak için bilgileri Wear OS'te birden fazla yeni ve kullanışlı yüzeye gösterebilir.

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

koşu-simgesi

Şekil 1. Etkinlik göstergesi.

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

başlatıcı

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

Devam eden bir etkinliğe bağlı devam eden bir bildirim kullanmak için iyi durumlar şunlardır:

zamanlayıcı

Şekil 3. Zamanlayıcı: Etkin bir şekilde zaman geri sayım yapar ve zamanlayıcı duraklatıldığında ya da durdurulduğunda sona erer.

harita

4.Şekil Adım adım navigasyon: Bir hedef için yol tariflerini duyurur. 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 hemen sonra 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 dair ayrıntılı bir örnek için Devam Eden Etkinlik codelab'e bakın.

Kurulum

Uygulamanızda Devam Eden Etkinlik API'sini kullanmaya başlamak için uygulamanızın build.gradle dosyasına aşağıdaki bağımlılıkları 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 oluşturup ardından devam eden bir etkinlik oluşturarak başlayın.

Devam eden bildirim oluşturma

Devam eden bir etkinlik, devam eden bir bildirimle yakından ilişkilidir. Kullanıcıların aktif olarak etkileşime girdiği bir görev veya bir şekilde beklemede olup cihazı meşgul eden bir görev hakkında kullanıcıları bilgilendirmek için birlikte çalışırlar.

Devam eden bir etkinliği devam eden bir bildirimle eşleştirmeniz gerekir. Devam eden etkinliğinizi bir bildirime bağlamanın aşağıdakiler de dahil olmak üzere pek çok faydası vardır:

  • Bildirimler, devam eden etkinlikleri desteklemeyen cihazlardaki yedeklerdir. Bildirim, uygulamanız arka planda çalışırken gösterilen tek yüzeydir.
  • Android 11 ve sonraki sürümlerde Wear OS, uygulama ek yüzeylerde devam eden bir etkinlik olarak göründüğünde bildirim tepsisinde bildirimi gizler.
  • Mevcut uygulama, iletişim mekanizması olarak Notification'yi kullanmaktadır.

Notification.Builder.setOncontinue kullanarak devam eden bir bildirim oluşturun.

Devam eden bir etkinlik başlatma

Devam eden bir bildiriminiz olduğunda aşağıdaki örnekte gösterildiği gibi devam eden bir etkinlik oluşturun. Her bir mülkün davranışını anlamak için eklenen 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, önceki örneğin en önemli kısmı açıklanmaktadır:

  1. NotificationCompat.Builder numaralı telefondan .setOngoing(true) adlı kuruluşu arayın ve isteğe bağlı alanları ayarlayın.

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

  3. Bir OngoingActivity oluşturun ve bildirim kimliği belirleyin.

  4. OngoingActivity numaralı telefondan apply() adlı kişiyi bağlam bilgisi vererek arayın.

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

Durum

Başlatıcının Son kullanılanlar bölümü gibi yeni yüzeylerde kullanıcıya OngoingActivity öğesinin geçerli, yayın durumunu göstermek için Status aracını kullanırsınız. Bu ö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 Kullanılanlar bölümünde görünmesini istediğiniz metni temsil eden bir şablon eklemeniz gerekir.

Ardından addTemplate() yöntemini kullanarak ve metnin dinamik bölümlerini Status.Part olarak belirterek metnin aralıklarla nasıl görüneceğini özelleştirebilirsiniz.

Aşağıdaki örnekte, "saat" kelimesinin nasıl kırmızı renkte görüneceği gösterilmektedir. Örnekte, uygulama başlatıcının Son Kullanılanlar bölümünde bir kronometreyi temsil etmek için Status.StopwatchPart kullanılmaktadı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 çevrili adı kullanın. Çıkışta # oluşturmak için şablonda ## kullanın.

Önceki örnekte HTMLCompat kullanılarak şablona aktarılacak bir CharSequence oluşturulur. Bu işlem, 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'in uygulamasına bağlı olarak bu özelleştirmeler kullanılamayabilir.

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: bir 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 arka plana sahip siyah beyaz bir vektör. Etkin modda kadranda gösterilir. 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 kadranda gösterilir. Animasyonlu simge ayarlanmazsa etkin modda kadranda statik simge kullanılır. Bu sağlanmazsa bildirim simgesi kullanılır. İkisi de ayarlanmazsa bir istisna atılır. (Uygulama başlatıcıda uygulama simgesini kullanmaya devam eder.)

  • OncontinueActivityStatus: Düz metin veya Chronometer. Uygulama başlatıcının Son Kullanılanlar bölümünde görüntülenir. Sağlanmazsa "bağlam metni" bildirimi kullanılır.

  • Dokunma Amacı: Kullanıcı devam eden etkinlik simgesine dokunduğunda uygulamaya geri dönmek için kullanılan PendingIntent. Kadranda 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 yayınlanır.

  • LocusId: Devam eden etkinliğin karşılık geldiği başlatıcı kısayolunu atayan kimlik. Etkinlik devam ederken Son Kullanılanlar bölümünde başlatıcıda görüntülenir. Sağlanmazsa 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() için yapılan çağrıların belirginliğini belirginleştirmek 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, bir örneği yeniden oluşturmak yerine saklamak istiyorsanız Devam eden Activity API, OngoingActivity öğesini güncellemek için yardımcı yöntemler de sunar.

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

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() öğesini çağırın:

Kotlin

ongoingActivity.update(context, newStatus)

Java

ongoingActivity.update(context, newStatus);

Kolaylık sağlaması açısından, devam eden bir etkinlik oluşturmak için sabit bir yöntem bulunur.

Kotlin

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

Java

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

Devam eden bir etkinliği durdurma

Uygulama, devam eden bir etkinlik olarak çalışmayı bitirdiğinde yalnızca devam eden bildirimi iptal etmesi gerekir.

Ayrıca, ön plana geldiğinde bildirimi veya devam eden etkinliği iptal etmeyi, ardından arka plana geri dönerken bunları yeniden oluşturmayı da seçebilirsiniz. Ancak bu zorunlu değildir.

Devam eden bir etkinliği duraklatma

Uygulamanızda açıkça 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

Devam Eden Etkinlik API'si ile çalışırken aşağıdakileri unutmayın:

  • notificationManager.notify(...) numaralı telefonu aramadan önce ongoingActivity.apply(context) adlı kuruluşu 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 alırsınız.

  • Şeffaf 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ı belirleyin. Aksi takdirde IllegalArgumentException alırsınız.

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

  • Uygulamanızın manifest dosyasında birden fazla MAIN LAUNCHER etkinliği beyan edilmişse dinamik kısayol yayınlayın ve LocusId kullanarak bunu devam eden etkinliğinizle ilişkilendirin.

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

Medya içeriği bir Wear OS cihazda oynatılıyorsa medya bildirimi yayınlayın. Bu işlem, sistemin buna karşılık gelen devam eden etkinliği oluşturmasına olanak tanır.

Media3 kullanıyorsanız bildirim otomatik olarak yayınlanır. Bildirimi manuel olarak oluşturursanız bildirim MediaStyleNotificationHelper.MediaStyle tarafından kullanılır ve ilgili MediaSession için oturum etkinliği doldurulur.