Android permissions for Bluetooth

Konstantinos Mihelis
4 min readMay 18, 2022

--

While creating a simple Android app that uses the Bluetooth APIs I stumbled the most in the very first and expectedly easiest step of the process: Setting the right permissions for my App. 😥😥😥

Let me tell you the issue so that nobody has to lose more hours on this trivial thing in the future. 😉

To begin with, I followed the official instructions provided for Bluetooth permissions targeting devices of Android 11 and 12. For older devices, the permissions change a bit but the process is the same.

Generally speaking, when you need permissions in an App you specify them at your Manifest and if they are considered dangerous you also request them at runtime…Easy right? 😉

So my manifest file looked like this:

Since my app was discovering other devices and not the other way around I didn't use android.permission.BLUETOOTH_ADVERTISE (API 31+) but you may need to include it…

Bluetooth permissions are considered of the dangerous type so you must request them at runtime.

Now what needed to be done is to ask for runtime permissions when the app was running (and preferably when the Bluetooth API needed it and not before).

So since my app was fairly simple, I had a button that initiated a devices list scan and then I had the permissions pop-up prompt show up….

The LATEST WAY of asking for permissions is to use ActivityResultContract either for single or multiple permissions. That was done like this (code is for composable functions and multiple permissions):

Don't bother with the function extraLocationPermissionRequest() just yet….

And the permissions required were:

By correctly handling the results for the permissions according to personal preferences this article should have finished here….

But unfortunately the App didn't work as intended in my phone (with Android 11 installed).🤔

Let's see now the extra steps that are needed for the app to work.

First, remember the function extraLocationPermissionRequest()? Well in Android 11 you need to request an extra permission for Manifest.permission.ACCESS_BACKGROUND_LOCATION in order for the app to allow you to use Bluetooth correctly.

So i used this function to take the user to another settings screen after he accepts the first permissions like this:

I am using general purpose functions so take your time to study the code above…🧐

After this extra step is made the user now must select the "Allow all the time" option from the settings screen.

https://developer.android.com/training/location/permissions#background-dialog-target-sdk-version

Now all these steps are documented although you have to poke around a lot to get them in order.

The last part is something that is NOT documented!

Android official documentation gives us specific steps that are illustrated below:

So after declaring permissions in the Manifest and after the user consented to runtime permissions everything should work as intended right? right? RIGHT?😮‍💨

Well… the Bluetooth never worked for my phone doing just the above… And it was by sheer luck that i found out the problem for this… You don't need to just give runtime access to bluetooth and location for your app.

You must have Bluetooth and Location services enabled!

Enabling Bluetooth was already part of my process, but enabling GPS was something that took me hours to figure out… So if you want to scan for example for nearby Bluetooth devices then Location services must be enabled….

So as final step you add this piece of code (wherever you like)…

… and you are done. Bluetooth is working just fine.🎉🎉🎉

I hope my article is of any help to fellow developers that have not used Bluetooth before…

As an extra note i want to add that in the process of making my App work i tried also using Companion Device manager. The documentation is straightforward for this API and i managed to easily set it up correctly and got it working… BUT! I had to also enable Location Services for my app to be able to discover devices AND if you want to do anything more with the device you pair with (for example exchange data), you must request runtime permissions. So although i got it working i didn't use it after all.

The Android app I made is a simple App that communicates with a Raspberry Pi for a Google funded project I participated and the full code can be found here if you want:

--

--