Skip to content

Commit 1cd89ba

Browse files
authored
Merge pull request #137 from garanj/main
Adds check for Wearable API
2 parents aae3e1e + 6478983 commit 1cd89ba

File tree

4 files changed

+91
-22
lines changed

4 files changed

+91
-22
lines changed

watchface/src/main/java/com/android/developers/androidify/watchface/creator/Signer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import java.security.cert.X509Certificate
3939
import java.util.Calendar
4040
import java.util.Date
4141

42-
private val keyAlias : String
42+
private val keyAlias: String
4343
get() = "com.android.developers.androidify.ApkSigningKey-" + BuildConfig.BUILD_TYPE
4444
private val certAlias: String
4545
get() = "com.android.developers.androidify.Cert-" + BuildConfig.BUILD_TYPE

watchface/src/main/java/com/android/developers/androidify/watchface/transfer/WearAssetTransmitter.kt

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,30 @@ class WearAssetTransmitterImpl @Inject constructor(
8282
*/
8383
override val watchFaceInstallationUpdates = callbackFlow {
8484
trySend(WatchFaceInstallationStatus.NotStarted)
85-
val listener = MessageClient.OnMessageReceivedListener { event ->
86-
if (event.path.contains(transferId)) {
87-
val response =
88-
ProtoBuf.decodeFromByteArray<WatchFaceInstallationStatus.Complete>(event.data)
89-
if (response.transferId == transferId) {
90-
trySend(response)
85+
86+
var listener: MessageClient.OnMessageReceivedListener? = null
87+
88+
/**
89+
* Some devices don't have access to Wearable API via Play Services, so it is necessary to
90+
* check for this scenario first before trying to use the API.
91+
*/
92+
val apiAvailable = WearableApiAvailability.isAvailable(messageClient)
93+
if (apiAvailable) {
94+
listener = MessageClient.OnMessageReceivedListener { event ->
95+
if (event.path.contains(transferId)) {
96+
val response =
97+
ProtoBuf.decodeFromByteArray<WatchFaceInstallationStatus.Complete>(event.data)
98+
if (response.transferId == transferId) {
99+
trySend(response)
100+
}
91101
}
92102
}
103+
messageClient.addListener(listener).await()
93104
}
94-
95-
messageClient.addListener(listener).await()
96-
97105
awaitClose {
98-
messageClient.removeListener(listener).addOnSuccessListener { }
106+
listener?.let {
107+
messageClient.removeListener(it).addOnSuccessListener { }
108+
}
99109
}
100110
}
101111

watchface/src/main/java/com/android/developers/androidify/watchface/transfer/WearDeviceRepository.kt

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,39 @@ class WearDeviceRepositoryImpl @Inject constructor(
4545
private val capabilityClient: CapabilityClient by lazy { Wearable.getCapabilityClient(context) }
4646

4747
override val connectedWatch = callbackFlow {
48-
val allDevices = nodeClient.connectedNodes.await().toSet()
49-
val reachableCapability =
50-
capabilityClient.getCapability(ANDROIDIFY_INSTALLED, CapabilityClient.FILTER_REACHABLE)
51-
.await()
48+
var capabilityListener: CapabilityClient.OnCapabilityChangedListener? = null
5249

53-
val installedDevices = reachableCapability.nodes.toSet()
50+
/**
51+
* Some devices don't have access to Wearable API via Play Services, so it is necessary to
52+
* check for this scenario first before trying to use the API.
53+
*/
54+
val apiAvailable = WearableApiAvailability.isAvailable(nodeClient)
55+
if (apiAvailable) {
56+
val allDevices = nodeClient.connectedNodes.await().toSet()
57+
val reachableCapability =
58+
capabilityClient.getCapability(
59+
ANDROIDIFY_INSTALLED,
60+
CapabilityClient.FILTER_REACHABLE,
61+
)
62+
.await()
5463

55-
trySend(selectConnectedDevice(installedDevices, allDevices))
64+
val installedDevices = reachableCapability.nodes.toSet()
65+
trySend(selectConnectedDevice(installedDevices, allDevices))
5666

57-
val capabilityListener = CapabilityClient.OnCapabilityChangedListener { capabilityInfo ->
58-
val installedDevicesUpdated = capabilityInfo.nodes.toSet()
67+
capabilityListener =
68+
CapabilityClient.OnCapabilityChangedListener { capabilityInfo ->
69+
val installedDevicesUpdated = capabilityInfo.nodes.toSet()
5970

60-
trySend(selectConnectedDevice(installedDevicesUpdated, allDevices))
71+
trySend(selectConnectedDevice(installedDevicesUpdated, allDevices))
72+
}
73+
capabilityClient.addListener(capabilityListener, ANDROIDIFY_INSTALLED)
74+
} else {
75+
trySend(null)
6176
}
62-
capabilityClient.addListener(capabilityListener, ANDROIDIFY_INSTALLED)
6377
awaitClose {
64-
capabilityClient.removeListener(capabilityListener)
78+
capabilityListener?.let {
79+
capabilityClient.removeListener(it)
80+
}
6581
}
6682
}
6783

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.android.developers.androidify.watchface.transfer
17+
18+
import android.util.Log
19+
import com.google.android.gms.common.GoogleApiAvailability
20+
import com.google.android.gms.common.api.AvailabilityException
21+
import com.google.android.gms.common.api.GoogleApi
22+
import kotlinx.coroutines.tasks.await
23+
24+
/**
25+
* Checks whether a given Wearable Data Layer API is available on this device.
26+
*/
27+
object WearableApiAvailability {
28+
suspend fun isAvailable(api: GoogleApi<*>) = try {
29+
GoogleApiAvailability.getInstance()
30+
.checkApiAvailability(api)
31+
.await()
32+
33+
true
34+
} catch (e: AvailabilityException) {
35+
Log.d(
36+
TAG,
37+
"${api.javaClass.simpleName} API is not available in this device.",
38+
)
39+
false
40+
}
41+
}
42+
43+
private const val TAG = "WearableApiAvailability"

0 commit comments

Comments
 (0)