Android蓝牙自动配对工具类,亲测好使!!!

Android 蓝牙工具类封装:支持经典蓝牙与 BLE,兼容高版本权限 为了优化经典蓝牙(Classic Bluetooth)和低功耗蓝牙(Bluetooth Low Energy, BLE)的操作,我们可以将功能封装到一个工具类中,支持扫描、连接、通信,并兼容高版本 Android 的动态权限申请。在 Android 12 及以上版本,需要动态申请 BLUETOOTH_SCAN 和 BLUETOOTH_CONNECT 权限。通过以上工具类,你可以轻松实现经典蓝牙和 BLE 的扫描、连接和通信功能,并兼容高版本 Android 的权限要求。BLE蓝牙发送和接收数据。 阅读详情

蓝牙自动配对,即搜索到其它蓝牙设备之后直接进行配对,不需要弹出配对确认框或者密钥输入框。
经过最近一段时间得研究,针对网上给出的案例。总结了一个亲测好使的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 实现蓝牙自动配对连接 BluetoothConnectActivityReceiver.java:监听蓝牙配对的广播 代码: package com.imte.Broadcast; import com.imte.utils.ClsUtils; import com.itme.ActivityClass.R; import android.bluetooth.BluetoothDevice; import 阅读详情

相关推荐

蓝牙自动配对怎么实现

明年就要毕业了,所以最近开始刷面试题,碰到了一个问题“蓝牙自动配对怎么实现的?”,刚开始有点懵逼了。于是学习一波,记录下来。 1 实现过程及原理   配对是建立连接的基础,任何从未配对过的设备(或曾经配对但其中一方已删除配对关系)都无法建立连接,因此配对无法绕过。配对的方式有输入pin码、输入密码、免输入的随机验证码等多种。当前XX设备与控制端的配对方式为免输入的随机验证码,两端确认6位数密码...

a1920135141的博客 1万+

Android蓝牙状态工具类 BlueToothUtils

蓝牙状态工具类 BlueToothUtils。

唐诺 330

Android蓝牙的配对流程

本文主要结合源码研究蓝牙的配对过程以上就是今天要讲的内容,本文仅仅简单介绍了蓝牙的配对流程。

其实我是一个演员 3724

Android BLE最完整的工具类(扫描/连接/读写/通知设备)

这里只要是Android设备与BLE设备的通讯都可以共用,只需要该的就是uuid的值,还有就是ble设备提供商要出文档协议,看看是如何发命令跟接收命令的。 bleUtil工具中,有些地方我感觉还是要提示下 1、characterUUID1 、characterUUID2 、descriptorUUID 这三个是对应的收发命令的,跟找到要操作的BluetoothGattDescriptor(特性...

无论何时都不要停止学习,这是改变自己的必要条件 1万+

android系统蓝牙自动配对连接

蓝牙配对主要在settings应用下面的com.android.settings.bluetooth目录下,主要是有广播侦听BluetoothPairingRequest.java,配对对话框BluetoothPairingDialog.java,BluetoothPairingDialogFragment.java, 配对控制类BluetoothPairingController.java.实...

hellolinshoujie的专栏 3985

安卓4.4蓝牙自动配对及管理应用设计

安卓4.4 KitKat版本,是谷歌在2013年推出的版本,标志着安卓系统迈向更为成熟和稳定的阶段。在这一版本中,谷歌不仅对系统界面进行了优化,还着重提升了应用性能和用户体验。蓝牙技术是一种无线技术标准,用于在短距离内交换数据,主要应用于移动电话、计算机、耳机等便携式设备之间的连接和通信。它的名称来源于公元10世纪统一丹麦和挪威的维京国王哈拉尔蓝牙。该技术的开发始于1994年,由瑞典的爱立信公司开始,并迅速成长为一种全球性的无线通信标准。

weixin_42284380的博客 797

Android工具类篇 蓝牙状态工具类 BlueToothUtils

/** * @author : Dumplings * @version : v1.0.0 * @ClassName : BlueToothUtils.java * @Function : * @Description : * @Idea : * {@link : } * @Encourage :And the more we try to understand one another, the more exceptional each of us will be. * 我们越是努力理

圈池 1339

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

本篇文章主要介绍了Android 蓝牙自动匹配PIN码跳过用户交互示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

tasker_如何通过Tasker Automation将Android设备用作行车记录仪

taskerHave you ever wanted to get more out of your Android convergence device? How about using it as a hassle free video recorder for your car trips? HTG explains how you can accomplish this with just...

cumai3211的博客 1606

three.js开发3D地图记录(二)

添加地图点击事件,点击区域,地图区域改变颜色并浮起来。

anwebDesigner的博客 1694

FreeRTOS实战:如何避免HAL_Delay在高优先级中断中的坑(附TIM6配置指南)

本文深入剖析了在STM32 FreeRTOS项目中,于高优先级中断内调用HAL_Delay函数导致系统假死的根本原因——SysTick时基被FreeRTOS占用且优先级最低。文章提供了治本方案:通过配置TIM6作为独立且最高优先级的HAL时基,实现与FreeRTOS系统心跳的解耦,并附上详细的CubeMX配置与代码移植指南,确保系统实时性与稳定性。

weixin_29230059的博客 64

Android蓝牙自动配对Demo,亲测好使!!!

蓝牙自动配对,即搜索到其它蓝牙设备之后直接进行配对,不需要弹出配对确认框或者密钥输入框。 经过最近一段时间得研究,针对网上给出的案例。总结了一个亲测好使的Demo。

冷血之心的博客 7万+

AI 自动生成商业计划书:AIGC 如何助力创业者?

在创业的早期阶段,商业计划书(Business Plan)是至关重要的。它不仅用于吸引投资者、明确发展路径,还能帮助团队对业务模式、市场定位和财务预测有清晰认知。然而,撰写一份高质量的商业计划书往往需要投入大量时间和精力。如今,AIGC(AI Generated Content,人工智能生成内容)技术正在改变这一现状。借助 AIGC,创业者可以更快速、高效地创建商业计划书,并通过 AI 进行优化和数据分析。

2401_82808034的博客 3780

Android 蓝牙连接,蓝牙配对,自动连接蓝牙

免费下载!Android蓝牙配对,开启关闭蓝牙,搜索附近蓝牙设备,代码如何使用介绍

As_thin的博客 1万+

LVGL的基础知识总结

另外,还有自定义字库的使用,具体可参考开发手册。

qq_28576837的博客 7384

UE5实现物体高亮描边效果(含UE相关源码浅析)

UE5实现物体高亮描边效果

专注GIS开发 7334

安卓系统蓝牙配对流程分析

安卓系统蓝牙配对流程分析 配对流程基本上始于首次连接一个蓝牙设备的过程中,本端的搜索流程结束获取到该设备的BluetoothDevice信息,就可以开启配对流程。 配对,顾名思义就是将两个设备通过相关技术进行绑定,达到能够互相识别彼此的目的。因此通过蓝牙技术进行的配对就是大家理解中的蓝牙配对。随着蓝牙技术在消费市场上越来越普及,生活中很容易就能遇到蓝牙配对这一使用蓝牙功能事必不可缺失的步骤。本期我们就简单聊聊安卓系统蓝牙配对的流程是如何运行的。 Application通过framework层Bluetoo

坏小子-无线通信技术 4040

手把手教你学PCIE(10.5)--PCIE故障排除方法的分步排查法介绍

通过以上分步排查法,你可以系统地诊断和解决 PCIe 设备的故障。每个步骤都有助于逐步缩小问题范围,最终找到并解决问题。

MHD0815的博客 1871

Android蓝牙自动配对授权连接的实现方法

如果有其他蓝牙设备申请对此设备进行连接,不需要谈出需要用户确认的对话框和pin code对话框,实现自动连接的一种实现方法; 修改设置蓝牙配对相关源码packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothPairingRequest.java 添加代码实现自动配对的过程: 添加变量 private static final int NOTIFICATION_ID = android.R.draw...

Fortuna的博客 3250

RK3568平台开发系列讲解(中断及异常篇)中断下半部:中断线程化

以前用 work 来线程化地处理中断,一个 worker 线程只能由一个 CPU 执行, 多个中断的 work 都由同一个 worker 线程来处理,在单 CPU 系统中也只能忍着 了。少数中断不能线程化,典型的例子是时钟中断,有些流氓进程不主动让出处理器,内核只能依靠周期性的时钟中断夺回处理器的控制权,时钟中断是调度器的脉搏。中断处理线程是优先级为50、调度策略是SCHED_FIFO的实时内核线程,名称是“irq/”后面跟着Linux中断号,线程处理函数是。,说明是线程化的中断,那么唤醒中断处理线程。

内核笔记 435

selenium绕过检测,规避检测

现在不少大网站有对selenium采取了监测机制。比如正常情况下我们用浏览器访问淘宝等网站的 window.navigator.webdriver的值为 undefined或者为false。而使用selenium访问则该值为true。那么如何解决这个问题呢?我们正常浏览器登录查看,window.navigator.webdriver的值为false我们通过selenium打开的网页,测试,可见window.navigator.webdriver的值为true。

景天科技苑 1万+

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

Android系统下蓝牙自动配对连接方法【专利摘要】本发明涉及一种Android系统下蓝牙自动配对连接方法,其包括如下步骤:步骤1、在Android设备端内存储上次进行蓝牙连接蓝牙外设的蓝牙地址,并存储已配对蓝牙外设的蓝牙地址以及对应的配对密钥;步骤2、在接收到蓝牙外设的连接请求时,Android设备端确定蓝牙外设的蓝牙地址,若与上次连接蓝牙外设的蓝牙地址对应时,将确定蓝牙外设的蓝牙地址与已配对蓝...

weixin_33138569的博客 3853

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Android 蓝牙自动配对

public class RegisterBlueTooth { Context context; public BluetoothAdapter btAdapt; public List lstDevices = new ArrayList(); public String TagetDeviceAddress; private Bluetooth

myrssq的博客 1736

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

上一篇: android httpClient 支持HTTPS的处理方式
下一篇: Android App 内存泄露之Handler
Allen-华
博客等级 码龄11年 10粉丝 33原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值