Tuesday, March 17, 2015

Learning how Bluetooth works on Android, by using it

I picked up a really great LG Bluetooth headset at RadioShack during our local store's closeout. But I quickly found what a pain it was to switch between the headset and my car stereo and my home stereo. I decided to write an Android home screen widget to make this super easy (it's still in progress) but in doing that I had to learn how Bluetooth works.

My app requires me to keep on top of the status of each A2DP (media) and headset (phone call handling) device. Do I query the Bluetooth system for status on all of my devices from time to time? Or can I get notified reliably when a device's Bluetooth status changes?

It turns out that Bluetooth can give you updates when things change. And how is via Broadcast Intents.

I decided to write a small app that would receive Broadcast Intents and write them to logcat. This was easy: I created a BroadcastReceiver and advertised my desire to receive a number of Bluetooth-related Broadcast Intents in the app manifest. Then I could exercise the phone - turn Bluetooth on and off, scan for devices, pair, unpair, etc - and see what Bluetooth tells me.

There was one little problem. While the Bluetooth API documentation shows you the names of constants that are sent in the intents as extras, the intents actually contain just the values. So you have to dig through the API documentation or the source to figure out which constant name each value belongs to.

To address this I wrote the app to look up the values and return them. For some of the values I created a lookup table, but for others I used reflection. Reflection, actually, is quite useful, because it returns the names for *any* constant values - even undocumented ones - as long as they exist in the class on the device. It turns out that manufacturers add additional information to the intent, and this is one way you'll discover it. For example, I discovered that Samsung added EXTRA_GEARMANAGER_GEAR to the BluetoothDevice ACTION_FOUND intent that is sent when a device is found during discovery.

So, here's what you attach a Galaxy S4 to your development machine, run $ adb logcat -s BluetoothIntentLogger, go to the phone, run the app, go into the Bluetooth settings, scan for devices, while an LG Viper is advertising its presence:


There are five broadcast intents received. Two from BluetoothAdapter at the start and end signal the beginning and ending of the discovery process. In the middle, the LG Viper is discovered, and we learn a bit about it:
  • It's a PHONE, and a SMART_PHONE to boot (we can use that info for choosing an icon!)
  • It's an LG Viper (in my other app, I'll let the use store a different name.)
  • It's (apparently) not Samsung Gear.
  • It's pretty close by - it has a signal strength of -48 dBm.
  • It doesn't support Bluetooth Low Energy.
In verbose mode, the app will show you the constant values and data types as well.

In playing with this app, I've found that when you turn on Bluetooth, you get a list of all devices that are currently paired to the device. That's perfect for populating my app for the first time. And the receipt of Broadcast Intents when things change will provide a timely trigger for the update of my widget.

Another thing I learned is that since Android 3.1, Broadcast Intents must be associated with a running process unless the sender designates otherwise (see the section on Launch Controls, in the 3.1 API notes.)

I considered displaying the log data in an Activity or send it to a pastebin, but that seems unnecessary, so logcat will remain the output mechanism for now.

Get BluetoothIntentLogger on Github

11 comments:

  1. Thank you so much for your blog. I have been using it as reference for my students during Android Course in Chennai. It has been so much useful, keep writing more :)

    ReplyDelete
  2. Nice info about blutooth. Its very informative for B.Tech Freshers

    ReplyDelete
  3. https://fueled.com/mobile-app-development-los-angeles/

    ReplyDelete
  4. This is really an informative blog for all the beginners. The application development company providing various advanced techniques. But will it support in Android 5.0 Lollipop version?

    ReplyDelete
  5. The blog gave me idea how bluetooth works on android My sincere thanks for sharing Please continue to share this post
    Android Training in Chennai

    ReplyDelete
  6. Thanks for your informative blog!!! Keep on updating your with such awesome information.
    Android Online Training

    ReplyDelete
  7. really nice blog has been shared by you. before i read this blog i didn't have any knowledge about this but now i got some knowledge. so keep on sharing such kind of an interesting blog.
    android training in chennai

    ReplyDelete
  8. Hi admin..,
    I read your blog completely really a awazing blog.Thanks for sharing.Anybody want to learn Android Training in Chennai..Refer


    Android Training in Chennai

    ReplyDelete
  9. really nice blog i have ever seen. before i read this blog i didn't have any knowledge about this but now i got some knowledge. so keep on sharing such kind of an interesting blogs.
    android training in chennai

    ReplyDelete
  10. This comment has been removed by the author.

    ReplyDelete
  11. Hats off to your presence of mind..I really enjoyed reading your blog. I really appreciate your information which you shared with us.


    Android Online Training

    ReplyDelete