Android蓝牙自动配对工具类,亲测好使!!!
蓝牙自动配对,即搜索到其它蓝牙设备之后直接进行配对,不需要弹出配对确认框或者密钥输入框。
经过最近一段时间得研究,针对网上给出的案例。总结了一个亲测好使的Demo。
说明如下:
1、本Demo用来连接蓝牙设备HC-05,如果你要连接其他蓝牙设备,注意修改相关名字以及修改设备初试pin值。
2、将Demo安装在Android手机上,点击按钮,可以实现与目标蓝牙设备的自动配对。
3、若目标蓝牙设备为Android手机的蓝牙,则只能保证本设备不弹出配对框,对方还是会弹出配对框。但是!!不管目标蓝牙点击“确认”or“取消”,在本设备中都显示已经成功配对。实测表明,确实已经配对了,可以进行数据传输。
4、由于使用了广播机制,所以需要在Androidmanifest.xml进行如下配置。
先配置蓝牙使用权限:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
然后配置action,将需要用到的广播进行注册
<receiver android:name="com.ywq.broadcast.BluetoothReceiver" ><intent-filter android:priority="1000"><action android:name="android.bluetooth.device.action.PAIRING_REQUEST"/><action android:name="android.bluetooth.device.action.FOUND" /></intent-filter>
</receiver>
程序运行流程:
1、点击按钮,判断蓝牙是否打开,,执行bluetoothAdapter.startDiscovery();由本地蓝牙设备扫描远程蓝牙设备,startDiscovery()方法是一个异步方法,调用后立即返回。该方法会进行蓝牙设备的搜索,持续12秒。
2、搜索时,系统会发送3个广播,分别为:ACTION_DISCOVERY_START:开始搜索 、ACTION_DISCOVERY_FINISHED:搜索结束、 ACTION_FOUND:找到设备,该Intent中包含两个extra fields;
3、在广播接收类中BluetoothReceiver.Java中,当设备找到之后会执行其onReceive方法。
4、String action = intent.getAction(); //得到action,
第一次action的值为BluetoothDevice.ACTION_FOUND,当找到的设备是我们目标蓝牙设备时,调用createBond方法来进行配对。ClsUtils.createBond(btDevice.getClass(), btDevice);该方法执行后,系统会收到一个请求配对的广播,即android.bluetooth.device.action.PAIRING_REQUEST。最后进行自动配对操作。
5、配对操作借助工具类ClsUtils.java得到了Android蓝牙API中隐藏的方法,实现自动配对,不弹出配对框的功能。
BluetoothReceiver.java
import com.ywq.tools.ClsUtils;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log; public class BluetoothReceiver extends BroadcastReceiver{ String pin = "1234"; //此处为你要连接的蓝牙设备的初始密钥,一般为1234或0000 public BluetoothReceiver() { } //广播接收器,当远程蓝牙设备被发现时,回调函数onReceiver()会被执行 @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); //得到action Log.e("action1=", action); BluetoothDevice btDevice=null; //创建一个蓝牙device对象 // 从Intent中获取设备对象 btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if(BluetoothDevice.ACTION_FOUND.equals(action)){ //发现设备 Log.e("发现设备:", "["+btDevice.getName()+"]"+":"+btDevice.getAddress()); if(btDevice.getName().contains("HC-05"))//HC-05设备如果有多个,第一个搜到的那个会被尝试。 { if (btDevice.getBondState() == BluetoothDevice.BOND_NONE) { Log.e("ywq", "attemp to bond:"+"["+btDevice.getName()+"]"); try { //通过工具类ClsUtils,调用createBond方法 ClsUtils.createBond(btDevice.getClass(), btDevice); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }else Log.e("error", "Is faild"); }else if(action.equals("android.bluetooth.device.action.PAIRING_REQUEST")) //再次得到的action,会等于PAIRING_REQUEST { Log.e("action2=", action); if(btDevice.getName().contains("HC-05")) { Log.e("here", "OKOKOK"); try { //1.确认配对 ClsUtils.setPairingConfirmation(btDevice.getClass(), btDevice, true); //2.终止有序广播 Log.i("order...", "isOrderedBroadcast:"+isOrderedBroadcast()+",isInitialStickyBroadcast:"+isInitialStickyBroadcast()); abortBroadcast();//如果没有将广播终止,则会出现一个一闪而过的配对框。 //3.调用setPin方法进行配对... boolean ret = ClsUtils.setPin(btDevice.getClass(), btDevice, pin); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }else Log.e("提示信息", "这个设备不是目标蓝牙设备"); } }
}
工具类ClsUtils.java
/************************************ 蓝牙配对函数 * **************/ import java.lang.reflect.Method;
import java.lang.reflect.Field;
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(); } }
}
针对网上其它帖子中的demo不好使的原因,在此给出一些我的看法,是不是这样不敢保证,至少部分是这些原因吧。。。
1、出现一个一闪而过的配对框怎么办?
答:那是因为广播没有停止,须得调用abortBroadcast();将广播停止。
2、自动配对框还是会弹出来怎么办?
答:网上好多帖子代码有误,或者没有说清楚。请注意相关配置和工具类中函数的使用。
Android蓝牙自动配对工具类,亲测好使!!!相关推荐
- 【转载】Android蓝牙自动配对Demo
注:新版本安卓需增加权限 <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION ...
- Android 蓝牙串口通信工具类 SeriaPortUtil 2.0.+
原文地址:https://www.shanya.world/archives/2fd981ea.html SerialPortUtil 提示 最新版本 3.0.+ 已发布,其对比 2.0.+ 版本,A ...
- Android TextView 自动排版工具类
使用TextView时会经常出现以下现象: 1.当遇到标点符号时,经常出现自动标点符号加上前面的一个汉字换到下一行,导致当前行出现缺一块的现象 2.当遇到英文时如果一行展示不下就自动换到下一行,排版参 ...
- Android 蓝牙自动匹配PIN码跳过用户交互
近期项目中需要连接蓝牙设备,起初只是设置蓝牙列表界面让用户点击然后输入默认PIN码,后来改需求了 = = ,要求自动连接指定设备并不需要用户手动输入PIN码,作为Android 小白的我是拒绝的,但是 ...
- Android下的蓝牙自动配对
转载 源码下载地址 经过最近一段时间得研究,针对网上给出的案例.总结了一个亲测好使的Demo. 说明如下: 1.本Demo用来连接蓝牙设备HC-05,如果你要连接其他蓝牙设备,注意修改相 ...
- android 实现ble蓝牙自动配对连接
蓝牙自动配对,即搜索到其它蓝牙设备之后直接进行配对,不需要弹出配对确认框或者密钥输入框. 本文章用来连接蓝牙设备ai-thinker,如果你要连接其他蓝牙设备,注意修改相关名字以及修改设备初试pin值 ...
- android蓝牙配对 自动联接,Android系统下蓝牙自动配对连接方法
Android系统下蓝牙自动配对连接方法 [专利摘要]本发明涉及一种Android系统下蓝牙自动配对连接方法,其包括如下步骤:步骤1.在Android设备端内存储上次进行蓝牙连接蓝牙外设的蓝牙地址,并 ...
- android 字体像素转换工具类_android px,dp,sp大小转换工具
package com.voole.playerlib.util; import android.content.Context; /** * Android大小单位转换工具类 * * float s ...
- android 字体像素转换工具类_Android中px与dip,sp与dip等的转换工具类
Android中px与dip,sp与dip等的转换工具类 功能 通常在代码中设置组件或文字大小只能用px,通过这个工具类我们可以把dip(dp)或sp为单位的值转换为以px为单位的值而保证大小不变.方 ...
- android 测试 大赛,轻量级android应用自动测试工具-2017全国大学生软件测试大赛.pdf...
轻量级android应用自动测试工具-2017全国大学生软件测试大赛 DroidBot: A Lightweight Android App Testing Bot 轻量级Android应用自动测试工 ...
最新文章
- 19个人工智能(AI)热门应用领域,你知道多少?
- Longest Y 字符串,货仓选址模型(600)
- ai的预览模式切换_AI字体制作,用AI制作创意阶梯式文字
- OpenSceneGraph 笔记–如何导出三角形数据
- RabbitMQ控制台详解
- selenium webdriver——鼠标事件
- 2022年华为杯中国研究生数学建模竞赛C题思路
- 【生信技能树】GEO数据库挖掘 P5
- 骑在银龙的背上歌词(带罗马音)
- 清水居士与数名志愿者大年三十慰问夏家河村周边贫困家庭
- Android Studio查看错误信息
- 图片水印怎么去掉?图片水印去除方法
- 谷歌在新标签页打开搜索结果(超级新手)
- 哈工大SCIR倾力打造NLP新书,详解预训练语言模型
- UEFI开发与调试--edk2中的基础组件
- 深度暗色调色效果Lr预设
- bigemap卫星地图下载器的优势
- php编程输出心形图案_PHP纯代码生成心形图片并自定义文字
- 通过session来设置登录主界面时,通过过滤器filter判断是否已经登录过,如果已经登陆过可以直接访问主界面,如果没有,需要重新登陆
- NFL定理——没有免费的午餐No Free Lunch Theorem