接上文:
http://ansonlai.iteye.com/blog/2304922
1. 获取蓝牙适配器:
// 得到本机蓝牙设备 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter != null) { Log.i(TAG, "getBluetooth()" + mBluetoothAdapter.isEnabled()); if (mBluetoothAdapter.isEnabled()) { // mLoadingView.setVisibility(View.VISIBLE); } else { mLoadingView.setVisibility(View.GONE); }
2. 添加监听:
void registerBleutoothStateReceiver(){ IntentFilter intentFilter = new IntentFilter(); //创建一个BluetoothReceiver对象 //for discovery . intentFilter.addAction(BluetoothDevice.ACTION_FOUND); intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); //for connection state intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); //for pair intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); intentFilter.addAction("android.bluetooth.device.action.PAIRING_CANCEL"); //for state intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); intentFilter.addAction("android.bluetooth.device.action.PAIRING_REQUEST"); // mBluetoothReceiver = new BluetoothReceiver(); //注册广播接收器 注册完后每次发送广播后,BluetoothReceiver就可以接收到这个广播了 registerReceiver(mBluetoothReceiver, intentFilter); }
3. 获取设备:
已绑定:
// 获得已配对的远程蓝牙设备的集合 Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices();
扫描:
/** * 在开始扫描前, 注意检测是否正在扫描. * start discovery bluetooth devices * @param force */ void startDiscovery(boolean force){ if(mBluetoothAdapter != null && mBluetoothAdapter.isDiscovering()){ ALog.w(TAG, "bluetooth already discovering"); if(!force){ return; }else{ ALog.d(TAG, "startDiscovery restart cancelDiscovery"); mBluetoothAdapter.cancelDiscovery(); } } mBluetoothAdapter.startDiscovery(); }
扫描到设备后, 会有广播:
if(BluetoothDevice.ACTION_FOUND.equals(action)){ //只要BluetoothReceiver接收到来自于系统的广播,这个广播是什么呢,是我找到了一个远程蓝牙设备 //Intent代表刚刚发现远程蓝牙设备适配器的对象,可以从收到的Intent对象取出一些信息 BluetoothDevice device = arg1.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); ALog.d(TAG,"fonud device : " + device.getName() + "(" + device.getAddress() + ")"); }
获取已连接设备:
//可以理解为两个代理, private BluetoothHeadset mBluetoothHeadset=null; private BluetoothA2dp mBluetoothA2dp=null; private BluetoothProfile.ServiceListener mHeadsetProfileServiceListener = new BluetoothProfile.ServiceListener() { @Override public void onServiceDisconnected(int arg0) { // TODO Auto-generated method stub mBluetoothHeadset = null; } @Override public void onServiceConnected(int arg0, BluetoothProfile profile) { // TODO Auto-generated method stub mBluetoothHeadset = (BluetoothHeadset)profile; } }; private BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() { @Override public void onServiceConnected(int arg0, BluetoothProfile arg1) { mBluetoothA2dp = (BluetoothA2dp) arg1; /** 获取已连接设备 **/ List<BluetoothDevice> list = arg1.getConnectedDevices(); } //get profile after bluetooth was enabled mBluetoothAdapter.getProfileProxy(ActivityBluetooth.this, mProfileServiceListener, BluetoothProfile.A2DP); mBluetoothAdapter.getProfileProxy(ActivityBluetooth.this, mHeadsetProfileServiceListener, BluetoothProfile.HEADSET); /** 记得在用完后, 去CLOSE 掉 **/ if(mBluetoothA2dp != null)mBluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, mBluetoothA2dp); if(mBluetoothHeadset != null)mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
4. 配对设备:
调用BluetoothDevice.createBond();
处理状态广播:
if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){ BluetoothDevice device = arg1.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); switch (device.getBondState()) { case BluetoothDevice.BOND_BONDING://11 Log.i("BlueToothTestActivity", "正在配对......"); break; case BluetoothDevice.BOND_BONDED://12 Log.i("BlueToothTestActivity", "完成配对"); break; case BluetoothDevice.BOND_NONE://10 Log.i(TAG, "取消配对"); default: break; }
5. 连接设备:
boolean debugConnect = true; /** connect Bluetooth device **/ boolean connectDevice(BluetoothDevice device){ if(device == null){ ALog.w("connectDevice device is null"); return false; } if(debugConnect)ALog.d(TAG, "try connect to " + device.getName()); boolean result = false; try { result = (Boolean)BluetoothA2dp.class.getDeclaredMethod("connect", BluetoothDevice.class) .invoke(mBluetoothA2dp, device); ALog.d(TAG, "connect to " + device.getName() + (result ? " success": " failed")); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; }
监听连接状态:
if(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)){ BluetoothDevice device = arg1.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); int state = arg1.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.STATE_DISCONNECTED); if(state == BluetoothAdapter.STATE_CONNECTED){ state = BluetoothItem.STATE_CONNECTED; }else if(state == BluetoothAdapter.STATE_CONNECTING){ state = BluetoothItem.STATE_CONNECTING; }else{ state = device.getBondState(); } }
6. 取消配对:
boolean debugUnpair = true; /** UNPAIR device **/ void unpairDevice(){ BluetoothDevice device = mDeviceList.get(mPosition); if(device == null){ ALog.w(TAG, "unpair devcie failed, could NOT find device"); }else{ try { if(debugUnpair)ALog.d(TAG, "try to unbond for " + device.getName()); boolean result = false; if(device.getBondState() == BluetoothDevice.BOND_BONDING){ if(debugUnpair)ALog.d(TAG, "unpair bonding device"); cancelBondProcess(BluetoothDevice.class, device); }else if(device.getBondState() == BluetoothDevice.BOND_BONDED){ if(debugUnpair)ALog.d(TAG, "unpair bonded device"); result = removeBond(BluetoothDevice.class, device); } if(debugUnpair)ALog.d(TAG, "unpair device " + device.getName() + (result ? " success" : " failed")); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // 取消正在配对 private boolean cancelBondProcess(Class bClass, BluetoothDevice device) throws Exception { Method createBondMethod = bClass.getMethod("cancelBondProcess"); Boolean returnValue = (Boolean) createBondMethod.invoke(device); return returnValue.booleanValue(); } private boolean removeBond(Class blass, BluetoothDevice device) throws Exception { Method removeBondMethod = blass.getDeclaredMethod("removeBond"); Boolean returnValue = (Boolean) removeBondMethod.invoke(device); return returnValue.booleanValue(); }
7. 断开连接:
boolean disconnectHeadset(BluetoothDevice device){ if(debugDisconnect)ALog.d(TAG, "start reflect class of BluetoothHeadset"); Class CHeadset = BluetoothHeadset.class; try { Method Mdisconnect = CHeadset.getDeclaredMethod("disconnect", BluetoothDevice.class); if(Mdisconnect != null){ if(debugDisconnect)ALog.d(TAG, "reflect disconnect method success"); Boolean result = (Boolean)Mdisconnect.invoke(mBluetoothHeadset, device); if(debugDisconnect)ALog.d(TAG, "call disconnect method " + (result ? "success":"failed")); return result; } } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } boolean disconnectA2dp(BluetoothDevice device){ if(debugDisconnect)ALog.d(TAG, "start reflect class of BluetoothA2dp"); Class CA2dp = BluetoothA2dp.class; try { Method Mdisconnect = CA2dp.getDeclaredMethod("disconnect", BluetoothDevice.class); if(Mdisconnect != null){ if(debugDisconnect)ALog.d(TAG, "reflect disconnect method success"); Boolean result = (Boolean)Mdisconnect.invoke(mBluetoothA2dp, device); if(debugDisconnect)ALog.d(TAG, "call disconnect method " + (result ? "success":"failed")); return result; } } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } return true; }
PS: 在做其它操作前, 注意取消扫描:
if (mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.cancelDiscovery(); } ;
以上代码仅适应蓝牙音箱或蓝牙耳机, 其它种类的设备暂未兼容测试.
另外, 小米三星等厂商对WIFI/BT这一部分的代码或平台兼容性上做了不少事情.
以上代码兼容性上存在不少问题, 仅仅为了整理和记录,
本文完.