我创建了连接到 BLE 设备的 Jetpack compose Android 应用程序。 BLE 设备更新其状态并将数据发送到应用程序。之前我使用过 Android 11 设备,现在我已将设备更新为具有 Android 14 的设备。
我在尝试使用 Android 14 向应用程序发送数据时遇到问题。我使用的是 Nordic Semiconductors Android BLE 库 v2.9.0。在 Android 端,我收到如下特征更改:
private val dataReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val action = intent!!.action
Log.i(tag, "This is the action $action")
try {
when (action) {
bluetoothManager.actionConnected -> {
}
bluetoothManager.actionDisconnected -> {
}
bluetoothManager.actionDataAvailable -> {
}
bluetoothManager.actionInfoAvailable -> {
}
bluetoothManager.actionError -> {
}
}
} catch (e: Exception) {
Log.e(tag, "onReceive ${e.stackTraceToString()}")
}
在 Android 11 中使用完全相同相同的代码(不包括 BLE 权限)时,我正常接收数据,并且在日志中我按预期得到“这是操作 ACTION_DATA_AVAILABLE”。使用 Android 14,我可以获得状态更新,例如“这是已连接的操作”和“这是已断开的操作”,但由于某种原因,它没有注册“这是操作 ACTION_DATA_AVAILABLE”。当改回使用 Android 11 的手机时,一切都按预期运行。我还验证了代码适用于 Android 12。现在仅在 Android 14 上出现问题。
这可能是什么原因造成的?我需要考虑一些安全问题吗?
确保您已正确定义蓝牙权限。例如,在清单中,您可以在下面的代码中看到。
// Required permissions in AndroidManifest.xml
/*
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
*/
private val dataReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (context == null || intent == null) return
val action = intent.action ?: return
Log.i(tag, "This is the action $action")
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
// Check runtime permissions for Android 14+
if (context.checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT)
!= PackageManager.PERMISSION_GRANTED) {
Log.e(tag, "Missing BLUETOOTH_CONNECT permission")
return
}
}
when (action) {
bluetoothManager.actionConnected -> {
handleConnected()
}
bluetoothManager.actionDisconnected -> {
handleDisconnected()
}
bluetoothManager.actionDataAvailable -> {
handleDataAvailable(intent)
}
bluetoothManager.actionInfoAvailable -> {
handleInfoAvailable(intent)
}
bluetoothManager.actionError -> {
handleError(intent)
}
}
} catch (e: Exception) {
Log.e(tag, "onReceive ${e.stackTraceToString()}")
}
}
}
// Register receiver with explicit intent filters
private fun registerReceiver() {
val filter = IntentFilter().apply {
addAction(bluetoothManager.actionConnected)
addAction(bluetoothManager.actionDisconnected)
addAction(bluetoothManager.actionDataAvailable)
addAction(bluetoothManager.actionInfoAvailable)
addAction(bluetoothManager.actionError)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
context.registerReceiver(dataReceiver, filter, Context.RECEIVER_NOT_EXPORTED)
} else {
context.registerReceiver(dataReceiver, filter)
}
}
// Don't forget to unregister
override fun onDestroy() {
super.onDestroy()
try {
context.unregisterReceiver(dataReceiver)
} catch (e: Exception) {
Log.e(tag, "Error unregistering receiver: ${e.message}")
}
}
并确保您的代码已注册接收器。处理蓝牙访问权限的逻辑。您可以在上面查看我的示例代码,以帮助您了解解决方案。 :)