首页 > 系统 > Android > 正文

Android 蓝牙自动匹配PIN码跳过用户交互示例

2019-12-12 02:45:28
字体:
来源:转载
供稿:网友

近期项目中需要连接蓝牙设备,起初只是设置蓝牙列表界面让用户点击然后输入默认PIN码,后来改需求了 = = ,要求自动连接指定设备并不需要用户手动输入PIN码,作为Android 小白的我是拒绝的,但是拒绝有什么用~

首先说一下之后会用到的关于蓝牙方面的东西:

  1. 断开蓝牙已配对的设备
  2. 搜索附近蓝牙设备
  3. 拦截用户交互页面,使用代码输入
  4. 由于在最后连接的时候使用的是设备的SDK所以在这里就不介绍了

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();    }  }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表