From 8fed0b269eb566d03396f3e0f13b359edaf1ba90 Mon Sep 17 00:00:00 2001 From: garanj Date: 2026年2月24日 17:23:56 +0000 Subject: [PATCH] Adds lifecycle-aware datalayer snippets --- .../snippets/datalayer/DataLayerActivity.kt | 61 ++++++++-------- .../wear/snippets/datalayer/LifecycleAware.kt | 69 +++++++++++++++++++ 2 files changed, 101 insertions(+), 29 deletions(-) create mode 100644 wear/src/main/java/com/example/wear/snippets/datalayer/LifecycleAware.kt diff --git a/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerActivity.kt b/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerActivity.kt index 3e292148f..8780f9c00 100644 --- a/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerActivity.kt +++ b/wear/src/main/java/com/example/wear/snippets/datalayer/DataLayerActivity.kt @@ -20,12 +20,12 @@ import android.content.Context import android.graphics.Bitmap import android.graphics.BitmapFactory import androidx.activity.ComponentActivity +import androidx.lifecycle.lifecycleScope import com.example.wear.R import com.google.android.gms.common.GoogleApiAvailability import com.google.android.gms.common.api.AvailabilityException import com.google.android.gms.common.api.GoogleApi import com.google.android.gms.tasks.Task -import com.google.android.gms.tasks.Tasks import com.google.android.gms.wearable.Asset import com.google.android.gms.wearable.DataClient import com.google.android.gms.wearable.DataEvent @@ -36,9 +36,11 @@ import com.google.android.gms.wearable.PutDataMapRequest import com.google.android.gms.wearable.PutDataRequest import com.google.android.gms.wearable.Wearable import java.io.ByteArrayOutputStream -import java.io.InputStream -import java.util.concurrent.ExecutionException +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.tasks.await +import kotlinx.coroutines.withContext private const val TAG = "DataLayer" @@ -169,24 +171,29 @@ class DataLayerActivity2 : ComponentActivity(), DataClient.OnDataChangedListener dataEvents .filter { it.type == DataEvent.TYPE_CHANGED && it.dataItem.uri.path == "/image" } .forEach { event -> - val bitmap: Bitmap? = DataMapItem.fromDataItem(event.dataItem) + val asset = DataMapItem.fromDataItem(event.dataItem) .dataMap.getAsset("profileImage") - ?.let { asset -> loadBitmapFromAsset(asset) } - // Do something with the bitmap + + asset?.let { safeAsset -> + lifecycleScope.launch { + val bitmap = loadBitmapFromAsset(safeAsset) + // Do something with the bitmap + } + } } } - fun loadBitmapFromAsset(asset: Asset): Bitmap? { - // Convert asset into a file descriptor and block until it's ready - val assetInputStream: InputStream? = - Tasks.await(Wearable.getDataClient(this).getFdForAsset(asset)) - ?.inputStream + private suspend fun loadBitmapFromAsset(asset: Asset): Bitmap? = withContext(Dispatchers.IO) { + try { + val assetResult = Wearable.getDataClient(this@DataLayerActivity2) + .getFdForAsset(asset) + .await() - return assetInputStream?.let { inputStream -> - // Decode the stream into a bitmap - BitmapFactory.decodeStream(inputStream) - } ?: run { - // Requested an unknown asset + assetResult?.inputStream?.use { inputStream -> + BitmapFactory.decodeStream(inputStream) + } + } catch (e: Exception) { + e.printStackTrace() null } } @@ -215,23 +222,19 @@ private fun handleTaskComplete() { } // [END android_wear_datalayer_async_call] // [START android_wear_datalayer_sync_call] -private fun Context.sendDataSync(count: Int) { - // Create a data item with the path and data to be sent - val putDataReq: PutDataRequest = PutDataMapRequest.create("/count").run { +private fun Context.sendDataSync(count: Int) = runBlocking { + val putDataReq = PutDataMapRequest.create("/count").run { dataMap.putInt("count_key", count) asPutDataRequest() } - // Create a task to send the data to the data layer - val task: Task = Wearable.getDataClient(this).putDataItem(putDataReq) + try { - Tasks.await(task).apply { - // Add your logic here - } - } catch (e: ExecutionException) { - // TODO: Handle exception - } catch (e: InterruptedException) { - // TODO: Handle exception - Thread.currentThread().interrupt() + val result = Wearable.getDataClient(this@sendDataSync) + .putDataItem(putDataReq) + .await() + // Logic for success + } catch (e: Exception) { + // Handle failure } } // [END android_wear_datalayer_sync_call] diff --git a/wear/src/main/java/com/example/wear/snippets/datalayer/LifecycleAware.kt b/wear/src/main/java/com/example/wear/snippets/datalayer/LifecycleAware.kt new file mode 100644 index 000000000..af401466a --- /dev/null +++ b/wear/src/main/java/com/example/wear/snippets/datalayer/LifecycleAware.kt @@ -0,0 +1,69 @@ +/* + * Copyright 2026 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.wear.snippets.datalayer + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import com.google.android.gms.wearable.DataClient +import com.google.android.gms.wearable.DataEventBuffer +import com.google.android.gms.wearable.Wearable + +// [START android_wear_datalayer_lifecycle_observer] +class WearDataLayerObserver( + private val dataClient: DataClient, + private val onDataReceived: (DataEventBuffer) -> Unit +) : DefaultLifecycleObserver, DataClient.OnDataChangedListener { + + // Implementation of the DataClient listener + override fun onDataChanged(dataEvents: DataEventBuffer) { + onDataReceived(dataEvents) + } + + // Automatically register when the Activity starts + override fun onResume(owner: LifecycleOwner) { + dataClient.addListener(this) + } + + // Automatically unregister when the Activity pauses + override fun onPause(owner: LifecycleOwner) { + dataClient.removeListener(this) + } +} +// [END android_wear_datalayer_lifecycle_observer] + +// [START android_wear_datalayer_lifecycle_activity] +class DataLayerLifecycleActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + val dataClient = Wearable.getDataClient(this) + + // Create the observer and link it to the activity's lifecycle + val wearObserver = WearDataLayerObserver(dataClient) { dataEvents -> + handleDataEvents(dataEvents) + } + + lifecycle.addObserver(wearObserver) + } + + private fun handleDataEvents(dataEvents: DataEventBuffer) { + // ... filter and process events ... + } +} +// [END android_wear_datalayer_lifecycle_activity]

AltStyle によって変換されたページ (->オリジナル) /