配对的Android设备的蓝牙配置文件

时间:2015-04-27 09:05:00

标签: android bluetooth

有没有办法获得配对的blutooth设备的配置文件。 我已经能够配对一个蓝牙设备,它已配对为INPUT_DEVICE 在android中,我得到了BluetoothDevice的Object,其中包含地址和其他内容,但是如果android已经存储了它的配置文件,那么我们可以从中获取配对的设备配置文件,如HEADSET或A2DP或INPUT_DEVICE或其他。

我已经尝试过服务监听器的方法

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;
            }


            }
        }
    };

现在每当我通过

调用它
activity.getAdapter().getProfileProxy(activity, listener,
                BluetoothProfile.HEADSET);

它将转到耳机日志,当我打电话

activity.getAdapter().getProfileProxy(activity, listener,
                BluetoothProfile.HEALTH);

它将转到运行状况日志,并显示已为同一设备连接了配置文件。但同一设备可以同时使用。

我的要求也完全不同于此,我不想尝试不同的场景来找出我已经包含的配对设备的实际配置文件,是他们获取实际配置文件的任何方式..?

1 个答案:

答案 0 :(得分:2)

可以找到与BluetoothDevice相关联的蓝牙配置文件或服务

    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());
                }
            }

我们也可以通过反思提出请求:

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());
        }
    }

此处日志返回远程设备支持的uuids列表,例如在我的情况下我需要连接到两个不同的设备,第一个带有HID配置文件,第二个带有串口或插槽,所以

对于串口设备我正在获取uuid:00001101-0000-1000-8000-00805f9b34fb

for HumanInterface我得到了uuid:00001124-0000-1000-8000-00805f9b34fb

它有bas_uuid:00000000-0000-1000-8000-00805F9B34FB 对于serialPort:0x1101 对于HID:0x1124

可以找到所有这些信息http://bluetooth-pentest.narod.ru/doc/assigned_numbers_-_service_discovery.html

我们也可以通过BluetoothClass检查这个,即

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;

}

对于设备包含的特定类型或服务,它将返回true。

但是根据BluetoothClass规范:

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

https://android.googlesource.com/platform/frameworks/base/+/4f868ed/core/java/android/bluetooth/BluetoothClass.java