最近老大让我开发电视的蓝牙,由于android电视的蓝牙不稳定和设计上的各种各样的要求,需要在原有的基础上做一些更改,中间遇到了各种问题,在此总结一下。
我们首先要获取blueToothAdapter的对象
转发:http://www.cnblogs.com/hyylog/p/5796711.html;
mBluetoothAdapter = bluetoothManager.getAdapter();
1、蓝牙的打开:
mBluetoothAdapter.enable();
2、蓝牙关闭:
mBluetoothAdapter.disenable();
3、蓝牙是否可见:
这个地方系统隐藏了其方法,我们就要用万能公式(反射)来实现:
可见:
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();
}
}
4、蓝牙搜索,停止:
开启搜索:mBluetoothAdapter.startDiscovery();
停止搜索:mBluetoothAdapter.cancelDiscovery();
5、蓝牙的配对、取消配对:
配对:
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();
}
6、蓝牙的连接:
音响的连接主要是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对象也用上述的监听方法
7、每次打开蓝牙获取已经连接的蓝牙设备:
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();
}