蓝牙连接音响问题(android电视)

最近老大让我开发电视的蓝牙,由于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();
}

上一篇:C/C++:copy control (拷贝控制)


下一篇:第5章 IP地址和子网划分(4)_超网合并网段