效果

权限

 <uses-permission android:name="android.permission.BLUETOOTH"/><uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

动态申请权限

public class ApplyPermission {public static void ApplyPermission(Context context) {ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.BLUETOOTH,Manifest.permission.BLUETOOTH_ADMIN,}, 1);}
}

连接工具类

/*** @anthor GrainRain* @funcation 蓝牙连接工具类* @date 2019/11/7*/
public class Util {//存放蓝牙设备名列表private static ArrayList<String> deviceNameList = new ArrayList<>();//存放蓝牙设备mac地址列表private static ArrayList<String> deviceMacList = new ArrayList<>();//存放蓝牙设备名和地址 用于显示private static ArrayList<String> deviceMsgList = new ArrayList<>();//存放已配对蓝牙列表private static ArrayList<String> pairedDeviceNameList = new ArrayList<>();private static Context context;private static BluetoothDevice btDevice;private static ArrayList<BluetoothDevice> btDeviceList = new ArrayList<>();private static OnConnectListener onConnectListener;private static final String[] items = new String[100];private static ArrayAdapter<String> adapter = null;private static BluetoothAdapter blueadapter;//这条是蓝牙串口通用的UUID,不要更改private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");private static BluetoothSocket btSocket = null;private static OutputStream outStream = null;private static InputStream inStream = null;private static int deviceMatchingNum = 0;private static boolean deviceMatching = false;private static ReceiveThread rThread = null;  //数据接收线程public Util() {for(int i = 0; i < items.length; i++) {items[i] = "";}}public void get(Context context, OnConnectListener listener) {setContext(context);showListDialog();blueadapter = BluetoothAdapter.getDefaultAdapter();//判断蓝牙是否打开if(!blueadapter.isEnabled()) {//            blueadapter.enable();} else {getContext().registerReceiver(bluetoothReceiver, intentFilter);//用BroadcastReceiver 来取得结果doDiscovry();}setOnConnectListener(listener);listener.onConnectSuccess(null);listener.onConnectFailed(null);}static IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);//注册广播接收信号private static final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction(); //得到action//创建一个蓝牙device对象 从Intent中获取设备对象btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);btDeviceList.add(btDevice);//获取已配对蓝牙列表
//            Set<BluetoothDevice> devices = blueadapter.getBondedDevices();
//            for (BluetoothDevice bluetoothDevice : devices) {//                pairedDeviceNameList.add(bluetoothDevice.getName());
//            }//发现设备if(BluetoothDevice.ACTION_FOUND.equals(action)){BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);deviceMsgList.add(device.getName() + " " + device.getAddress());//将搜索到的蓝牙名称和地址添加到列表deviceNameList.add(device.getName());       //将搜索到的蓝牙名称添加到列表deviceMacList.add(device.getAddress());     //将搜索到的蓝牙地址添加到列表Log.w("-----------------", deviceMsgList.get(deviceMsgList.size()-1));items[deviceMsgList.size()-1] = deviceMsgList.get(deviceMsgList.size()-1);adapter.notifyDataSetChanged();}}};private static void doDiscovry() {if (blueadapter.isDiscovering()) {//判断蓝牙是否正在扫描,如果是调用取消扫描方法;如果不是,则开始扫描blueadapter.cancelDiscovery();} elseblueadapter.startDiscovery();}//搜索到的蓝牙列表private void showListDialog() {final AlertDialog.Builder listDialog = new AlertDialog.Builder(context);adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, items);listDialog.setAdapter(adapter, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {for(int j = 0; j < btDeviceList.size(); j++) {if(btDeviceList.get(j).getAddress().equals(btDeviceList.get(i).getAddress())) {deviceMatching = true;deviceMatchingNum = j;}}//连接配对if(deviceMatching) {//HC-05设备如果有多个,第一个搜到的那个会被尝试。if (btDeviceList.get(deviceMatchingNum).getBondState() == BluetoothDevice.BOND_NONE) {//未配对 进行配对try {//通过工具类ClsUtils,调用createBond方法PairUtils.createBond(btDeviceList.get(deviceMatchingNum).getClass(), btDeviceList.get(deviceMatchingNum));} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}} else {//已配对 进行连接//mac 要连接的目标蓝牙设备MAC地址new ConnectTask().execute(deviceMacList.get(deviceMatchingNum));}}}});listDialog.setPositiveButton("返回", new DialogInterface.OnClickListener() {public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {listDialog.create();}});listDialog.show();}//连接蓝牙设备的异步任务static class ConnectTask extends AsyncTask<String,String,String> {@Overrideprotected String doInBackground(String... params) {// TODO Auto-generated method stubBluetoothDevice device = blueadapter.getRemoteDevice(params[0]);try {btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);btSocket.connect();Log.e("error", "ON RESUME: BT connection established, data transfer link open.");} catch (IOException e) {try {//将异常信息传递给回调接口if(getOnConnectListener() != null) {getOnConnectListener().onConnectFailed(e);}btSocket.close();return "Socket 创建失败";} catch (IOException e2) {//将异常信息传递给回调接口if(getOnConnectListener() != null) {getOnConnectListener().onConnectFailed(e2);}Log .e("error","ON RESUME: Unable to close socket during connection failure", e2);return "Socket 关闭失败";}}//取消搜索blueadapter.cancelDiscovery();try {outStream = btSocket.getOutputStream();} catch (IOException e) {//将异常信息传递给回调接口if(getOnConnectListener() != null) {getOnConnectListener().onConnectFailed(e);}Log.e("error", "ON RESUME: Output stream creation failed.", e);return "Socket 流创建失败";}return "蓝牙连接正常,Socket 创建成功";}@Override    //这个方法是在主线程中运行的,所以可以更新界面protected void onPostExecute(String result) {// TODO Auto-generated method stub//连接成功则启动监听rThread = new ReceiveThread();rThread.start();Log.e("Bluetooth", "连接状态:" + result);super.onPostExecute(result);}}//从蓝牙接收信息的线程static class ReceiveThread extends Thread {@Overridepublic void run() {while(btSocket != null ) {//定义一个存储空间buffbyte[] buff = new byte[1024];try {inStream = btSocket.getInputStream();System.out.println("waitting for instream");if(inStream != null) {inStream.read(buff); //读取数据存储在buff数组中}processBuffer(buff,1024);} catch (IOException e) {e.printStackTrace();}}}public void processBuffer(byte[] buff,int size) {int length = 0;for(int i = 0; i < size; i++) {if(buff[i] > '\0') {length++;} else {break;}}//newbuff字节数组,用于存放真正接收到的数据byte[] newbuff = new byte[length];int[] receiveData = new int[length];for(int j = 0; j < length; j++) {newbuff[j] = buff[j];receiveData[j] = buff[j] & 0xff;}Log.w("收到数据: ", Arrays.toString(receiveData));//回调if(getOnConnectListener() != null) {getOnConnectListener().onConnectSuccess(receiveData);}}}//发送String数据到蓝牙设备的异步任务static class SendInfoTask extends AsyncTask<String,String,String> {@Overrideprotected void onPostExecute(String result) {// TODO Auto-generated method stubsuper.onPostExecute(result);Log.e("Bluetooth", "连接状态:" + result);}@Overrideprotected String doInBackground(String... arg0) {// TODO Auto-generated method stubif(btSocket == null) {new ConnectTask().execute(deviceMacList.get(deviceMatchingNum));return "还没有创建连接";}if(arg0[0].length()>0) {//不是空白串//String target=arg0[0];byte[] msgBuffer = arg0[0].getBytes();try {if(outStream != null) {//  将msgBuffer中的数据写到outStream对象中outStream.write(msgBuffer);}} catch (IOException e) {Log.e("error", "ON RESUME: Exception during write.", e);return "发送失败";}}return "发送成功";}}//发送byte数据到蓝牙设备的异步任务/*static class SendInfoTask extends AsyncTask<byte[], String, String> {@Overrideprotected String doInBackground(byte[]... bytes) {try {outStream.write(bytes[0]);} catch (IOException e) {e.printStackTrace();}return null;}@Overrideprotected void onPostExecute(String result) {// TODO Auto-generated method stubsuper.onPostExecute(result);}
}
*///回调接口public interface OnConnectListener{//连接成功void onConnectSuccess(int[] msg);//连接异常信息void onConnectFailed(Exception e);}public static OnConnectListener getOnConnectListener() {return onConnectListener;}public void setOnConnectListener(OnConnectListener onConnectListener) {this.onConnectListener = onConnectListener;}public static Context getContext() {return context;}public void setContext(Context context) {this.context = context;}
}

配对工具类

/*** @anthor GrainRain* @funcation 配对工具类* @date 2019/10/25*/
public class PairUtils {/*** 与设备配对 参考源码: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", 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 blocke.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 blocke.printStackTrace();}}
}

使用 activity

 //打开蓝牙if(!BluetoothAdapter.getDefaultAdapter().isEnabled()) {BluetoothAdapter.getDefaultAdapter().enable();}

通过回调接收信息

    new Util().get(BlueAct.this, new Util.OnConnectListener() {@Overridepublic void onConnectSuccess(int[] msg) {}@Overridepublic void onConnectFailed(Exception e) {}});

Android 蓝牙配对、连接和通信相关推荐

  1. Android蓝牙A2DP连接实现

    代码地址如下: http://www.demodashi.com/demo/14624.html 开发环境: 开发工具:Androidstudio 适配机型:honor8(Android6.0), 坚 ...

  2. 传统蓝牙配对连接,为何有些蓝牙模块只配对没连接上?

    最近调试需求,针对性对某个无屏幕的设备编写了个蓝牙日志传输应用,也很简单,即使把log和log文件通过蓝牙传输到另一台设备查看,不多说,讲下蓝牙配对连接.直接上代码 public class BleL ...

  3. android 蓝牙自动断开,Android蓝牙:连接()/断开()

    我目前正在设计一个应用程序,它需要连接到设备,写入/读取数据,并可靠地关闭连接.目前我有写/读固体.我的断开连接然后重新连接非常不可靠,并且经常实际上使手机崩溃.我一直在寻找通过大量文章试图弄清楚和. ...

  4. Android蓝牙配对时不弹框

    Android蓝牙配对框,根据输出log看到,包名是com.android.settings.bluetooth.BluetoothPairingDialog 是在Android原生Setting里面 ...

  5. android 实现蓝牙自动配对连接,Android实践 -- Android蓝牙设置连接

    蓝牙开发相关 使用Android Bluetooth APIs将设备通过蓝牙连接并通信,设置蓝牙,查找蓝牙设备,配对蓝牙设备 连接并传输数据,以下是Android系统提供的蓝牙相关的类和接口 Blue ...

  6. Android蓝牙搜索连接通信

    蓝牙( Bluetooth® ):是一种无线技术标准,可实现固定设备.移动设备和楼宇个人域网之间的短距离数据交换(使用2.4-2.485GHz的ISM波段的UHF无线电波).蓝牙技术最初由电信巨头爱立 ...

  7. android蓝牙配对 自动联接,Android系统下蓝牙自动配对连接方法

    Android系统下蓝牙自动配对连接方法 [专利摘要]本发明涉及一种Android系统下蓝牙自动配对连接方法,其包括如下步骤:步骤1.在Android设备端内存储上次进行蓝牙连接蓝牙外设的蓝牙地址,并 ...

  8. android蓝牙配对 自动联接,如何实现android蓝牙开发 自动配对连接,并不弹出提示框...

    之前做一个android版的蓝牙 与血压计通讯的项目,遇到最大的难题就是自动配对. 上网查资料说是用反射createBond()和setPin(),但测试时进行配对还是会出现提示,但配对是成功了 我就 ...

  9. android 蓝牙自动连接,蓝牙自动连接实现

    实现的主要功能(蓝牙配对成功如何与远程设备一直连接) 1.当蓝牙配对成功连接时,断开远程端设备会自动连接 2.当设备长时间锁屏会导致CachedBluetoothDevice自动清空,如果蓝牙断开就不 ...

  10. android 蓝牙串口连接不上,安卓手机搜索不到蓝牙模块HC-06,是怎么回事?

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 问题0010:蓝牙串口模块使用的正确步骤 很多人现在都开始使用蓝口模块,利用手机蓝牙或者PC蓝牙进行控制单片机系统.但是很多人一上来就直接把蓝牙模块和单片 ...

最新文章

  1. django-查询-F对象-Q对象
  2. UITextView自定义placeholder功能:用一个label写了文字,然后当检测到长度不为0的时候就把label隐藏...
  3. Java10的新特性
  4. 常用技巧性CSS:颜色渐变,截断英文单词,阴影文字.
  5. VMware Workstation “The Msi Failed”解决方法
  6. numpy——numpy.corrcoef
  7. Java:Spring @Transactional工作原理
  8. python-jieba-分词----官方文档截取
  9. The GDM user does not exist.Please correct gdm configration and restart gdm
  10. VsCode配置Java环境
  11. Alibaba代码检查工具插件
  12. 一文学懂risc-v汇编操作
  13. 切换阿里巴巴开源镜像站镜像——Kali镜像
  14. 别再问我Android前景如何了?我都要发飙了
  15. 编程猫李天驰:让编程教育回归互联网
  16. ubuntu中ping停不下来的解决
  17. win10更新后应用无法连接服务器,win10更新无法连接到更新服务怎么办_win10无法连接到更新服务的解决方法...
  18. python程序猿_python程序员指南 pdf下载
  19. 项目经历怎么写_简历里的项目经历怎么写才能打动招生官和面试官?
  20. 云端守望者(上):十二道难关

热门文章

  1. 用vuejs如何实现ajax,vuejs使用FormData实现ajax上传图片文件
  2. 微信小程序——仿写京东购物商城带源码
  3. Redhat 国内Yum源配置
  4. html鼠标经过小手,css鼠标小手
  5. css的鼠标手势总结
  6. 推荐一款很好用的小说APP——追书神器
  7. bs4.BeautifulSoup获取outerHTML和innerHTML
  8. 网络分析工具-Mtr
  9. 智慧城管三维可视化决策系统平台(数字孪生)-解决方案开发案例
  10. 上海大华条码称代码_上海大华条码秤简易说明书