Reputation: 107
is there any way to get the Profile of a paired blutooth device. i have been able to pair a bluetooth device and it has been paired as INPUT_DEVICE in android, i get the Object of BluetoothDevice for that , which contains the address and other things, but if the android has stored it's profile then from where we can get the paired device profile , like is it HEADSET or A2DP or INPUT_DEVICE or other.
i have already tried the method of service listener
private BluetoothProfile.ServiceListener listener=new BluetoothProfile.ServiceListener() {
@Override
public void onServiceDisconnected(int profile) {
// TODO Auto-generated method stub
//if(profile==BluetoothProfile.HEADSET)
headSet=null;
}
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
// TODO Auto-generated method stub
switch(profile){
case BluetoothProfile.HEADSET:
Log.e("found","headset");
break;
case BluetoothProfile.A2DP:
Log.e("found","a2dp");
activity.onA2DPListenr((BluetoothA2dp) proxy);
break;
case BluetoothProfile.HEALTH:
Log.e("found","HEALTH");
break;
}
}
}
};
now whenever i call it via
activity.getAdapter().getProfileProxy(activity, listener,
BluetoothProfile.HEADSET);
it'll go to headset log, and when i call with
activity.getAdapter().getProfileProxy(activity, listener,
BluetoothProfile.HEALTH);
it'll go to health log, and shows that the profile has been connected for same device.but the same device can bot be both.
also my requirment totally different from this, i don't want to try different scenarios to find out the actual profile of my paired device which android already contains, is their any way to get the actual profile..?
Upvotes: 1
Views: 2727
Reputation: 107
the bluetooth profile or service associated with the BluetoothDevice can be found by
boolean hasLatestUuids=device.fetchUuidsWithSdp();
if(hasLatestUuids){
/*getUuids() return cached uuids so we need to make an sdp request to get refresh uuid associated with the device*/
ParcelUuid[] uu=device.getUuids();
for(ParcelUuid u:uu){
Log.e("found","uuid "+u.getUuid());
}
}
we can also make request via reflection as:
Method m=null;
boolean hasLatestUuid=false;
try {
m=BluetoothDevice.class.getDeclaredMethod("fetchUuidsWithSdp", null);
m.setAccessible(true);
hasLatestUuid=(Boolean) m.invoke(device, null);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ParcelUuid[] uuids=null;
if(hasLatestUuid){
try {
m=device.getClass().getDeclaredMethod("getUuids", null);
m.setAccessible(true);
uuids=(ParcelUuid[]) m.invoke(device, null);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(uuids!=null){
for(ParcelUuid u:uuids){
Log.e("found","uuid "+u.describeContents());
Log.e("found","uuid "+u.getUuid());
}
}
here the log return the uuids list supported by the remote device, for example in my case i need to connect to two different devices , first one with HID profile and second with serial port or socket, so
for serial port device i am getting uuid:00001101-0000-1000-8000-00805f9b34fb
for HumanInterface i am getting uuid:00001124-0000-1000-8000-00805f9b34fb
it has bas_uuid:00000000-0000-1000-8000-00805F9B34FB and for serialPort:0x1101 and for HID:0x1124
all these information can be found http://bluetooth-pentest.narod.ru/doc/assigned_numbers_-_service_discovery.html
we can also check this via BluetoothClass i.e
public static final int PROFILE_HEADSET = 0;
/** @hide */
public static final int PROFILE_A2DP = 1;
/** @hide */
public static final int PROFILE_OPP = 2;
/** @hide */
public static final int PROFILE_HID = 3;
/** @hide */
public static final int PROFILE_PANU = 4;
/** @hide */
public static final int PROFILE_NAP = 5;
BluetoothClass myClass=device.getBluetoothClass();
int val=myClass.getDeviceClass();
Log.e("found","class "+val);
Log.e("found","class "+(val|bitmask));
Log.e("found","PROFILE_HEADSET:"+doesclassMatch(PROFILE_HEADSET,myClass));
Log.e("found","PROFILE_A2DP:"+doesclassMatch(PROFILE_A2DP,myClass));
Log.e("found","PROFILE_OPP:"+doesclassMatch(PROFILE_OPP,myClass));
Log.e("found","PROFILE_HID:"+doesclassMatch(PROFILE_HID,myClass));
Log.e("found","PROFILE_PANU:"+doesclassMatch(PROFILE_PANU,myClass));
Log.e("found","PROFILE_NAP:"+doesclassMatch(PROFILE_NAP,myClass));
private boolean doesclassMatch(int profile,BluetoothClass myClass){
Method m=null;
try {
m=BluetoothClass.class.getMethod("doesClassMatch", new Class[]{int.class});
m.setAccessible(true);
return (Boolean) m.invoke(myClass, profile);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
it'll return true for particular type or service the device contain.
but as per BluetoothClass specification:
BluetoothClass is useful as a hint to roughly describe a device
* (for example to show an icon in the UI), but does not reliably describe which
* Bluetooth profiles or services are actually supported by a device. Accurate
* service discovery is done through SDP requests, which are automatically
* performed when creating an RFCOMM socket with
* BluetoothDevice#createRfcommSocketToServiceRecord} and
* BluetoothAdapter#listenUsingRfcommWithServiceRecord
Upvotes: 2