这里有新鲜出炉的精品教程,程序狗速度看过来!
Android 是一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 "安卓" 或 "安致"。
本篇文章主要介绍了 Android 蓝牙自动匹配 PIN 码跳过用户交互示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
近期项目中需要连接蓝牙设备,起初只是设置蓝牙列表界面让用户点击然后输入默认 PIN 码,后来改需求了 = = ,要求自动连接指定设备并不需要用户手动输入 PIN 码,作为 Android 小白的我是拒绝的,但是拒绝有什么用~
首先说一下之后会用到的关于蓝牙方面的东西:
1. 断开已配对设备
最后在项目中发现没有用。这里就先记录一下。
- //得到配对的设备列表,清除已配对的设备
- public void removePairDevice() {
- if (mBluetoothAdapter != null) {
- //mBluetoothAdapter初始化方式 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
- //这个就是获取已配对蓝牙列表的方法
- Set < BluetoothDevice > bondedDevices = mBluetoothAdapter.getBondedDevices();
- for (BluetoothDevice device: bondedDevices) {
- //这里可以通过device.getName() device.getAddress()来判断是否是自己需要断开的设备
- unpairDevice(device);
- }
- }
- }
- //反射来调用BluetoothDevice.removeBond取消设备的配对
- private void unpairDevice(BluetoothDevice device) {
- try {
- Method m = device.getClass().getMethod("removeBond", (Class[]) null);
- m.invoke(device, (Object[]) null);
- } catch(Exception e) {
- Log.e("mate", e.getMessage());
- }
- }
2. 搜索附近蓝牙
首先我们需要注册两个广播,第一个为正在搜索时的,第二个为搜索完成的。
- // Register for broadcasts when a device is discovered
- IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
- this.registerReceiver(mFindBlueToothReceiver, filter);
- // Register for broadcasts when discovery has finished
- filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
- this.registerReceiver(mFindBlueToothReceiver, filter);
- //需要时开始搜索
- if (mBluetoothAdapter.isDiscovering()) {
- mBluetoothAdapter.cancelDiscovery();
- }
- mBluetoothAdapter.startDiscovery();
然后对广播进行处理。这里要说明一下 ClsUtils.createBond() 这个方法如果连接设备 SDK 中有配对的方法,建议把这个方法去掉,我这里是去掉的,加上的话偶尔会 Toast 出无法配对。
- private final BroadcastReceiver mFindBlueToothReceiver = new BroadcastReceiver() {@Override public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- // When discovery finds a device
- if (BluetoothDevice.ACTION_FOUND.equals(action)) {
- //TODO 开始搜索
- BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- // if (device.getBondState() != BluetoothDevice.BOND_BONDED) {//判断蓝牙状态,是否是已配对
- //TODO 可以在这判断名字 如果搜索结束后没有,再到已配对中寻找
- String BTName[] = device.getName().split("-");
- if (BTName[0].equals("xxx")) {
- //在这连接设备 一般需要蓝牙地址 device.getAddress();
- try {
- ClsUtils.createBond(device.getClass(), device);
- } catch(Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- // }
- } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
- //TODO 搜索结束
- Toast.makeText(context, "搜索结束", Toast.LENGTH_SHORT).show();
- }
- }
- };
这里在 Activity 结束时记得取消注册和取消搜索
- unregisterReceiver(mFindBlueToothReceiver);
- if (mBluetoothAdapter != null) {
- mBluetoothAdapter.cancelDiscovery();
- }
3. 拦截用户交互页面
通过广播可以监听到输入 PIN 码的那个页面将要弹出
- <receiver android:name=".BluetoothConnectActivityReceiver" >
- <intent-filter android:priority="1000">
- <action android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
- </intent-filter>
- </receiver>
广播中需要做的事情,注意一定要调用 abortBroadcast(),不然交互页面还是会出现一下然后消失。就是这个方法找了一天(╯‵□′)╯︵┴─┴。。。
- public class BluetoothConnectActivityReceiver extends BroadcastReceiver {
- @Override public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals("android.bluetooth.device.action.PAIRING_REQUEST")) {
- BluetoothDevice mBluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- try {
- //(三星)4.3版本测试手机还是会弹出用户交互页面(闪一下),如果不注释掉下面这句页面不会取消但可以配对成功。(中兴,魅族4(Flyme 6))5.1版本手机两中情况下都正常
- //ClsUtils.setPairingConfirmation(mBluetoothDevice.getClass(), mBluetoothDevice, true);
- abortBroadcast(); //如果没有将广播终止,则会出现一个一闪而过的配对框。
- //3.调用setPin方法进行配对...
- boolean ret = ClsUtils.setPin(mBluetoothDevice.getClass(), mBluetoothDevice, "你需要设置的PIN码");
- } catch(Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
然后只要在搜索到自己需要的设备后连接进行操作就可以了!!!一定要记得加权限~
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
- <uses-permission android:name="android.permission.BLUETOOTH" />
在 Android6.0 之后还需要一个模糊定位的权限
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
最后把 ClsUtils 类奉上,网上有很多的。
- /**************** 蓝牙配对函数 ***************/
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import android.bluetooth.BluetoothDevice;
- import android.util.Log;
- public class ClsUtils {
- /**
- * 与设备配对 参考源码:platform/packages/apps/Settings.git
- * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
- */
- static public boolean createBond(Class btClass, BluetoothDevice btDevice) throws Exception {
- Method createBondMethod = btClass.getMethod("createBond");
- Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
- return returnValue.booleanValue();
- }
- /**
- * 与设备解除配对 参考源码:platform/packages/apps/Settings.git
- * /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
- */
- static public boolean removeBond(Class < ?>btClass, BluetoothDevice btDevice) throws Exception {
- Method removeBondMethod = btClass.getMethod("removeBond");
- Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
- return returnValue.booleanValue();
- }
- static public boolean setPin(Class < ?extends BluetoothDevice > btClass, BluetoothDevice btDevice, String str) throws Exception {
- try {
- Method removeBondMethod = btClass.getDeclaredMethod("setPin", new Class[] {
- byte[].class
- });
- Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice, new Object[] {
- str.getBytes()
- });
- Log.e("returnValue", "" + returnValue);
- } catch(SecurityException e) {
- // throw new RuntimeException(e.getMessage());
- e.printStackTrace();
- } catch(IllegalArgumentException e) {
- // throw new RuntimeException(e.getMessage());
- e.printStackTrace();
- } catch(Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return true;
- }
- // 取消用户输入
- static public boolean cancelPairingUserInput(Class < ?>btClass, BluetoothDevice device) throws Exception {
- Method createBondMethod = btClass.getMethod("cancelPairingUserInput");
- // cancelBondProcess(btClass, device);
- Boolean returnValue = (Boolean) createBondMethod.invoke(device);
- return returnValue.booleanValue();
- }
- // 取消配对
- static public boolean cancelBondProcess(Class < ?>btClass, BluetoothDevice device) throws Exception {
- Method createBondMethod = btClass.getMethod("cancelBondProcess");
- Boolean returnValue = (Boolean) createBondMethod.invoke(device);
- return returnValue.booleanValue();
- }
- //确认配对
- static public void setPairingConfirmation(Class < ?>btClass, BluetoothDevice device, boolean isConfirm) throws Exception {
- Method setPairingConfirmation = btClass.getDeclaredMethod("setPairingConfirmation", boolean.class);
- setPairingConfirmation.invoke(device, isConfirm);
- }
- /**
- *
- * @param clsShow
- */
- static public void printAllInform(Class clsShow) {
- try {
- // 取得所有方法
- Method[] hideMethod = clsShow.getMethods();
- int i = 0;
- for (; i < hideMethod.length; i++) {
- Log.e("method name", hideMethod[i].getName() + ";and the i is:" + i);
- }
- // 取得所有常量
- Field[] allFields = clsShow.getFields();
- for (i = 0; i < allFields.length; i++) {
- Log.e("Field name", allFields[i].getName());
- }
- } catch(SecurityException e) {
- // throw new RuntimeException(e.getMessage());
- e.printStackTrace();
- } catch(IllegalArgumentException e) {
- // throw new RuntimeException(e.getMessage());
- e.printStackTrace();
- } catch(Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
来源: http://www.phperz.com/article/17/0821/337557.html