Devam eden etkinlikleri görüntüleme

Wear OS cihazlar genellikle antrenman 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.

Devam Eden Etkinlikler, uygulamanızın daha uzun süre görünür kalmasını sağlayarak sistemin belirli bir süre işlem yapılmadığında saat yüzüne dönmesini de engeller. Daha fazla bilgi için Uygulamanızı Wear'da görünür tutma başlıklı makaleyi inceleyin.

Ö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

Şekil 1. Etkinlik göstergesi.

Devam eden bir bildirim, genel 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. Global başlatıcı.

Aşağıdaki durumlarda, devam eden bir etkinliğe bağlı olarak devam eden bildirim kullanmak iyi bir fikirdir:

zamanlayıcı

Şekil 3. Zamanlayıcı: Zamanı aktif olarak geri sayar ve zamanlayıcı 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

Şekil 5. 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'yi 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.18.0"
}

Devam eden 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 Etkinlik'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 kadran üzerinde 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 uygula

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 kadranına ekler. Başlatıcının Son Kullanılanlar bölümünde daha da zengin ve anlık güncellemeler sunmak 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

  • Belirlenen 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 kadran üzerinde gösterilir. Hareketli simge ayarlanmamışsa etkin modda kadran üzerinde statik simge kullanılır. Bu sağlanmazsa bildirim simgesi kullanılır. İkisi de ayarlanmamışsa bir 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. Kadran üzerinde 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. Belirtilmezse başlatıcı, Son Kullanılanlar bölümündeki aynı pakete ait 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

Durumu değiştirmeniz gerektiğinde yeni bir bildirim ve devam eden etkinlik oluşturmak yerine mevcut bildirimin devam eden etkinliğini güncellemeniz gerekir. 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)

OngoingActivity'ye referans depolamanın mümkün olmadığı durumlarda OngoingActivity'yi kurtarmak için statik bir yöntem vardır. Ancak bu yöntem daha az tercih edilir:

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 kaldırıldıktan sonra devam ettirin. Açıkça durdurma işlemi olmayan bir uygulamada, etkinlik duraklatıldığında sonlandırılır.

Göz önünde bulundurulması gereken önemli noktalar

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 tanımlanmışsa dinamik 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.