最近老大让我开发电视的蓝牙,因为android电视的蓝牙不稳定和设计上的各类各样的要求,须要在原有的基础上作一些更改,中间遇到了各类问题,在此总结一下。html
咱们首先要获取blueToothAdapter的对象 android
转发:http://www.cnblogs.com/hyylog/p/5796711.html;ide
mBluetoothAdapter = bluetoothManager.getAdapter();spa
一、蓝牙的打开:设计
mBluetoothAdapter.enable();htm
二、蓝牙关闭:对象
mBluetoothAdapter.disenable();blog
三、蓝牙是否可见:开发
这个地方系统隐藏了其方法,咱们就要用万能公式(反射)来实现:rem
可见:
public static void setDiscoverableTimeout(int timeout) {
BluetoothAdapter adapter=BluetoothAdapter.getDefaultAdapter();
try {
Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
setDiscoverableTimeout.setAccessible(true);
Method setScanMode =BluetoothAdapter.class.getMethod("setScanMode", int.class,int.class);
setScanMode.setAccessible(true);
setDiscoverableTimeout.invoke(adapter, timeout);
setScanMode.invoke(adapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE,timeout);
} catch (Exception e) {
e.printStackTrace();
}
}
当timeout设置为0的时候为永久可见
关闭:
public static void closeDiscoverableTimeout() {
BluetoothAdapter adapter=BluetoothAdapter.getDefaultAdapter();
try {
Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
setDiscoverableTimeout.setAccessible(true);
Method setScanMode =BluetoothAdapter.class.getMethod("setScanMode", int.class,int.class);
setScanMode.setAccessible(true);
setDiscoverableTimeout.invoke(adapter, 1);
setScanMode.invoke(adapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE,1);
} catch (Exception e) {
e.printStackTrace();
}
}
四、蓝牙搜索,中止:
开启搜索:mBluetoothAdapter.startDiscovery();
中止搜索:mBluetoothAdapter.cancelDiscovery();
五、蓝牙的配对、取消配对:
配对:
static public boolean pair(String strAddr, byte[] strPsw) {
boolean result = false;
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.cancelDiscovery();
if (!bluetoothAdapter.isEnabled()) {
bluetoothAdapter.enable();
}
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(strAddr);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
try {
Log.d("mylog", "NOT BOND_BONDED");
boolean flag1 = ClsUtils.setPin(device.getClass(), device,
strPsw);
boolean flag2 = ClsUtils.createBond(device.getClass(), device);
// remoteDevice = device;
result = true;
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("mylog", "setPiN failed!");
e.printStackTrace();
} //
} else {
Log.d("mylog", "HAS BOND_BONDED");
try {
ClsUtils.removeBond(device.getClass(), device);
// ClsUtils.createBond(device.getClass(), device);
boolean flag1 = ClsUtils.setPin(device.getClass(), device,
strPsw);
boolean flag2 = ClsUtils.createBond(device.getClass(), device);
result = true;
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("mylog", "setPiN failed!");
e.printStackTrace();
}
}
return result;
}
取消配对:
static public boolean removeBond(Class<? extends BluetoothDevice> btClass,
BluetoothDevice btDevice) throws Exception {
Method removeBondMethod = btClass.getMethod("removeBond");
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
六、蓝牙的链接:
音响的链接主要是BluetoothA2dp协议,BluetoothHeadset协议主要用于耳机的,可是在实际的操做过程当中若是只链接BluetoothA2dp对于广播的接受是不正常的且有时候也是不发声的,因此这两个协议要一块儿链接
首先要启动这两个协议的服务监听:
private BluetoothProfile.ServiceListener mA2dpProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.A2DP) {
mBluetoothA2dp = (BluetoothA2dp) proxy;
try {
if(realConnect)
ClsUtils.connect(mBluetoothA2dp.getClass(),mBluetoothA2dp, mDevice);
} catch (Exception e) {
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, mBluetoothA2dp);
e.printStackTrace();
}
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.A2DP) {
mBluetoothA2dp = null;
}
}
};
/**
* @Fields mHeadsetProfileListener : BluetoothHeadset服务监听器
*/
private BluetoothProfile.ServiceListener mHeadsetProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = (BluetoothHeadset) proxy;
try {
if(realConnect)
ClsUtils.connect(mBluetoothHeadset.getClass(),mBluetoothHeadset, mDevice);
} catch (Exception e) {
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
e.printStackTrace();
}
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = null;
}
}
};
链接:
mBluetoothAdapter.getProfileProxy(mContext, mA2dpProfileListener, BluetoothProfile.A2DP);
mBluetoothAdapter.getProfileProxy(mContext, mHeadsetProfileListener, BluetoothProfile.HEADSET);
断开:
@Override
public void disconnectBlueTooth(BluetoothDevice device) {
mDevice = device;
if(mBluetoothA2dp!=null){
try {
ClsUtils.disconnect(mBluetoothA2dp.getClass(),mBluetoothA2dp, device);
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, mBluetoothA2dp);
} catch (Exception e) {
e.printStackTrace();
}
}
if(mBluetoothHeadset!=null){
try {
ClsUtils.disconnect(mBluetoothHeadset.getClass(),mBluetoothHeadset, device);
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
} catch (Exception e) {
e.printStackTrace();
}
}
}
其次得到A2dp和headset对象也用上述的监听方法
七、每次打开蓝牙获取已经链接的蓝牙设备:
int a2dp = bluetoothAdapter.getProfileConnectionState(BluetoothProfile.A2DP); int headset = bluetoothAdapter.getProfileConnectionState(BluetoothProfile.HEADSET); int health = bluetoothAdapter.getProfileConnectionState(BluetoothProfile.HEALTH); int flag = -1; if (a2dp == BluetoothProfile.STATE_CONNECTED) { flag = a2dp; } else if (headset == BluetoothProfile.STATE_CONNECTED) { flag = headset; } else if (health == BluetoothProfile.STATE_CONNECTED) { flag = health; } if (flag != -1) { bluetoothAdapter.getProfileProxy(mcContext, new ServiceListener() { @Override public void onServiceDisconnected(int profile) { } @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { List<BluetoothDevice> mDevices = proxy.getConnectedDevices(); } }, flag); }else{ listener.disConnected(); }