Wear'da Veri Katmanı etkinliklerini işleme

Data tier API'ye bir çağrı yaptığınızda, çağrı tamamlandığında çağrının durumunu alabilirsiniz. Uygulamanızın Wear OS by Google ağındaki herhangi bir yerde yaptığı veri değişikliklerinden kaynaklanan veri etkinliklerini de dinleyebilirsiniz.

Veri Katmanı API'siyle etkili bir şekilde çalışmaya ilişkin bir örnek için Android DataKatman Örneği uygulamasına göz atın.

Veri Katmanı çağrılarının durumunu bekleyin

Data Katman API'ye yapılan çağrılar (ör. DataClient sınıfının putDataItem yöntemini kullanan bir çağrı) bazen Task<ResultType> nesnesi döndürür. Task nesnesi oluşturulur oluşturulmaz işlem arka planda sıraya alınır. Bundan sonra başka bir şey yapmazsanız işlem sonunda sessizce tamamlanır.

Bununla birlikte, genellikle işlem tamamlandıktan sonra sonuçla bir şey yapmak istersiniz. Bu nedenle Task nesnesi, eşzamansız veya eşzamanlı olarak sonuç durumunu beklemenizi sağlar.

Eşzamansız çağrılar

Kodunuz ana kullanıcı arayüzü iş parçacığında çalışıyorsa Data Katman API'ye engelleme çağrıları yapmayın. İşlem tamamlandığında tetiklenen Task nesnesine bir geri çağırma yöntemi ekleyerek çağrıları eşzamansız olarak çalıştırın:

Kotlin

// Using Kotlin function references
task.addOnSuccessListener(::handleDataItem)
task.addOnFailureListener(::handleDataItemError)
task.addOnCompleteListener(::handleTaskComplete)
...
fun handleDataItem(dataItem: DataItem) { ... }
fun handleDataItemError(exception: Exception) { ... }
fun handleTaskComplete(task: Task<DataItem>) { ... }

Java

// Using Java 8 Lambdas.
task.addOnSuccessListener(dataItem -> handleDataItem(dataItem));
task.addOnFailureListener(exception -> handleDataItemError(exception));
task.addOnCompleteListener(task -> handleTaskComplete(task));

Farklı görevlerin yürütülmesini zincirleme dahil olmak üzere diğer olasılıklar için Görev API'sine bakın.

Eşzamanlı aramalar

Kodunuz, WearableListenerService gibi bir arka plan hizmetindeki ayrı bir işleyici iş parçacığında çalışıyorsa çağrıların engellenmesi sorun oluşturmaz. Bu durumda, Task nesnesinde Tasks.await() çağırabilirsiniz. Bu çağrı, istek tamamlandıktan ve Result nesnesini döndürene kadar engelleme yapar. Bu, aşağıdaki örnekte gösterilmiştir.

Not: Ana ileti dizisindeyken bunu çağırmamaya dikkat edin.

Kotlin

try {
    Tasks.await(dataItemTask).apply {
        Log.d(TAG, "Data item set: $uri")
    }
}
catch (e: ExecutionException) { ... }
catch (e: InterruptedException) { ... }

Java

try {
    DataItem item = Tasks.await(dataItemTask);
    Log.d(TAG, "Data item set: " + item.getUri());
} catch (ExecutionException | InterruptedException e) {
  ...
}

Veri Katmanı etkinliklerini dinleme

Veri katmanı, verileri avuç içi ve giyilebilir cihazlar arasında senkronize edip gönderdiğinden, genellikle oluşturulan veri öğeleri ve alınan mesajlar gibi önemli etkinlikleri dinlemeniz gerekir.

Veri katmanı etkinliklerini dinlemek için iki seçeneğiniz vardır:

Bu seçeneklerin her ikisinde de, işlemek istediğiniz etkinlikler için veri etkinliği geri çağırma yöntemlerini geçersiz kılarsınız.

Not: İşleyici uygulaması seçerken uygulamanızın pil kullanımını göz önünde bulundurun. WearableListenerService, uygulamanın manifest dosyasında kayıtlıdır ve halihazırda çalışmıyorsa uygulamayı başlatabilir. Etkinlikleri yalnızca uygulamanız çalışırken dinlemeniz gerekiyorsa (genellikle etkileşimli uygulamalarda böyle bir durum söz konusuysa) WearableListenerService kullanmayın. Bunun yerine canlı dinleyici kaydını yapın. Örneğin, DataClient sınıfının addListener yöntemini kullanın. Bu, sistem üzerindeki yükü ve pil kullanımını azaltabilir.

WearableListenerService kullanma

Genellikle hem giyilebilir cihaz hem de avuç içi uygulamalarınızda WearableListenerService örnekleri oluşturursunuz. Ancak, uygulamalardan birindeki veri etkinlikleriyle ilgilenmiyorsanız hizmeti söz konusu uygulamada uygulamanız gerekmez.

Örneğin, veri öğesi nesnelerini ayarlayan ve alan bir avuç içi uygulamanız ve kullanıcı arayüzünü güncellemek için bu güncellemeleri dinleyen bir giyilebilir uygulamanız olabilir. Giyilebilir cihaz uygulaması hiçbir veri öğesini güncellemediğinden avuç içi uygulama, giyilebilir uygulamadan gelen veri etkinliklerini dinlemez.

WearableListenerService kullanarak dinleyebileceğiniz etkinliklerden bazıları şunlardır:

  • onDataChanged(): Bir veri öğesi nesnesi oluşturulduğunda, silindiğinde veya değiştirildiğinde, sistem bu geri çağırma işlemini tüm bağlı düğümlerde tetikler.
  • onMessageReceived(): Bir düğümden gönderilen bir mesaj, hedef düğümde bu geri çağırmayı tetikler.
  • onCapabilityChanged(): Uygulamanızın bir örneğinin reklamını yaptığı bir özellik ağda kullanılabilir hale geldiğinde, bu etkinlik bu geri çağırmayı tetikler. Yakındaki bir düğümü arıyorsanız geri çağırmada sağlanan düğümlerin isNearby() yöntemini sorgulayabilirsiniz.

Ayrıca ChannelClient.ChannelCallback tarafından sağlanan onChannelOpened() gibi etkinlikleri de dinleyebilirsiniz.

Önceki tüm etkinlikler ana iş parçacığında değil, bir arka plan iş parçacığında yürütülür.

WearableListenerService oluşturmak için aşağıdaki adımları uygulayın:

  1. WearableListenerService aralığını kapsayan bir sınıf oluşturun.
  2. onDataChanged() gibi ilgilendiğiniz etkinlikleri dinleyin.
  3. Sistemi WearableListenerService hakkında bilgilendirmek için Android manifest dosyanızda bir amaç filtresi beyan edin. Bu beyan, sistemin gerektiği şekilde hizmetinizi bağlamasına olanak tanır.

Aşağıdaki örnekte, basit bir WearableListenerService öğesinin nasıl uygulanacağı gösterilmektedir:

Kotlin

private const val TAG = "DataLayerSample"
private const val START_ACTIVITY_PATH = "/start-activity"
private const val DATA_ITEM_RECEIVED_PATH = "/data-item-received"

class DataLayerListenerService : WearableListenerService() {

    override fun onDataChanged(dataEvents: DataEventBuffer) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onDataChanged: $dataEvents")
        }

        // Loop through the events and send a message
        // to the node that created the data item.
        dataEvents.map { it.dataItem.uri }
                .forEach { uri ->
                    // Get the node ID from the host value of the URI.
                    val nodeId: String = uri.host
                    // Set the data of the message to be the bytes of the URI.
                    val payload: ByteArray = uri.toString().toByteArray()

                    // Send the RPC.
                    Wearable.getMessageClient(this)
                            .sendMessage(nodeId, DATA_ITEM_RECEIVED_PATH, payload)
                }
    }
}

Java

public class DataLayerListenerService extends WearableListenerService {
    private static final String TAG = "DataLayerSample";
    private static final String START_ACTIVITY_PATH = "/start-activity";
    private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onDataChanged: " + dataEvents);
        }

        // Loop through the events and send a message
        // to the node that created the data item.
        for (DataEvent event : dataEvents) {
            Uri uri = event.getDataItem().getUri();

            // Get the node ID from the host value of the URI.
            String nodeId = uri.getHost();
            // Set the data of the message to be the bytes of the URI.
            byte[] payload = uri.toString().getBytes();

            // Send the RPC.
            Wearable.getMessageClient(this).sendMessage(
                  nodeId,  DATA_ITEM_RECEIVED_PATH, payload);
        }
    }
}

Aşağıdaki bölümde, bu işleyiciyle intent filtresinin nasıl kullanılacağı açıklanmaktadır.

WearableListenerService ile filtre kullanma

Önceki bölümde gösterilen WearableListenerService örneğine ait amaç filtresi aşağıdaki gibi görünebilir:

<service android:name=".DataLayerListenerService" android:exported="true" tools:ignore="ExportedService" >
  <intent-filter>
      <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
      <data android:scheme="wear" android:host="*"
               android:path="/start-activity" />
  </intent-filter>
</service>

Bu filtrede DATA_CHANGED işlemi, daha önce önerilen BIND_LISTENER işleminin yerini alarak yalnızca belirli etkinliklerin uygulamanızı uyandırmasını veya başlatmasını sağlar. Bu değişiklik sistem verimliliğini artırır ve pil tüketimini ve uygulamanızla ilişkilendirilen diğer ek yükü azaltır. Bu örnekte, saat /start-activity veri öğesini, telefon ise /data-item-received mesajının yanıtını dinler.

Standart Android filtresi eşleştirme kuralları geçerlidir. Manifest başına birden fazla hizmet, hizmet başına birden fazla intent filtresi, filtre başına birden fazla işlem ve filtre başına birden fazla veri sütunu belirtebilirsiniz. Filtreler, bir joker karakter ana makinesinde veya belirli bir ana makinede eşleşebilir. Bir joker karakter ana makinesinde eşleştirmek için host="*" işlevini kullanın. Belirli bir ana makinede eşleştirmek için host=<node_id> değerini belirtin.

Ayrıca değişmez değer yol veya yol ön ekini de eşleştirebilirsiniz. Bunu yapmak için bir joker karakter veya belirli bir ana makine belirtmeniz gerekir. Aksi takdirde, sistem belirttiğiniz yolu yoksayar.

Wear OS'in desteklediği filtre türleri hakkında daha fazla bilgi için WearableListenerService API referans belgelerini inceleyin.

Veri filtreleri ve eşleştirme kuralları hakkında daha fazla bilgi için <data> manifest öğesiyle ilgili API referans belgelerine göz atın.

Amaç filtrelerini eşleştirirken iki önemli kuralı göz önünde bulundurun:

  • Amaç filtresi için şema belirtilmemişse sistem diğer tüm URI özelliklerini yoksayar.
  • Filtre için ana makine belirtilmediyse sistem tüm yol özelliklerini yoksayar.

Canlı dinleyici kullanma

Uygulamanız yalnızca kullanıcı uygulamayla etkileşimde bulunurken veri katmanı etkinliklerini önemsiyorsa her veri değişikliğini işlemek için uzun süreli bir hizmete ihtiyacı olmayabilir. Böyle bir durumda, aşağıdaki arayüzlerden birini veya daha fazlasını uygulayarak bir etkinlikteki etkinlikleri dinleyebilirsiniz:

Veri etkinliklerini dinleyen bir etkinlik oluşturmak için aşağıdakileri yapın:

  1. İstenen arayüzleri uygulayın.
  2. onCreate() veya onResume() yönteminde, Google Play hizmetlerine etkinliğinizin veri katmanı etkinliklerini dinlemekle ilgilendiğini bildirmek için Wearable.getDataClient(this).addListener(), MessageClient.addListener(), CapabilityClient.addListener() veya ChannelClient.registerChannelCallback() yöntemini çağırın.
  3. onStop() veya onPause() içinde DataClient.removeListener(), MessageClient.removeListener(), CapabilityClient.removeListener() veya ChannelClient.unregisterChannelCallback()'teki tüm dinleyicilerin kaydını iptal edin.
  4. Bir etkinlik yalnızca belirli bir yol ön ekine sahip etkinliklerle ilgileniyorsa yalnızca geçerli uygulama durumuyla ilgili verileri almak için uygun ön ek filtresine sahip bir işleyici ekleyebilirsiniz.
  5. Uyguladığınız arayüzlere bağlı olarak onDataChanged(), onMessageReceived(), onCapabilityChanged() veya ChannelClient.ChannelCallback adresindeki yöntemleri uygulayın. Bu yöntemler ana iş parçacığında çağrılır veya WearableOptions kullanarak özel bir Looper belirtebilirsiniz.

Aşağıda, DataClient.OnDataChangedListener işlevinin uygulandığı bir örnek verilmiştir:

Kotlin

class MainActivity : Activity(), DataClient.OnDataChangedListener {

    public override fun onResume() {
        Wearable.getDataClient(this).addListener(this)
    }

    override fun onPause() {
        Wearable.getDataClient(this).removeListener(this)
    }

    override fun onDataChanged(dataEvents: DataEventBuffer) {
        dataEvents.forEach { event ->
            if (event.type == DataEvent.TYPE_DELETED) {
                Log.d(TAG, "DataItem deleted: " + event.dataItem.uri)
            } else if (event.type == DataEvent.TYPE_CHANGED) {
                Log.d(TAG, "DataItem changed: " + event.dataItem.uri)
            }
        }
    }
}

Java

public class MainActivity extends Activity implements DataClient.OnDataChangedListener {

    @Override
    public void onResume() {
        Wearable.getDataClient(this).addListener(this);
    }

    @Override
    protected void onPause() {
        Wearable.getDataClient(this).removeListener(this);
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        for (DataEvent event : dataEvents) {
            if (event.getType() == DataEvent.TYPE_DELETED) {
                Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri());
            } else if (event.getType() == DataEvent.TYPE_CHANGED) {
                Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri());
            }
        }
    }
}

Canlı dinleyicilerle filtreleri kullanma

Daha önce de belirtildiği gibi, manifest tabanlı WearableListenerService nesneleri için intent filtreleri belirtebildiğiniz gibi Giyilebilir API aracılığıyla canlı dinleyici kaydederken intent filtrelerini kullanabilirsiniz. Aynı kurallar hem API tabanlı canlı işleyiciler hem de manifest tabanlı işleyiciler için geçerlidir.

İşleyiciyi bir etkinliğin onResume() yönteminde belirli bir yol veya yol ön ekiyle kaydetmek ve ardından etkinliğin onPause() yönteminden kaldırmak yaygın bir yöntemdir. İşleyicileri bu şekilde uygulamak, uygulamanızın etkinlikleri daha seçici bir şekilde almasını sağlar. Böylece, tasarımını ve verimliliğini iyileştirir.