Debugging permissions on Android (esp. bluetooth)

I have used managed workflow for many years, and had good luck at first adding react-native-ble-plx and its config plugin. Unfortunately following the release of this app, I quickly realized that permissions for Android around Bluetooth are fairly nuanced and change a lot between Android versions. I am not used to using Android Studio, expo prebuild, or any native stuff, so I am looking for some bare-bones advice on debugging permissions, and producing a binary that works, and which I can maintain into the future.

  1. I cannot afford to buy 40 Android phones, so, can I be fairly sure that Android Studio will faithfully replicate the behaviour of at least most Android devices, in regards to permissions? Will I be able to use Android studio, with expo, to debug permissions issues well?

  2. Using expo prebuild, is it safe to modify the permissions in the android manifest xml manually, and then run eas build? I have looked at authoring a config plugin but it looks fairly hard, and I would rather be in charge of keeping the xml up-to-date manually. The docs recommend against it, but don’t give details on how the flow would work, should I choose to go against that advice.

  3. Is there a better way to debug permissions?

  4. Does anyone have any general advice on Bluetooth permissions for Android? Sadly the config plugin does not produce the right permissions currently.

Thanks so much for any advice, fully in the dark here and keen to level up. Happy to contribute back in any way that seems helpful. I would be open to learning the config-plugin system just in order to work on the existing ble-plx plugin, should I be successful.

If this post is confusing, incomplete, or otherwise not good, please do just let me know.

I have concluded through some further experiments and research that
a) Android studio emulator is not able to use Bluetooth, so not a good debug tool for me.
b) Running expo prebuild, manually editing the manifest XML, and uploading with eas build does work. I am a little unsure how to best maintain this kind of system in version control.

Hi @marchingband

Yes, that’s my understanding.

Yes, but you are now on the Bare workflow, so should bear that in mind when following installation/upgrade instructions. But I am not convinced you need to be on the Bare workflow :slight_smile:

Perhaps you can use one of the cloud services that allow you to rent time on multiple devices for the purposes of testing. Not sure if that will be feasible when testing Bluetooth, though, since you presumably need at least two devices that can see each other over Bluetooth.

Sorry, I have only played briefly with Bluetooth support, so I can’t answer this, but in what way are the permissions incorrect and what changes did you make to AndroidManifest.xml to get it to the way you want it?

They can be tricky, but a config plugin for updating AndroidManifest.xml is, I think, one of the simplest ones to write. I’ve written a couple of them.

Also, if you just want to add some permissions to the list, you shouldn’t even need a config plugin. You should be able to add whatever you need to the android.permissions array in app.json.

I’ve had a brief look at the following pages which might help:

Thanks @wodin
The current config plugin adds max and min sdk versions for some permissions to the xml that are just incorrect. So the resulting binary will work on some Android versions but not others. Since we cannot override permissions like this, if I add the correct permissions via app.json, then the google play store rejects the binary due to duplicate permissions.
Further, there are some permissions that indeed should have max/min sdk version guards, but app.json cannot create them.
There are open issues but no movement.

I don’t know what choice I have other then to use bare workflow, or make a PR on the repo after learning the config plugin system.

@wodin can you link me to any good tutorials on getting started with authoring config plugins? Like you said I only need to tweak the AndroidManifest.xml, and I could then write a PR. I could at least simply follow the android docs, and test with whatever devices me and my friends have.

@wodin I just noticed mods.android.manifest would this be a good use case for that? It seems like a good way to offer a patch until the config plugin is updated.

OK, I see from those links that this is a lot more complicated than expected.

I don’t have any tutorials for you, but I think looking at example plugins that use withAndroidManifest and similar mods (e.g. withAndroidStyles) should help. I normally go looking in the various Expo repositories for config plugins that seem similar to what I want to do.

withAndroidManifest and others that work with XML files basically transform the XML file into JavaScript objects. The config plugin manipulates that. Then afterwards it gets converted back to XML and written to disk. xml2js is used for this. See xml2js - npm

I can’t claim to be an expert, but have a look at these:

For testing the config plugin I normally make changes to the code, run npx expo prebuild or npx expo prebuild --clean and compare the resulting AndroidManifest.xml (or whatever) with what I am expecting.

The official Expo config plugins try to work even if you re-run them multiple times without using the --clean option and I try to do the same.

@wodin thank you. xml2js definitely is part of what confused me, when skimming through existing plugins.
Thanks for the tips.
If I succeed at this, what would be the best way to make the plugin/mod available to others, I feel bad for anyone using the ble-plx config plugin expecting it to work, it was a long and stressful debug journey, and I am glad to have retained the client through that process :sweat_smile:

Ideally the config plugin would be included in the react-native-ble-plx project, but I see it hasn’t been updated in a couple of years. Also, I suspect Evan Bacon who wrote the expo/config-plugins one has already tried to upstream his one. So it might be best to submit a PR to the expo/config-plugins repository with the fixes.

Alternatively, create a project for it (e.g. on GitHub), and publish it as an NPM package.