How can I detect the presence of a Sony SmartEyeglass device? - android

I am writing an android app that will interface with a Sony SmartEyeGass. I want to detect the presence and connection of the device, prior to the user starting functions that use the glasses.
Unfortunately, I am having trouble reliably detecting if the device is present or not. Watching for the START, STOP, etc events is not solving my problems because I often get START events received by the ExtensionReciever when I start the application and the ExtensionService, despite having the glasses powered off. Running the ControlExtension that shows stuff on the glasses has no problems drawing onto nothing.
How can I get information from the SmartEyeglassAPI indicating whether the device is present or not? I have not been able to find this digging through their online documentation nor in the samples.

There is no API as part of SmartExtensions to check whether the glasses are connected or not. You should be able to detect whether the glasses are connected by listening for connecting Bluetooth devices and checking the device name.
This API may work for you:
http://developer.android.com/reference/android/bluetooth/BluetoothHeadset.html#getConnectedDevices()

Related

How to reliably fetch and detect changes to the active audio route on Android?

I have a feature where I need to fetch current AND detect switch of the active audio output device of the system. Something like:
run app -> fetch current device (which might be embedded speakers)
connect bluetooth speaker -> detect switch to bluetooth speaker
connect audio jack -> detect switch from bluetooth speaker to audio jack
It seems to me there should be one API for this but it seems there are several. The one that makes the most sense seems to be MediaRouter but there are two large issues with it that prevent me from using it as described above:
There are at least 2 scenarios in which it fetches the wrong device as the active route and on other scenarios it straight up doesn't detect route switches at all. For details on this please check out the ticket I opened on the google issue tracker
I need certain information on the current active output device, most importantly a universal identifier. For bluetooth devices, the Complete Local Name can be used for this, which is available from BluetoothDevice types but this is not obtainable from the MediaRouter. Instead, MediaRouter makes a productName available, which sometimes can be an alias of the bluetooth devices, and not the static name.
I have since abandoned this API and moved on to find other solutions, let me know if anyone thinks there's a way around the problems above, most importantly the first one. I will note that I have used both the android.media.MediaRouter and the androidx one, they both have these issues.
I am now leveraging a combination of other APIs. It works but it is a far from acceptable solution:
Using AudioManager.registerAudioDeviceCallback(object : AudioDeviceCallback) for non-bluetooth devices detection (AudioDeviceInfo.TYPE_WIRED_HEADPHONES, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER)). I'm getting callbacks when any of these devices get added or removed and then I can check if a wired type device is present then that's the active one 100% of the time, if it's not, then the embedded-type is active. It's kind of hacky but it works.
More interestingly, for detection of Bluetooth output devices I use a private API, that Android itself uses in the Settings app to display the current audio output device.
BluetoothA2dp::class.java.getDeclaredMethod("getActiveDevice") to get the current active output device. This is done by getting the profile proxy service bluetoothAdapter.getProfileProxy
register a receiver for this action BluetoothA2dp::class.java.getField("ACTION_ACTIVE_DEVICE_CHANGED").get(null) in order to detect switches of the bluetooth active audio device.
This solution works but also has a few limitations:
they are obvious private APIs, subjected to sudden change and potential breaks
the active device APIs mentioned above are not available < Android 9. I have yet to investigate what Android is using pre-Android9 in the Settings app
On Samsung devices the active device API works incorrectly.
So, the million dollar question. How do I fetch and detect the current audio route on Android, reliably?

How android system autoconnects to paired device?

What I want to know:
I'm wondering how the android system (like Android smart phone) auto-connects to devices which is paired before.
For example, I pair my bluetooth headset with my android smartphone in the procedure of "turn on scanning/advertising -> click pairing" on day 1. And when I turn on advertising on my headset, it connects automatically on day 2, 3, 4, and so on. The point is, I don't have to make my smartphone scan again to find my (paired) headset.
I can't understand how android system finds that the paired device is turned on. Does the android system scan periodically in background? Even if I don't click "scan" button?
Why I ask:
I want to make my app autoconnect to customized BLE device, after make pairing. I succeed to make pairing(bonding) with createBond() method, but after that, I couldn't find how to make autoconnect. I know I can turn on autoconnect function like this way, connectGatt(XXX, true, XXX), but this autoconnect function doesn't work when the BLE device is disconnected a few days.
So I want to make my app works like android system and Bluetooth headset. But I couldn't find how android bluetooth system works even I dig AOSP codes.
I found many questions (here and here) about problems like mine but there were no answers.
Thanks in advance.
Update:
I found that bt_btif gets activated (with LG smartphone and Nexus 5) when the paired headset is turned on (start advertising). But bt_btif doesn't get activated with my custom BLE device... What can I do?
Executing connectGatt(XXX, true, XXX) is the correct way to go. gatt.connect() also starts an auto connect. Once you execute that, your phone will scan for the device and once it appears it connects to it. The only thing that interrupt this call is either if Bluetooth is turned off on the phone or if your app process is being killed. To avoid your process from being killed, let your app have a foreground service.
One gotcha however, there is a bug in Android which will sometimes make auto connect do a direct connect instead (and cancel after 30 seconds or so). See https://code.google.com/p/android/issues/detail?id=69834. You need to use reflection to avoid this bug.
I think I found a solution.
First, the solution for my question: Android smartphone seems to detect state changes of nearby bluetooth devices from the hardware sides. When the paired bluetooth headset starts to advertise, a callback in HAL (I think) is called.
So I made my app to connectGatt with autoConnection=True to the device that I want, by using MAC address, when the activity is started (in onResume() of MainActivity).
The connection would fail if my BLE peripheral device is not advertising. But the device auto-connects when it starts advertising, because the autoConnection parameter was set to true.
I've done a similar app and i didn't have problem with that. As a last resort for your problem, i would suggest writing the BLE Device Address in a simple DB table and manually connect to it. I've made something like this here
. It is no best practice code, but i hope you can find ideas for you solution.

How to get if android is in hands free mode?

I wan't to check if the user is operating the phone while a call is being made by using device's sensors and GPS.
I need to check if we are in hand free mode because in that case I should hear noise but may not see any movements or rotation.
I tried looking in android.telephony but found nothing. Also tried my good old friend google and no luck. Is it even doable?
Thanks!
Here you go. Your problem can be divided into 4 steps. Plus you dont need any sensors or GPS to achieve this.
1) Try to get connected Bluetooth Device list, via BluetoothAdapter class.
2) Check device class, via BluetoothDevice's APIs.
3) If you see Phone is connected to Bluetooth Device with capabilities like A2DP(audio) etc. Then you will know phone is in handsfree mode.
4) also try to find out phone_state of the phone. It shouln't be Idle, if you just want to check in state of making/receiving/during call.

Android Awareness of remote Bluetoth-Request with disabled BluetoothAdapter

I'd like to use android's bluetooth for some kind of sensing devices. But I don't want to connect to these devices. As far as I know Devices won't react to scanning when their own bluetooth is disabled. But is there any way to get my app noticed when such a scan has been performed by a remote device, even when my app is running with bluetooth turned off?
I don't want to force toggling bluetooth on, but I need to get some kind of Action started in other devices running the same app. So I'm wondering if some there is any description/data field that can be sent with a bluetooth scan, so if scan is rejected the app has the opportunity to read that data just to know there was this specific call?
I need to leverage context-awareness within my system as to users, not knowing each other, still can interchange content (if they agree). But I need to find some ways of sensing while I also don't want to have all sensors activated all the time.
Hope you can give me a hint, or tell me that this is simply not possible, which would also help me not spending any more time on that.
Thanks.

Manually pairing Bluetooth Decives in Android?

I was reading this
http://developer.android.com/guide/topics/wireless/bluetooth.html#QueryingPairedDevices
which is allot of help on how to pair,connect to a bluetooth device.
I have a situation where I have several BT devices that are in Non-Discover mode always. I know the MAC and the PIN of these devices. IS there a way in Android Dev to manually add devices to the PAIRED list so i can just use the connect as a client.
I understand this maual is written allot for V3. i think i will need to do this on 2.0 ; 2.1- has anybody done this before?
Basically these devices I want to connect to are power saving modules I used pre built BT modules to monitor daylight, another one humidity, etc.. every 3hrs or when interrupted and runs of a single battery for months. So turning off divcory on server saves immense power and prevents other people trying to connect and waste battery.
Not sure what you mean by "manually": Do you mean "manually" as in GUI/user interaction, or "manually" as "I do it in my own application code"?
Some suggestions though:
If you can make your BT devices discoverable at all, you could do it this way:
Make your BT device discoverable
Let Android search for and find the device and then initiate a connection
Android will ask for the PIN for pairing with the device; enter the PIN.
Once pairing was successful, Android stores the pairing information for future use, so that you can
Make your BT device invisible again.
From then on your app should be able to connect to the BT device at any time without further pairing operations.
If the said is not an option for you, maybe you want to go another way:
In current Android versions there are different API routines implemented which are neither documented nor exposed in the normal SDK. A hack kind of solution may be to use some of these "hidden" ("#hide"...) APIs, either via reflection or via modification of your SDK installation.
But be aware that this is always a hack and it may work on a specific device with a specific version of Android and is likely to break your app on another device and/or any other Android version.
Having said that, here comes some reference:
Example of how to access "hidden" bluetooth API.
Then, have a look at the source code for android.bluetooth.BluetoothDevice, e.g. here.
In there, public boolean createBond(){...} may do what you want.

Categories

Resources