Keywords: Android 12 | Bluetooth Permissions | Platform Bug | BLUETOOTH_SCAN | BLUETOOTH_CONNECT
Abstract: This article delves into the new Bluetooth permission system introduced in Android 12 (BLUETOOTH_SCAN, BLUETOOTH_CONNECT, etc.), analyzing typical issues developers face, such as failure to discover devices. Based on high-scoring Stack Overflow answers, it reveals that this problem was a platform bug in early Android 12, fixed by Google in subsequent Beta versions. The article systematically covers core concepts including permission configuration, runtime requests, and compatibility handling, with complete code examples and best practices to help developers avoid common pitfalls and ensure stable Bluetooth functionality on Android 12 and above.
Major Overhaul of Bluetooth Permission Architecture in Android 12
With the release of Android 12, Google restructured the Bluetooth permission system, introducing a more granular control mechanism. Traditionally, Android apps only needed to declare BLUETOOTH and BLUETOOTH_ADMIN permissions for most Bluetooth operations. However, starting from Android 12, three new runtime permissions were added: BLUETOOTH_SCAN (for scanning Bluetooth devices), BLUETOOTH_ADVERTISE (for making the device discoverable), and BLUETOOTH_CONNECT (for communicating with paired devices). These changes aim to enhance user privacy protection, requiring apps to explicitly declare their Bluetooth usage intent.
Typical Issue in Developer Practice: Device Discovery Failure After Permission Configuration
Many developers, while adapting to Android 12, added the new permission declarations as per official documentation and requested runtime permissions, but still encountered issues where Bluetooth Low Energy (BLE) devices could not be discovered. For example, in Stack Overflow discussions, a developer reported: "I added BLUETOOTH_SCAN and BLUETOOTH_CONNECT permissions and obtained runtime grants (along with the usual location permissions pre-Android 12), but the app still cannot find BLE devices." Such problems often confuse developers, as the permission setup seems correct, yet functionality fails.
Core Discovery: Confirmation and Fix of Platform Bug
According to a high-scoring Stack Overflow answer (Answer 3, score 10.0), this issue was confirmed as a platform bug in early Android 12. Google fixed this bug in subsequent Android 12 Beta versions. This means that even if developers fully followed the permission guidelines, Bluetooth scanning functionality could still be abnormal in bug-affected versions. This highlights the importance of timely updates to Android system versions and testing environments. Developers should monitor official changelogs and consider platform compatibility factors first when encountering similar issues.
Complete Permission Configuration and Code Implementation
To ensure compatibility, it is recommended to declare all relevant permissions in AndroidManifest.xml, including legacy permissions for devices below Android 12. Here is an example configuration:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-feature android:name="android.hardware.bluetooth" android:required="false"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
In Kotlin code, permissions must be requested dynamically based on the Android version. For Android 12 and above, use ActivityResultContracts.RequestMultiplePermissions to request BLUETOOTH_SCAN and BLUETOOTH_CONNECT; for older versions, enable the Bluetooth adapter. Here is a simplified example:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
requestMultiplePermissions.launch(arrayOf(
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_CONNECT))
} else {
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
requestBluetooth.launch(enableBtIntent)
}
Supplementary Practices: Permission Checks and Error Handling
Referring to other answers (e.g., Answer 1 and Answer 2), permission checks should be performed before executing Bluetooth operations. For example, before connecting to a Bluetooth device, verify if BLUETOOTH_CONNECT permission is granted:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_DENIED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.BLUETOOTH_CONNECT), REQUEST_CODE)
return
}
}
// Execute Bluetooth connection operation
mBTSocket.connect()
Additionally, handle cases where users deny permissions and provide user-friendly prompts. For example, in the onRequestPermissionsResult callback, check permission results and take appropriate actions.
Conclusion and Best Practice Recommendations
The Bluetooth permission changes in Android 12 represent a trend towards privacy protection, requiring developers to adapt proactively. Key steps include: declaring all necessary permissions in the manifest, dynamically requesting runtime permissions based on version, and updating testing environments promptly to avoid platform bugs. It is recommended to refer to official documentation (e.g., Android Bluetooth Permissions Guide) for the latest information. By systematically implementing these measures, apps can ensure stable and reliable Bluetooth functionality on Android 12 and above, enhancing user experience.