Devam eden etkinlikler

Wear OS cihazlar genellikle egzersiz takibi gibi uzun süren deneyimler için kullanılır. Bu durum, kullanıcı deneyimi açısından bir sorun teşkil eder: Bir göreve başlayan kullanıcılar, saat yüzüne geçtikten sonra nasıl geri dönebilir? Başlatıcıyı kullanarak uygulamaya dönmek, özellikle hareket halindeyken zor olabilir ve gereksiz sürtünme yaratır.

Çözüm, devam eden bir bildirimi OngoingActivity ile eşleştirmektir. Bu sayede cihaz, uzun süren etkinliklerle ilgili bilgileri kullanıcı arayüzünde gösterebilir ve kadranın alt kısmındaki dokunulabilir simge gibi özellikleri etkinleştirebilir. Bu sayede kullanıcılar arka planda yapılan görevden haberdar olur ve uygulamaya tek dokunuşla geri dönebilir.

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

koşu simgesi

1. şekil. Etkinlik göstergesi.

Devam eden bildirimler, global uygulama başlatıcının Son Kullanılanlar bölümünde de bilgi gösterir. Bu sayede kullanıcılar görevlerinin durumunu görebilir ve uygulamayla yeniden etkileşim kurabilir:

başlatıcı

Şekil 2. Dünya genelinde kullanıma sunuldu.

Devam eden bir etkinliğe bağlı sürekli bildirim kullanmak için uygun durumlar şunlardır:

zamanlayıcı

3.Şekil Zamanlayıcı: Zamanı aktif olarak geri sayar ve duraklatıldığında veya durdurulduğunda sona erer.

harita

Şekil 4. Adım adım navigasyon: Hedefe giden yol tarifini sesli olarak bildirir. Kullanıcı hedefe ulaştığında veya navigasyonu durdurduğunda sona erer.

müzik

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

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

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

Kurulum

Devam Eden Etkinlik API'sini uygulamanızda 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.1.0"
  implementation "androidx.core:core:1.17.0"
}

Devam eden bir etkinlik oluşturma

Bu süreç üç adımdan oluşur:

  1. Standart bir NotificationCompat.Builder oluşturun ve bunu devam eden olarak yapılandırın.
  2. Bildirim oluşturucuyu ileterek bir OngoingActivity nesnesi oluşturun ve yapılandırın.
  3. Devam eden etkinliği bildirim oluşturucuya uygulayın ve sonuçta elde edilen bildirimi yayınlayın.

Bildirimi oluşturma ve yapılandırma

NotificationCompat.Builder oluşturarak başlayın. Önemli adım, setOngoing(true) işlevini çağırarak bildirimi devam eden bildirim olarak işaretlemektir. Bu aşamada küçük simge ve kategori gibi diğer bildirim özelliklerini de ayarlayabilirsiniz.

// Create a PendingIntent to pass to the notification builder
val pendingIntent =
    PendingIntent.getActivity(
        this,
        0,
        Intent(this, AlwaysOnActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
        },
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
    )

val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("Always On Service")
    .setContentText("Service is running in background")
    .setSmallIcon(R.drawable.animated_walk)
    // Category helps the system prioritize the ongoing activity
    .setCategory(NotificationCompat.CATEGORY_WORKOUT)
    .setContentIntent(pendingIntent)
    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
    .setOngoing(true) // Important!

OngoingActivity oluşturma

Ardından, oluşturucusunu kullanarak OngoingActivity örneği oluşturun. OngoingActivity.Builder için Context, bildirim kimliği ve önceki adımda oluşturduğunuz NotificationCompat.Builder gerekir.

Yeni kullanıcı arayüzü yüzeylerinde gösterilecek anahtar özelliklerini yapılandırın:

  • Animasyonlu ve statik simgeler: Etkin ve ambiyans modlarında saat yüzünde gösterilen simgeler sağlayın.
  • Dokunma amacı: Kullanıcı, devam eden etkinlik simgesine dokunduğunda onu uygulamanıza geri getiren bir PendingIntent. Önceki adımda oluşturulan pendingIndent yeniden kullanılabilir.

val ongoingActivity =
    OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
        // Sets the icon that appears on the watch face in active mode.
        .setAnimatedIcon(R.drawable.animated_walk)
        // Sets the icon that appears on the watch face in ambient mode.
        .setStaticIcon(R.drawable.ic_walk)
        // Sets the tap target to bring the user back to the app.
        .setTouchIntent(pendingIntent)
        .build()

Bildirime ve gönderiye uygulanır.

Son adım, OngoingActivity ile bildirimi bağlayıp yayınlamaktır. ongoingActivity.apply() yöntemi, orijinal bildirim oluşturucuyu değiştirerek gerekli verileri ekler. Böylece sistem, bildirimi ek yüzeylerde gösterebilir. Bu özelliği uyguladıktan sonra bildirimi her zamanki gibi oluşturup yayınlayabilirsiniz.

// This call modifies notificationBuilder to include the ongoing activity data.
ongoingActivity.apply(applicationContext)

// Post the notification.
startForeground(NOTIFICATION_ID, notificationBuilder.build())

Başlatıcıya dinamik durum metni ekleme

Yukarıdaki kod, dokunulabilir simgeyi kol saatine ekler. Başlatıcının Son Kullanılanlar bölümünde daha da zengin ve anlık güncellemeler sağlamak için Status nesnesi oluşturup OngoingActivity öğenize ekleyin . Özel bir Status sağlamazsanız sistem, varsayılan olarak bildirimin içerik metnini (setContentText() kullanılarak ayarlanır) kullanır.

Dinamik metin görüntülemek için Status.Builder kullanın. Yer tutucular içeren bir şablon dizesi tanımlayabilir ve bu yer tutucuları doldurmak için Status.Part nesneleri sağlayabilirsiniz. Status.Part, kronometre veya zamanlayıcı gibi dinamik olabilir .

Aşağıdaki örnekte, "[Kronometre] için koş" ifadesini gösteren bir durumun nasıl oluşturulacağı gösterilmektedir:

// Define a template with placeholders for the activity type and the timer.
val statusTemplate = "#type# for #time#"

// Set the start time for a stopwatch.
// Use SystemClock.elapsedRealtime() for time-based parts.
val runStartTime = SystemClock.elapsedRealtime()

val ongoingActivityStatus = Status.Builder()
    // Sets the template string.
    .addTemplate(statusTemplate)
    // Fills the #type# placeholder with a static text part.
    .addPart("type", Status.TextPart("Run"))
    // Fills the #time# placeholder with a stopwatch part.
    .addPart("time", Status.StopwatchPart(runStartTime))
    .build()

Son olarak, Status cihazını OngoingActivity cihazınıza bağlamak için OngoingActivity.Builder üzerinden setStatus()'ı arayın.

val ongoingActivity =
    OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
        // ...
        // Add the status to the OngoingActivity.
        .setStatus(ongoingActivityStatus)
        .build()

Ek özelleştirmeler

Status dışında, devam eden etkinliğinizi veya bildirimlerinizi aşağıdaki şekillerde özelleştirebilirsiniz. Ancak bu özelleştirmeler, OEM'nin uygulamasına bağlı olarak 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 senkron iletişim isteği
    • CATEGORY_NAVIGATION: Harita veya adım adım navigasyon
    • CATEGORY_TRANSPORT: Oynatma için medya taşıma kontrolü
    • CATEGORY_ALARM: alarm veya zamanlayıcı
    • CATEGORY_WORKOUT: antrenman
    • CATEGORY_LOCATION_SHARING: geçici konum paylaşımı kategorisi)
    • CATEGORY_STOPWATCH: Kronometre

Devam Eden Etkinlik

  • Animasyonlu simge: Tercihen şeffaf arka planı olan siyah beyaz bir vektör. Etkin modda kadran üzerinde gösterilir. Animasyonlu simge sağlanmazsa varsayılan bildirim simgesi kullanılır. Varsayılan bildirim simgesi her uygulamada farklıdır.

  • Statik simge: Şeffaf arka plana sahip bir vektör simgesi. Ambiyans modunda saat kadranında gösterilir. Hareketli simge ayarlanmamışsa aktif modda kadranda statik simge kullanılır. Bu sağlanmazsa bildirim simgesi kullanılır. İkisi de ayarlanmamışsa istisna oluşturulur. (Uygulama başlatıcı, uygulama simgesini kullanmaya devam eder.)

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

  • Dokunma Amacı: Kullanıcı devam eden etkinlik simgesine dokunduğunda uygulamaya geri dönmek için kullanılan bir PendingIntent. Kadranda veya başlatıcı öğesinde gösterilir. Uygulamayı başlatmak için kullanılan orijinal amaçtan farklı olabilir. Bu bilgi sağlanmazsa bildirimin içerik amacı kullanılır. İkisi de ayarlanmamışsa istisna oluşturulur.

  • LocusId: Devam eden etkinliğin karşılık geldiği başlatıcı kısayolunu atayan kimlik. Etkinlik devam ederken başlatıcıdaki Son Arananlar bölümünde gösterilir. Sağlanmazsa başlatıcı, aynı paketteki Son Kullanılanlar bölümündeki tüm uygulama öğelerini gizler ve yalnızca devam eden etkinliği gösterir.

  • Devam Eden Etkinlik Kimliği: Bir uygulamada birden fazla devam eden etkinlik olduğunda fromExistingOngoingActivity() çağrılarını netleş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 yeni bir devam eden etkinlik oluşturur. Ancak Ongoing Activity API, bir örneği yeniden oluşturmak yerine korumak istiyorsanız OngoingActivity güncellemek için yardımcı yöntemler de sunar.

Uygulama arka planda çalışıyorsa Devam Eden Etkinlik API'sine güncellemeler gönderebilir. Ancak güncelleme yöntemi birbirine çok yakın çağrıları yoksaydığı için bunu çok sık yapmayın. Dakikada birkaç güncelleme makuldür.

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() işlevini çağırın:

ongoingActivity.update(context, newStatus)

Kolaylık sağlamak için devam eden bir etkinlik oluşturmaya yönelik statik bir yöntem vardır.

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

Devam eden bir etkinliği durdurma

Uygulama, devam eden etkinlik olarak çalışmayı tamamladığında yalnızca devam eden bildirimi iptal etmesi gerekir.

Ayrıca, bildirim veya devam eden etkinlik ön plana geldiğinde bunları iptal edip arka plana döndüğünüzde yeniden oluşturmayı da seçebilirsiniz ancak bu işlem zorunlu değildir.

Devam eden bir etkinliği duraklatma

Uygulamanızda açık bir durdurma işlemi varsa devam eden etkinliği duraklatma işlemi kaldırıldıktan sonra devam ettirin. Açıkça durdurma işlemi olmayan bir uygulamada, etkinlik duraklatıldığında sonlandırılır.

En iyi uygulamalar

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

  • Devam Eden Etkinliğiniz için açıkça veya bildirim kullanılarak yedek olarak statik bir simge ayarlayın. Aksi takdirde IllegalArgumentException alırsınız.

  • Şeffaf arka planlı siyah beyaz vektör simgeler kullanın.

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

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

Wear OS cihazlarda medya oynatılırken medya bildirimleri yayınlama

Wear OS cihazda medya içeriği oynatılıyorsa medya bildirimi yayınlayın. Bu sayede sistem, ilgili devam eden etkinliği oluşturabilir.

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