Tonven
Tonven

Reputation: 626

Exception while using Health Device Profile on Android

I am trying to get data from Onyx2(Fingertip Oximeter) via Bluetooth using Health Device Profile and sample, which can be found at Android Developers site. But I am getting the following error

E/BluetoothEventLoop.cpp(432): onHealthDeviceConnectionResult: D-Bus error: org.bluez.Error.HealthError (Error getting remote SDP records). What can be a reason of this problem? BTW, approximately 1 time out of 50, I get the data.

// Callbacks to handle connection set up and disconnection clean up.
private final BluetoothProfile.ServiceListener mBluetoothServiceListener =
        new BluetoothProfile.ServiceListener() {
    public void onServiceConnected(int profile, BluetoothProfile proxy) {
        if (profile == BluetoothProfile.HEALTH) {
            mBluetoothHealth = (BluetoothHealth) proxy;
            if (Log.isLoggable(TAG, Log.DEBUG))
                Log.d(TAG, "onServiceConnected to profile: " + profile);
        }
    }

    public void onServiceDisconnected(int profile) {
        if (profile == BluetoothProfile.HEALTH) {
            mBluetoothHealth = null;
        }
    }
};

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;
            sendMessage(STATUS_HEALTH_APP_REG, RESULT_FAIL);
        } else if (status == BluetoothHealth.APP_CONFIG_REGISTRATION_SUCCESS) {
            mHealthAppConfig = config;
            sendMessage(STATUS_HEALTH_APP_REG, RESULT_OK);
        } else if (status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_FAILURE ||
                status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_SUCCESS) {
            sendMessage(STATUS_HEALTH_APP_UNREG,
                    status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_SUCCESS ?
                    RESULT_OK : RESULT_FAIL);
        }
    }

    // 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_CONNECTING &&
                newState == BluetoothHealth.STATE_CHANNEL_CONNECTED) {
            if (config.equals(mHealthAppConfig)) {
                mChannelId = channelId;
                sendMessage(STATUS_CREATE_CHANNEL, RESULT_OK);
                (new ReadThread(fd)).start();
            } else {
                sendMessage(STATUS_CREATE_CHANNEL, RESULT_FAIL);
            }
        } else if (prevState == BluetoothHealth.STATE_CHANNEL_CONNECTING &&
                   newState == BluetoothHealth.STATE_CHANNEL_DISCONNECTED) {
            sendMessage(STATUS_CREATE_CHANNEL, RESULT_FAIL);
        } else if (newState == BluetoothHealth.STATE_CHANNEL_DISCONNECTED) {
            if (config.equals(mHealthAppConfig)) {
                sendMessage(STATUS_DESTROY_CHANNEL, RESULT_OK);
            } else {
                sendMessage(STATUS_DESTROY_CHANNEL, RESULT_FAIL);
            }
        }
    }
};
// Initiates application registration through {@link
    // BluetoothHDPService}.
    Button registerAppButton = (Button) findViewById(R.id.button_register_app);
    registerAppButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            sendMessage(BluetoothHDPService.MSG_REG_HEALTH_APP,
                    HEALTH_PROFILE_SOURCE_DATA_TYPE);
        }
    });

    // Initiates application unregistration through {@link
    // BluetoothHDPService}.
    Button unregisterAppButton = (Button) findViewById(R.id.button_unregister_app);
    unregisterAppButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            sendMessage(BluetoothHDPService.MSG_UNREG_HEALTH_APP, 0);
        }
    });

    // Initiates channel creation through {@link BluetoothHDPService}. Some
    // devices will
    // initiate the channel connection, in which case, it is not necessary
    // to do this in the
    // application. When pressed, the user is asked to select from one of
    // the bonded devices
    // to connect to.
    Button connectButton = (Button) findViewById(R.id.button_connect_channel);
    connectButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            mAllBondedDevices = (BluetoothDevice[]) mBluetoothAdapter
                    .getBondedDevices().toArray(new BluetoothDevice[0]);

            if (mAllBondedDevices.length > 0) {
                int deviceCount = mAllBondedDevices.length;
                if (mDeviceIndex < deviceCount)
                    mDevice = mAllBondedDevices[mDeviceIndex];
                else {
                    mDeviceIndex = 0;
                    mDevice = mAllBondedDevices[0];
                }
                String[] deviceNames = new String[deviceCount];
                int i = 0;
                for (BluetoothDevice device : mAllBondedDevices) {
                    deviceNames[i++] = device.getName();
                }
                SelectDeviceDialogFragment deviceDialog = SelectDeviceDialogFragment
                        .newInstance(deviceNames, mDeviceIndex);
                deviceDialog.show(getFragmentManager(), "deviceDialog");
            }
        }
    });

    // Initiates channel disconnect through {@link BluetoothHDPService}.
    Button disconnectButton = (Button) findViewById(R.id.button_disconnect_channel);
    disconnectButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            disconnectChannel();
        }
    });
    registerReceiver(mReceiver, initIntentFilter());
}

// Sets up communication with {@link BluetoothHDPService}.
private ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName name, IBinder service) {
        mHealthServiceBound = true;
        Message msg = Message.obtain(null,
                BluetoothHDPService.MSG_REG_CLIENT);
        msg.replyTo = mMessenger;
        mHealthService = new Messenger(service);
        try {
            mHealthService.send(msg);
        } catch (RemoteException e) {
            Log.w(TAG, "Unable to register client to service.");
            e.printStackTrace();

Upvotes: 0

Views: 1453

Answers (1)

taciosd
taciosd

Reputation: 312

I remember that Android HDP demo app had some problem about not closing bluetooth connections when terminated. One test that you can do to verify this is:

  • Turn off bluetooth of your android.
  • Turn it on again.
  • Pair with the health device (in android settings)
  • Start your android application.
  • Try to connect and transfer data with health device.

If these steps works consistently when repeated, i'm almost sure it has something to do with the app not releasing resources like i sad before.

Upvotes: 1

Related Questions