can not connect to bluetooth headset in android - android

After steeping in the wrong path for almost two months i found out what my mistake was.
Now i am pacing a new problem which I cannot find the answer to:
Using this function while trying to connect to the headset:
mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
final BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = (BluetoothHeadset) proxy;
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = null;
}
}
};
I cannot initialize the mBluetoothHeadset object ,for some reason the debugger wont step into the onServiceConnected function..
Any help will be appreciated...realy needs one
shai
More Info:
Inded what haped was that after a android restart Bluetooth nneded to be enabled'solved in code:
This is the function code:
Log("PM.CheckForHeadSet","In");
if (mBluetoothAdapter == null) {
Log("PM.CheckForHeadSet","BlueTooth adapter not found");
return "Error Bluetooth adapter";
}
switch (mBluetoothAdapter.getState()){
case BluetoothAdapter.STATE_OFF:
Log("PM.CheckForHeadSet.getState"," STATE_OFF");
mBluetoothAdapter.enable();
break;
case BluetoothAdapter.STATE_TURNING_ON:
Log("PM.CheckForHeadSet.getState","STATE_TURNING_ON");
break;
case BluetoothAdapter.STATE_ON:
Log("PM.CheckForHeadSet.getState","STATE_ON");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Log("PM.CheckForHeadSet.getState","STATE_TURNING_OFF");
break;
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices, add each one to the ArrayAdapter
if (pairedDevices.size() == 1) {
for (BluetoothDevice device : pairedDevices)
if(device.getBondState() == BluetoothDevice.BOND_BONDED){
Log("PM.CheckForHeadSet Connected to:",device.getName());
}
}
Log("PM.CheckForHeadSet ServiceListener:","In");
final BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = (BluetoothHeadset) proxy;
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = null; }
}};
if(mBluetoothHeadset == null)
Log("PM.CheckForHeadSet","mBluetoothHeadset = null");
else
Log("PM.CheckForHeadSet","mBluetoothHeadset = " + mBluetoothHeadset.toString());
if(context == null)
Log("PM.CheckForHeadSet","context = null");
else
Log("PM.CheckForHeadSet","context = " + context.toString());
if(mProfileListener == null)
Log("PM.CheckForHeadSet","mProfileListener = null");
else
Log("PM.CheckForHeadSet","mProfileListener = " + mProfileListener.toString());
if(mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET) == true)
Log("PM.CheckForHeadSet.getProfileProxy","true");
else
Log("PM.CheckForHeadSet.getProfileProxy","false");
Log("PM.CheckForHeadSet","Out");
return "Set Headset";
If i place the GetProfileProxy above the new ProfileListener (as in the docomantaion example|) the mProfileListener var is still null and getProfileProxy return false
And this is the logcat:
03-12 10:09:49.906: D/SpySitter(4205): PM.CheckForHeadSet-In
03-12 10:09:50.968: D/dalvikvm(4205): threadid=1: still suspended after undo (sc=1 dc=1)
03-12 10:09:59.453: D/SpySitter(4205): PM.CheckForHeadSet.getState-STATE_ON
03-12 10:10:02.640: D/SpySitter(4205): PM.CheckForHeadSet Connected to:-Motorola H790
03-12 10:10:04.226: D/SpySitter(4205): PM.CheckForHeadSet ServiceListener:-In
03-12 10:10:13.945: D/SpySitter(4205): PM.CheckForHeadSet-mBluetoothHeadset = null
03-12 10:10:17.984: D/SpySitter(4205): PM.CheckForHeadSet-context = android.app.Application#408472a0
03-12 10:10:21.820: D/SpySitter(4205): PM.CheckForHeadSet-mProfileListener = com.example.HelloForm.Tools$1#40894d00
03-12 10:10:28.796: D/SpySitter(4205): PM.CheckForHeadSet.getProfileProxy-true
03-12 10:10:31.226: D/SpySitter(4205): PM.CheckForHeadSet-Out

getProxyProfile returns false in three cases (this is according to the android-15 source, so it might be slightly different in android-11):
the Context passed in is null
the BluetoothProfile.ServiceListener passed in is null
the int passed in is not one of BluetoothProfile.HEADSET, BluetoothProfile.A2DP, BluetoothProfile.INPUT_DEVICE, BluetoothProfile.PAN, or BluetoothProfile.HEALTH
I'd suggest setting a breakpoint on your call to getProxyProfile to figure out which of these cases is causing the false return value.
edit: Further info
Bluetooth has to be supported and enabled for the interface methods to be called. If Bluetooth is not supported, getDefaultAdapter() will return null. If you have an adapter, you can check whether Bluetooth is enabled by calling isEnabled() on the adapter. That's pretty straightforward, so you may have already done that.
onServiceConnected is called by the android.content.ServiceConnection member (mServiceConnection) in the BluetoothHeadset class, which is in turn called by the Android OS by virtue of a bindService call when the BluetoothHeadset object is created. If the binding of this service fails, there should be an error in the logcat message log something like:
"Could not bind to Bluetooth Headset Service"
with a tag of "BluetoothHeadset". If you don't see this error, things are probably working as they should under the hood.
A final note is that Android only supports one connected headset at a time. Make sure that no headset is connected when you are running this code. On a similar note, many devices only support one bluetooth connection at a time. If that applies to your device, you'll want to make sure it is not already connected when you run this code.
That pretty much exhausts what I know and can easily determine about Bluetooth connections. Hope it helps you solve your problem.

Related

USB broadcast receiver called multiple times

I'm creating an app that connects to an Arduino via USB. The connection works fine and I can properly transmit and receive data. My problem is when connecting and disconnecting the USB.
For some reason, everytime I connect or disconnect the Arduino via USB, the BroadcastReceives is called from 2 to 4 times, and sometimes the Arduino just doesn't even connect at all.
My BroadcastReceiver implementation:
public static class ArduinoConnectionReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
switch(intent.getAction()) {
case ArduinoConfigurations.ACTION_USB_PERMISSION:
if (intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED)) {
connection = usbManager.openDevice(device);
serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
if (serialPort != null) {
if (serialPort.open()) { //Set Serial Connection Parameters.
serialPort.setBaudRate(115200);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serialPort.read(new ArduinoCallback());
Log.d("ARDUINO", "Arduino connected!");
((MainActivity)context).enableButtons(true);
} else
Log.e("ARDUINO", "Port not open, not possible to connect.");
} else
Log.e("ARDUINO", "Port is null, not possible to connect.");
} else
Log.e("ARDUINO", "Permission not granted, not possible to connect.");
break;
case UsbManager.ACTION_USB_DEVICE_ATTACHED:
openConnection((MainActivity)context);
break;
case UsbManager.ACTION_USB_DEVICE_DETACHED:
default:
closeConnection((MainActivity)context);
break;
}
...
Sometimes it also throws:
exception in UsbManager.openDevice
java.lang.IllegalArgumentException: device /dev/bus/usb/003/012 does not exist or is restricted
at android.os.Parcel.readException(Parcel.java:1688)
at android.os.Parcel.readException(Parcel.java:1637)
at android.hardware.usb.IUsbManager$Stub$Proxy.openDevice(IUsbManager.java:411)
at android.hardware.usb.UsbManager.openDevice(UsbManager.java:330)
...
and
Error on connecting Arduino: Attempt to invoke virtual method 'boolean android.hardware.usb.UsbDeviceConnection.claimInterface(android.hardware.usb.UsbInterface, boolean)' on a null object reference
I've read that the USB connector can be really unstable sometimes. But is it just that? Can I work around this so that the Arduino is connected and disconnected only once?

BluetoothGattServer cancelConnection does not cancel the connection

I have Android application which exposes BLE Server. I connect with BluetoothGattServer#connect. It works - my app gets call to BluetoothGattServerCallback#onConnectionStateChange with STATE_CONNECTED. When I'm done with the client I try to disconnect from my app with BluetoothGattServer#cancelConnection.
But I do not get call to BluetoothGattServerCallback#onConnectionStateChange and it seems that the connection is still active as my BLE client does not start to advertise (which it does when nothing is connected to it).
In logcat I see only:
BluetoothGattServer: cancelConnection() - device: XX:XX:XX:XX:XX:XX
The funny part is, my app gets call to BluetoothGattServerCallback#onConnectionStateChange with STATE_DISCONNECTED as soon as I turn off BT completely.
Similar issues in Google's tracker: 63461 and 63464.
When newState==BluetoothProfile.STATE_CONNECTED, you have to call BluetoothGattServer.connect();.
#Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
super.onConnectionStateChange(device, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED){
mDevice = device;
mBluetoothGattServer.connect(device, false);
}else {
mDevice = null;
}
}
private void cancelConnection(){
if (mDevice != null) {
mBluetoothGattServer.cancelConnection(mDevice);
}
}
Encountering same issue when calling disconnect() method.. no disconnect is given in onConnectionStateChange in my BluetoothGattCallback.
Cycling Bluetooth seems the be the only thing that works.
edit:
also, after disconnect() and close() method are called, I am still connected according to this code:
public int getConnectedBLEDevices() {
int i = 0;
List<BluetoothDevice> devices = mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT);
for(BluetoothDevice device : devices) {
if(device.getType() == BluetoothDevice.DEVICE_TYPE_LE) {
Logs.writeEvent(TAG+".getConnectedBLEDevices()", device.getAddress() + "\n"+ getStateAsString(mBluetoothManager.getConnectionState(device, BluetoothProfile.GATT)));
i++;
}
}
return i;
}
pls see https://issuetracker.google.com/issues/37127644
Status: Won't Fix (Intended Behavior)
You must call BluetoothGattServer.connect() to mark connection as used, then BluetoothGattServer.disconnect() to mark it as no longer used. Then after a timeout stack can decide to disconnect from the remote if no one else is using the connection.
If BluetoothGattServer.connect() is not called after the connection is established, then the stack is keeping the connection until some gatt client/server app start using this connection.

Programmatically pairing with a BLE device on Android 4.4+

Does anyone have a complete working example of how to programmatically pair with a BLE (not Bluetooth Classic) device that uses passkey entry (i.e. a 6-digit PIN) or Numeric Comparison on Android 4.4 or later? By 'programmatically' I mean I tell Android the PIN - the user isn't prompted.
There are many similar questions about this on SO but they are either a) about Bluetooth Classic, b) old (before setPin() and createBond() were public), or c) unanswered.
My understanding is as follows.
You connect to the device and discover its services.
You try to read a 'protected' characteristic.
The device returns an authentication error.
Android somehow initiates pairing and you tell it the PIN.
You can now read the characteristic.
I have created a device using mBed running on the nRF51-DK and given it a single characteristic.
I set up the security parameters like so:
ble.securityManager().init(
true, // Enable bonding (though I don't really need this)
true, // Require MitM protection. I assume you don't get a PIN prompt without this, though I'm not 100% sure.
SecurityManager::IO_CAPS_DISPLAY_ONLY, // This makes it us the Passkey Entry (PIN) pairing method.
"123456"); // Static PIN
And then in the characteristic I used
requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM);
Now when I try to read it with the Nordic Master Control Panel, I get a pairing request notification like this:
And I can put this PIN in, and then MCP says I'm bonded, and can read the characteristic.
However, in my app I would like to avoid having the user enter the PIN, since I know it already. Does anyone have a complete recent example of how to do this?
Edit: By the way this is the most relevant question I found on SO, but the answer there doesn't seem to work.
I almost have it working. It pairs programmatically but I can't get rid of the "Pairing request" notification. Some answers to this question claim to be able to hide it just after it is shown using the hidden method cancelPairingUserInput() but that doesn't seem to work for me.
Edit: Success!
I eventually resorted to reading the source code of BluetoothPairingRequest and the code that sends the pairing request broadcast and realised I should be intercepting the ACTION_PAIRING_REQUEST. Fortunately it is an ordered intent broadcast so you can intercept it before the system does.
Here's the procedure.
Register to receive BluetoothDevice.ACTION_PAIRING_REQUEST changed broadcast intents. Use a high priority!
Connect to the device.
Discover services.
If you have disconnected by now, it's probably because the bond information is incorrect (e.g. the peripheral purged it). In that case, delete the bond information using a hidden method (seriously Google), and reconnect.
Try to read a characteristic that requires encryption MitM protection.
In the ACTION_PAIRING_REQUEST broadcast receiver, check that the pairing type is BluetoothDevice.PAIRING_VARIANT_PIN and if so, call setPin() and abortBroadcast(). Otherwise you can just let the system handle it, or show an error or whatever.
Here is the code.
/* This implements the BLE connection logic. Things to watch out for:
1. If the bond information is wrong (e.g. it has been deleted on the peripheral) then
discoverServices() will cause a disconnect. You need to delete the bonding information and reconnect.
2. If the user ignores the PIN request, you get the undocumented GATT_AUTH_FAILED code.
*/
public class ConnectActivityLogic extends Fragment
{
// The connection to the device, if we are connected.
private BluetoothGatt mGatt;
// This is used to allow GUI fragments to subscribe to state change notifications.
public static class StateObservable extends Observable
{
private void notifyChanged() {
setChanged();
notifyObservers();
}
};
// When the logic state changes, State.notifyObservers(this) is called.
public final StateObservable State = new StateObservable();
public ConnectActivityLogic()
{
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Tell the framework to try to keep this fragment around
// during a configuration change.
setRetainInstance(true);
// Actually set it in response to ACTION_PAIRING_REQUEST.
final IntentFilter pairingRequestFilter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
pairingRequestFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY - 1);
getActivity().getApplicationContext().registerReceiver(mPairingRequestRecevier, pairingRequestFilter);
// Update the UI.
State.notifyChanged();
// Note that we don't actually need to request permission - all apps get BLUETOOTH and BLUETOOTH_ADMIN permissions.
// LOCATION_COARSE is only used for scanning which I don't need (MAC is hard-coded).
// Connect to the device.
connectGatt();
}
#Override
public void onDestroy()
{
super.onDestroy();
// Disconnect from the device if we're still connected.
disconnectGatt();
// Unregister the broadcast receiver.
getActivity().getApplicationContext().unregisterReceiver(mPairingRequestRecevier);
}
// The state used by the UI to show connection progress.
public ConnectionState getConnectionState()
{
return mState;
}
// Internal state machine.
public enum ConnectionState
{
IDLE,
CONNECT_GATT,
DISCOVER_SERVICES,
READ_CHARACTERISTIC,
FAILED,
SUCCEEDED,
}
private ConnectionState mState = ConnectionState.IDLE;
// When this fragment is created it is given the MAC address and PIN to connect to.
public byte[] macAddress()
{
return getArguments().getByteArray("mac");
}
public int pinCode()
{
return getArguments().getInt("pin", -1);
}
// Start the connection process.
private void connectGatt()
{
// Disconnect if we are already connected.
disconnectGatt();
// Update state.
mState = ConnectionState.CONNECT_GATT;
State.notifyChanged();
BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(macAddress());
// Connect!
mGatt = device.connectGatt(getActivity(), false, mBleCallback);
}
private void disconnectGatt()
{
if (mGatt != null)
{
mGatt.disconnect();
mGatt.close();
mGatt = null;
}
}
// See https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/stack/include/gatt_api.h
private static final int GATT_ERROR = 0x85;
private static final int GATT_AUTH_FAIL = 0x89;
private android.bluetooth.BluetoothGattCallback mBleCallback = new BluetoothGattCallback()
{
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState)
{
super.onConnectionStateChange(gatt, status, newState);
switch (newState)
{
case BluetoothProfile.STATE_CONNECTED:
// Connected to the device. Try to discover services.
if (gatt.discoverServices())
{
// Update state.
mState = ConnectionState.DISCOVER_SERVICES;
State.notifyChanged();
}
else
{
// Couldn't discover services for some reason. Fail.
disconnectGatt();
mState = ConnectionState.FAILED;
State.notifyChanged();
}
break;
case BluetoothProfile.STATE_DISCONNECTED:
// If we try to discover services while bonded it seems to disconnect.
// We need to debond and rebond...
switch (mState)
{
case IDLE:
// Do nothing in this case.
break;
case CONNECT_GATT:
// This can happen if the bond information is incorrect. Delete it and reconnect.
deleteBondInformation(gatt.getDevice());
connectGatt();
break;
case DISCOVER_SERVICES:
// This can also happen if the bond information is incorrect. Delete it and reconnect.
deleteBondInformation(gatt.getDevice());
connectGatt();
break;
case READ_CHARACTERISTIC:
// Disconnected while reading the characteristic. Probably just a link failure.
gatt.close();
mState = ConnectionState.FAILED;
State.notifyChanged();
break;
case FAILED:
case SUCCEEDED:
// Normal disconnection.
break;
}
break;
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status)
{
super.onServicesDiscovered(gatt, status);
// Services have been discovered. Now I try to read a characteristic that requires MitM protection.
// This triggers pairing and bonding.
BluetoothGattService nameService = gatt.getService(UUIDs.NAME_SERVICE);
if (nameService == null)
{
// Service not found.
disconnectGatt();
mState = ConnectionState.FAILED;
State.notifyChanged();
return;
}
BluetoothGattCharacteristic characteristic = nameService.getCharacteristic(UUIDs.NAME_CHARACTERISTIC);
if (characteristic == null)
{
// Characteristic not found.
disconnectGatt();
mState = ConnectionState.FAILED;
State.notifyChanged();
return;
}
// Read the characteristic.
gatt.readCharacteristic(characteristic);
mState = ConnectionState.READ_CHARACTERISTIC;
State.notifyChanged();
}
#Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
{
super.onCharacteristicRead(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS)
{
// Characteristic read. Check it is the right one.
if (!UUIDs.NAME_CHARACTERISTIC.equals(characteristic.getUuid()))
{
// Read the wrong characteristic. This shouldn't happen.
disconnectGatt();
mState = ConnectionState.FAILED;
State.notifyChanged();
return;
}
// Get the name (the characteristic I am reading just contains the device name).
byte[] value = characteristic.getValue();
if (value == null)
{
// Hmm...
}
disconnectGatt();
mState = ConnectionState.SUCCEEDED;
State.notifyChanged();
// Success! Save it to the database or whatever...
}
else if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION)
{
// This is where the tricky part comes
if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_NONE)
{
// Bonding required.
// The broadcast receiver should be called.
}
else
{
// ?
}
}
else if (status == GATT_AUTH_FAIL)
{
// This can happen because the user ignored the pairing request notification for too long.
// Or presumably if they put the wrong PIN in.
disconnectGatt();
mState = ConnectionState.FAILED;
State.notifyChanged();
}
else if (status == GATT_ERROR)
{
// I thought this happened if the bond information was wrong, but now I'm not sure.
disconnectGatt();
mState = ConnectionState.FAILED;
State.notifyChanged();
}
else
{
// That's weird.
disconnectGatt();
mState = ConnectionState.FAILED;
State.notifyChanged();
}
}
};
private final BroadcastReceiver mPairingRequestRecevier = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(intent.getAction()))
{
final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
if (type == BluetoothDevice.PAIRING_VARIANT_PIN)
{
device.setPin(Util.IntToPasskey(pinCode()));
abortBroadcast();
}
else
{
L.w("Unexpected pairing type: " + type);
}
}
}
};
public static void deleteBondInformation(BluetoothDevice device)
{
try
{
// FFS Google, just unhide the method.
Method m = device.getClass().getMethod("removeBond", (Class[]) null);
m.invoke(device, (Object[]) null);
}
catch (Exception e)
{
L.e(e.getMessage());
}
}
}
I also faced the same problem and after all the research, I figured out the below solution to pair to a BLE without any manual intervention.
(Tested and working!!!)
I am basically looking for a particular Bluetooth device (I know MAC address) and pair with it once found. The first thing to do is to create pair request using a broadcast receiver and handle the request as below.
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
registerReceiver(broadCastReceiver,intentFilter);
You need to write the broadcastReceiver and handle it as below.
String BLE_PIN = "1234"
private BroadcastReceiver broadCastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action))
{
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
bluetoothDevice.setPin(BLE_PIN.getBytes());
Log.e(TAG,"Auto-entering pin: " + BLE_PIN);
bluetoothDevice.createBond();
Log.e(TAG,"pin entered and request sent...");
}
}
};
Voila! You should be able to pair to Bluetooth device without ANY MANUAL INTERVENTION.
Hope this helps :-) Please make it right answer if it works for you.

How to detect bluetooth headset connection in Android

I tried example code google refers as below to detect connected bluetooth devices
BluetoothHeadset mBluetoothHeadset;
// Get the default adapter
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// Establish connection to the proxy.
mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = (BluetoothHeadset) proxy;
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = null;
}
}
};
// ... call functions on mBluetoothHeadset
But I got the following problems:
mBluetoothHeadset is only available inside onServiceConnected. I use getConnectedDevices to detect live bluetooth headset. but if I place the code below
List ConnectedDevices = mBluetoothHeadset.getConnectedDevices();
out of onServiceConnected, running program lead always crash. What's wrong here?
is there any possibility to use mBluetoothHeadset value outside onServiceConnected ? like the example show? Or May I trans some parameter/value from onServiceConnected to outside?
Actually the example codes don't work. i have to place additional code after mProfileListener:
if (mBluetoothAdapter.getProfileProxy(this, mProfileListener,BluetoothProfile.HEADSET)==false) { ....
What's the reason? or what's wrong with my code?
From system log the code seems work, but when I run it, program stay in onServiceConnected, never go to onServiceDisconnected, or outside if no other action the user perform(e.g press a confirm button). What's wrong?

android bluetooth headset getprofileproxy returning null

I am trying to connect a bluetooth headset to my android device using the android developer page as a reference. http://developer.android.com/guide/topics/connectivity/bluetooth.html
My problem is when i trying calling the getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET) method, I am unsure of what to pass for context? I located this error from the question here:
can not connect to bluetooth headset in android
I am extremely new to this so I will apologize in advance if this is a silly question. I have spent a lot of time trying to research this but every example and documentation I find just has a context variable passed in so I am not sure where I am going wrong. My code, which is more or less a copy from the android documentation is:
// Establish connection to the proxy.
boolean mProfileProxy = mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
Log.d(TAGP,"Get Adapter Success: "+mProfileProxy);
Log.d(TAGP,"Context: "+context);
BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = (BluetoothHeadset) proxy;
Log.d(TAGP,"BLuetooth Headset: "+mBluetoothHeadset);
Log.d(TAGP,"Proxy: "+proxy);
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = null;
}
}
};
The context can be an activity or service context. So if the code above is in a class that extends Activity or Service you can pass this.
You can use my answer at Using the Android RecognizerIntent with a bluetooth headset

Categories

Resources