Android 12 New Bluetooth Permissions
Solution 1
This was a platform bug. Google fixed the bug in the new Android 12 Beta version.
Solution 2
100% working solution : no need any 3rd party plugin
manifest code:
<!--BLUETOOTH PERMISSION-->
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- Needed only if your app looks for Bluetooth devices.
If your app doesn't use Bluetooth scan results to derive physical
location information, you can strongly assert that your app
doesn't derive physical location. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<!-- Needed only if your app makes the device discoverable to Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- Needed only if your app communicates with already-paired Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!--bibo01 : hardware option-->
<uses-feature android:name="android.hardware.bluetooth" android:required="false"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
Kotlin code:
//check android12+
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)
}
....................................................
private var requestBluetooth = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
//granted
}else{
//deny
}
}
private val requestMultiplePermissions =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
permissions.entries.forEach {
Log.d("test006", "${it.key} = ${it.value}")
}
}
Read more: https://developer.android.com/guide/topics/connectivity/bluetooth/permissions
Solution 3
I just added to the manifest:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
and then I requested those permissions from Main Activity as any other. For requesting permission I am using library
implementation 'pub.devrel:easypermissions:3.0.0'
then you can just call this function
public static final String[] BLUETOOTH_PERMISSIONS_S = { Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT} ;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (!EasyPermissions.hasPermissions(this, BLUETOOTH_PERMISSIONS_S)) {
EasyPermissions.requestPermissions(this, message, yourRequestCode,BLUETOOTH_PERMISSIONS_S);
}
}
and override onRequestPermissionResult
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
UPDATE FOR JETPACK COMPOSE
If you are using jetpack compose you can handle it like this:
Create a list of your permissions inside of rememberMultiplePermissionState function
rememberMultiplePermissionsState(
permissions = listOf(
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.BLUETOOTH_SCAN
)
)
Then observe a lifecycle events and on resume launch permission request
val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(key1 = lifecycleOwner,
effect = {
val observer = LifecycleEventObserver { _, event ->
if(event == Lifecycle.Event.ON_START) {
permissionsState.launchMultiplePermissionRequest()
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
})
Observe the permission state
permissionsState.permissions.forEach { permissionState ->
when(permissionState.permission) {
Manifest.permission.ACCESS_FINE_LOCATION -> {
when {
permissionState.hasPermission -> {}
}
}
}
}
}
Solution 4
This worked for me,
In the manifest, add the following permissions:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Then, before executing a Bluetooth function, check the permission:
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_DENIED)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
{
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.BLUETOOTH_CONNECT}, 2);
return;
}
}
For an example,
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_DENIED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.BLUETOOTH_CONNECT}, 2);
return;
}
}
mBTSocket.connect();
Related videos on Youtube
![Mustafa Kuloğlu](https://lh3.googleusercontent.com/-Ndox2xvobcY/AAAAAAAAAAI/AAAAAAAACt4/Ewwq-t5btOM/photo.jpg?sz=256)
Mustafa Kuloğlu
Android Developer from Carly Connected Car. Interested in Linux, Linux kernel, and hardware. Curious about Artificial intelligence and machine learning.
Updated on March 07, 2022Comments
-
Mustafa Kuloğlu over 2 years
Bluetooth is the main dependency of our app. So, We already try to implement new Android 12 Bluetooth permissions. Our only resource is Android developers New Bluetooth permissions in Android 12. There is just saying add permissions
"android.permission.BLUETOOTH_CONNECT"
"android.permission.BLUETOOTH_SCAN"
I add and I got runtime permissions for both and of course location(usual as pre 12)).
There is no other change in my codebase. Should be? I don't know. So, the problem is my app can't find the BLE device. I couldn't find the reason.Do you have any suggestions or resources?
-
Dinkar Kumar about 3 yearsnot able to find BLE device on Android 12 or pre 12 as well?
-
or_dvir about 3 yearsi am trying to add these permissions too but they dont exist in android studio... i only see the old ones (BLUETOOTH, BLUETOOTH_ADMIN, BLUETOOTH_ADMIN_PRIVILEGED). i set my targetSdkVersion to "S", my compileSdkVersion to "android-S", and my buildToolsVersion to "3.0.0-rc5". any idea?
-
Mustafa Kuloğlu about 3 yearsI can see. My settings like this: compileSdkVersion "android-S" buildToolsVersion "30.0.3" targetSdkVersion 31
-
-
Mustafa Kuloğlu about 3 yearsThanks for your answer Barney and sorry for didn't mention it before but
BLUETOOTH_ADMIN
is already added. It is not working with that also. -
RaJ over 2 yearsWorking Fine. But Why Nearbyshare permission showing?
-
ocramot over 2 yearsNot totally working for me, I'm on Android 10. I don't see any popup asking for permissions, I immediately get to the part where the permissions are granted.