I want to connect to Fora thermometer via Android BluetoothPRofile and get the reading. Following is my approoach :-
In OnCreate() i have written this piece of code :-
if (!mBluetoothAdapter.getProfileProxy(this, mBluetoothServiceListener, BluetoothProfile.HEALTH)) { Toast.makeText(this, "No Health Profile Supported", Toast.LENGTH_LONG); return; }
This triggers the mBluetoothServiceListener callback which is mentioned below :-
@SuppressLint("NewApi") private final BluetoothProfile.ServiceListener mBluetoothServiceListener = new BluetoothProfile.ServiceListener() { public void onServiceConnected(int profile, BluetoothProfile proxy) { Log.d(TAG, "onServiceConnected to profile: " + profile + " while health is " + BluetoothProfile.HEALTH); if (profile == BluetoothProfile.HEALTH) { mBluetoothHealth = (BluetoothHealth) proxy; if (Log.isLoggable(TAG, Log.DEBUG)) Log.d(TAG, "onServiceConnected to profile: " + profile); } else if(profile == BluetoothProfile.HEADSET) { Log.d(TAG, "onServiceConnected to profile: " + profile); } } public void onServiceDisconnected(int profile) { if (profile == BluetoothProfile.HEALTH) { mBluetoothHealth = null; } } };
After this the code searches for nearby bluetooth devices and shows it in the list. The onclicklistener of that list item calls the following code :-
boolean bool = mBluetoothHealth.registerSinkAppConfiguration(TAG, HEALTH_PROFILE_SOURCE_DATA_TYPE, mHealthCallback); // where HEALTH_PROFILE_SOURCE_DATA_TYPE = 0x1008 (it's a body thermometer)
Once the registeration process is done i try to connect the device like this :-
boolean bool = mBluetoothHealth.connectChannelToSource(mDevice, mHealthAppConfig);
Once all the above steps are done then the BluetoothHealthCallback is called whenever the device connection state changes
private final BluetoothHealthCallback mHealthCallback = new BluetoothHealthCallback() { // Callback to handle application registration and unregistration events. The service // passes the status back to the UI client. public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config, int status) { if (status == BluetoothHealth.APP_CONFIG_REGISTRATION_FAILURE) { mHealthAppConfig = null; } else if (status == BluetoothHealth.APP_CONFIG_REGISTRATION_SUCCESS) { mHealthAppConfig = config; } else if (status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_FAILURE || status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_SUCCESS) { } } // Callback to handle channel connection state changes. // Note that the logic of the state machine may need to be modified based on the HDP device. // When the HDP device is connected, the received file descriptor is passed to the // ReadThread to read the content. public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config, BluetoothDevice device, int prevState, int newState, ParcelFileDescriptor fd, int channelId) { if (Log.isLoggable(TAG, Log.DEBUG)) Log.d(TAG, String.format("prevState\t%d ----------> newState\t%d", prevState, newState)); if (prevState == BluetoothHealth.STATE_CHANNEL_DISCONNECTED && newState == BluetoothHealth.STATE_CHANNEL_CONNECTED) { if (config.equals(mHealthAppConfig)) { mChannelId = channelId; (new ReadThread(fd)).start(); } else { } } else if (prevState == BluetoothHealth.STATE_CHANNEL_CONNECTING && newState == BluetoothHealth.STATE_CHANNEL_DISCONNECTED) { } else if (newState == BluetoothHealth.STATE_CHANNEL_DISCONNECTED) { if (config.equals(mHealthAppConfig)) { } else { } } } };
In the above case i get the BluetoothHealthCallback precisely 2 times :-
First Time i get the prevState = BluetoothHealth.STATE_CHANNEL_DISCONNECTED and newState = BluetoothHealth.STATE_CHANNEL_CONNECTING
While in Second time i get the prevState = BluetoothHealth.STATE_CHANNEL_CONNECTING and newState = BluetoothHealth.STATE_CHANNEL_DISCONNECTED
i.e. the attempt is made to connect to the device but it is not succesfull. Also in both the callbacks the ParcelFileDescriptor is null
*Note : The device is already paired
Do you think yours below "if" statement is right?
if (prevState == BluetoothHealth.STATE_CHANNEL_DISCONNECTED && newState == BluetoothHealth.STATE_CHANNEL_CONNECTED) {
It should be either (as it happen for classic Bluetooth devices)
if (prevState == BluetoothHealth.STATE_CHANNEL_CONNECTING && newState == BluetoothHealth.STATE_CHANNEL_CONNECTED) {
as you get connecting first and then connected
or I could be just
if (newState == BluetoothHealth.STATE_CHANNEL_CONNECTED) {
And same correction for other "if" statement.
Also, Does device support paired and connected option? If yes then you may try to connect it manually.
来源:https://stackoverflow.com/questions/22809749/unable-to-connect-to-bluetooth-health-device-fora-using-android-bluetoothprofile