diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 5b9e919b..59ae1b62 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -73,12 +73,13 @@ validatorPush = "1.0.0-alpha08"
version-catalog-update = "1.0.0"
watchfaceComplicationsDataSourceKtx = "1.2.1"
wear = "1.3.0"
-wearComposeFoundation = "1.5.0-rc02"
-wearComposeMaterial = "1.5.0-rc02"
-wearComposeMaterial3 = "1.5.0-rc02"
+wearComposeFoundation = "1.5.2"
+wearComposeMaterial = "1.5.2"
+wearComposeMaterial3 = "1.5.2"
wearOngoing = "1.1.0"
wearToolingPreview = "1.0.0"
webkit = "1.14.0"
+media3Ui = "1.8.0"
[libraries]
accompanist-adaptive = "com.google.accompanist:accompanist-adaptive:0.37.3"
@@ -196,6 +197,7 @@ play-services-wearable = { module = "com.google.android.gms:play-services-wearab
validator-push = { module = "com.google.android.wearable.watchface.validator:validator-push", version.ref = "validatorPush" }
wear-compose-material = { module = "androidx.wear.compose:compose-material", version.ref = "wearComposeMaterial" }
wear-compose-material3 = { module = "androidx.wear.compose:compose-material3", version.ref = "wearComposeMaterial3" }
+androidx-media3-ui = { group = "androidx.media3", name = "media3-ui", version.ref = "media3Ui" }
[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
diff --git a/wear/build.gradle.kts b/wear/build.gradle.kts
index d88421c1..4c3c9405 100644
--- a/wear/build.gradle.kts
+++ b/wear/build.gradle.kts
@@ -53,6 +53,8 @@ android {
dependencies {
implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.media3.exoplayer)
+ implementation(libs.androidx.media3.ui)
val composeBom = platform(libs.androidx.compose.bom)
implementation(composeBom)
androidTestImplementation(composeBom)
diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml
index a70ca62d..b2732aae 100644
--- a/wear/src/main/AndroidManifest.xml
+++ b/wear/src/main/AndroidManifest.xml
@@ -72,6 +72,11 @@
+
+
?) {
+ super.onAudioDevicesAdded(addedDevices)
+ if (audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP) ||
+ audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_BROADCAST) ||
+ audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_HEADSET) ||
+ audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_SPEAKER)
+ ) {
+ // A Bluetooth or BLE device is connected and available for playback.
+ }
+ }
+ override fun onAudioDevicesRemoved(removedDevices: Array?) {
+ super.onAudioDevicesRemoved(removedDevices)
+ if (!(audioOutputAvailable(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP)) &&
+ !(audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_BROADCAST)) &&
+ !(audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_HEADSET)) &&
+ !(audioOutputAvailable(AudioDeviceInfo.TYPE_BLE_SPEAKER))
+ ) {
+ // No Bluetooth or BLE devices are connected anymore.
+ }
+ }
+ }
+
+ audioManager.registerAudioDeviceCallback(audioDeviceCallback, /*handler=*/ null)
+ // [END android_wear_audio_register_callback]
+ }
+}
diff --git a/wear/src/main/java/com/example/wear/snippets/audio/BluetoothSettings.kt b/wear/src/main/java/com/example/wear/snippets/audio/BluetoothSettings.kt
new file mode 100644
index 00000000..d2ebbd13
--- /dev/null
+++ b/wear/src/main/java/com/example/wear/snippets/audio/BluetoothSettings.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2025 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.audio
+
+import android.content.Context
+import android.content.Intent
+import android.provider.Settings
+
+object BluetoothSettings {
+ // [START android_wear_bluetooth_settings]
+ fun Context.launchBluetoothSettings(closeOnConnect: Boolean = true) {
+ val intent = with(Intent(Settings.ACTION_BLUETOOTH_SETTINGS)) {
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ putExtra("EXTRA_CONNECTION_ONLY", true)
+ if (closeOnConnect) {
+ putExtra("EXTRA_CLOSE_ON_CONNECT", true)
+ }
+ putExtra("android.bluetooth.devicepicker.extra.FILTER_TYPE", FILTER_TYPE_AUDIO)
+ }
+ startActivity(intent)
+ }
+
+ internal const val FILTER_TYPE_AUDIO = 1
+ // [END android_wear_bluetooth_settings]
+}