Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Android开发笔记(一百六十二)蓝牙设备的连接与配对

Android开发笔记(一百六十二)蓝牙设备的连接与配对

作者头像
aqi00
发布于 2019-01-18 07:51:24
发布于 2019-01-18 07:51:24
3.4K00
代码可运行
举报
文章被收录于专栏:老欧说安卓老欧说安卓
运行总次数:0
代码可运行

蓝牙是一种短距离无线通信技术,它由爱立信公司于1994年创制,原本想替代连接电信设备的数据线,但是后来发现它也能用于移动设备之间的数据传输,所以蓝牙技术在手机上获得了长足发展。 因为手机内部的通讯芯片一般同时集成了2G/3G/4G、WIFI和蓝牙,所以蓝牙功能已经是智能手机的标配了。若想进行蓝牙方面的开发,需要在App工程的AndroidManifest.xml中补充下面的权限配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    <!-- 蓝牙 -->
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <!-- 如果Android6.0 蓝牙搜索不到设备,需要补充下面两个权限 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

与NFC类似,Android也提供了蓝牙模块的管理工具,名叫BluetoothAdapter,虽然通常把BluetoothAdapter翻译为“蓝牙适配器”,其实它干的是管理器的活。下面是BluetoothAdapter类常用的方法说明: getDefaultAdapter : 获取默认的蓝牙适配器。该方法为静态方法。 getState : 获取蓝牙的开关状态。STATE_ON表示已开启,STATE_TURNING_ON表示正在开启,STATE_OFF表示已关闭,STATE_TURNING_OFF表示正在关闭。 enable : 启用蓝牙功能。 disable : 禁用蓝牙功能。 isEnabled : 判断蓝牙功能是否启用。返回true表示已启用,返回false表示未启用。 getBondedDevices : 获取已配对的设备集合。 getRemoteDevice : 根据设备地址获取远程的设备对象。 startDiscovery : 开始搜索周围的蓝牙设备。 cancelDiscovery : 取消搜索周围的蓝牙设备。 isDiscovering : 判断是否正在搜索周围的蓝牙设备。 接下来通过一个检测蓝牙设备并配对的例子,介绍如何在App开发中运用蓝牙技术。不要小看这个例子,简简单单的功能可得分成四个步骤:初始化、启用蓝牙、搜索蓝牙设备、与指定设备配对,下面分别进行详细说明: 一、初始化蓝牙适配器 如果仅仅是普通的蓝牙连接,则调用getDefaultAdapter获取蓝牙适配器就行了。初始化蓝牙适配器的代码示例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private BluetoothAdapter mBluetooth;
    private void initBluetooth() {
        mBluetooth = BluetoothAdapter.getDefaultAdapter();
        if (mBluetooth == null) {
            Toast.makeText(this, "本机未找到蓝牙功能", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

二、启用蓝牙功能 虽然BluetoothAdapter提供了enable方法用于启用蓝牙功能,但是该方法并不允许外部发现本设备,所以等于没用。实际开发中要弹窗提示用户,是否允许其他设备检测到自身,弹窗代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    // 弹出是否允许扫描蓝牙设备的选择对话框
    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    startActivityForResult(intent, mOpenCode);

蓝牙权限的选择对话框如下图所示:

由于选择弹窗上面可选择“允许”还是“拒绝”,因此代码中要重写onActivityResult函数,在该函数中判断蓝牙权限的选择结果。下面是判断权限选择的例子代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private int mOpenCode = 1;
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        if (requestCode == mOpenCode) {
            mHandler.postDelayed(mRefresh, 50); // 刷新蓝牙设备列表
            if (resultCode == RESULT_OK) {
                Toast.makeText(this, "允许本地蓝牙被附近的其它蓝牙设备发现", Toast.LENGTH_SHORT).show();
            } else if (resultCode == RESULT_CANCELED) {
                Toast.makeText(this, "不允许蓝牙被附近的其它蓝牙设备发现", Toast.LENGTH_SHORT).show();
            }
        }
    }

三、搜索周围的蓝牙设备 蓝牙功能打开之后,就能调用startDiscovery方法去搜索周围的蓝牙设备了。不过因为搜索动作是个异步的过程,startDiscovery方法并不直接返回搜索发现的设备结果,而是通过广播BluetoothDevice.ACTION_FOUND返回新发现的蓝牙设备。所以页面代码需要注册一个蓝牙搜索结果的广播接收器,在接收器中解析蓝牙设备信息,再把新设备添加到蓝牙设备列表。 下面是蓝牙搜索接收器的注册、注销,以及内部逻辑处理的代码例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private void beginDiscovery() {
        // 如果当前不是正在搜索,则开始新的搜索任务
        if (!mBluetooth.isDiscovering()) {
            mBluetooth.startDiscovery();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        //需要过滤多个动作,则调用IntentFilter对象的addAction添加新动作
        IntentFilter discoveryFilter = new IntentFilter();
        discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);
        //注册搜索结果的接收器
        registerReceiver(discoveryReceiver, discoveryFilter);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // 注销广播接收器
        unregisterReceiver(discoveryReceiver);
    }

    // 蓝牙设备的搜索结果通过广播返回
    private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(TAG, "onReceive action=" + action);
            // 获得已经搜索到的蓝牙设备
            if (action.equals(BluetoothDevice.ACTION_FOUND)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                refreshDevice(device); // 将发现的蓝牙设备加入到设备列表
            }
        }
    };

搜索到的蓝牙设备可能会有多个,每发现一个新设备都会收到一次发现广播,这样设备列表是动态刷新的。搜索完成的蓝牙设备列表界面如下图所示,其中左图为A手机的设备列表,右图为B手机的设备列表:

四、与指定的蓝牙设备配对 注意到新发现的设备状态是“未绑定”,这意味着当前手机并不能跟对方设备进行数据交互。只有新设备是“已绑定”状态,才能与当前手机传输数据。蓝牙设备的“未绑定”与“已绑定”,区别在于这两部设备之间是否成功配对了,而配对操作由BluetoothDevice类管理。下面是BluetoothDevice类的常用方法说明: getName : 获取设备的名称。 getAddress : 获取设备的MAC地址。 getBondState : 获取设备的绑定状态。BOND_NONE表示未绑定,BOND_BONDING表示正在绑定,BOND_BONDED表示已绑定。 createBond : 建立该设备的配对信息。该方法为隐藏方法,需要通过反射调用。 removeBond : 移除该设备的配对信息。该方法为隐藏方法,需要通过反射调用。 从上面的方法说明可以看出,搜索获得新设备后,即可调用设备对象的createBond方法建立配对。但配对成功与否的结果同样不是立即返回的,因为系统会弹出配对确认框供用户选择,就像下面的两个界面截图那样,左图是A手机上的配对弹窗,右图是B手机上的配对弹窗。

只有用户在两部手机都选择了“配对”按钮,才算是双方正式搭配好了。由于配对请求需要在界面上手工确认,因此配对结果只能通过异步机制返回,此处的结果返回仍然采取广播形式,即系统会发出广播BluetoothDevice.ACTION_BOND_STATE_CHANGED通知App。故而前面第三步的广播接收器得增加过滤绑定状态的变更动作,接收器内部也要补充更新蓝牙设备的绑定状态了。修改后的广播接收器相关代码片段如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Override
    protected void onStart() {
        super.onStart();
        //需要过滤多个动作,则调用IntentFilter对象的addAction添加新动作
        IntentFilter discoveryFilter = new IntentFilter();
        discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);
        // 增加绑定状态的变更动作
        discoveryFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        //注册搜索结果的接收器
        registerReceiver(discoveryReceiver, discoveryFilter);
    }


    // 蓝牙设备的搜索结果通过广播返回
    private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(TAG, "onReceive action=" + action);
            // 获得已经搜索到的蓝牙设备
            if (action.equals(BluetoothDevice.ACTION_FOUND)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                refreshDevice(device); // 将发现的蓝牙设备加入到设备列表
            } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // 更新蓝牙设备的绑定状态
                if (device.getBondState() == BluetoothDevice.BOND_BONDING) {
                    tv_discovery.setText("正在配对" + device.getName());
                } else if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                    tv_discovery.setText("完成配对" + device.getName());
                } else if (device.getBondState() == BluetoothDevice.BOND_NONE) {
                    tv_discovery.setText("取消配对" + device.getName());
                }
            }
        }
    };

两部手机配对完毕,分别刷新自己的设备列表页面,将对方设备的绑定状态改为“已绑定”,然后它俩就可以眉目传情,传递小纸条什么的了。下面是更新状态后的设备列表界面,其中左图为A手机的设备列表,右图为B手机的设备列表:

点此查看Android开发笔记的完整目录

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年02月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
蓝牙API介绍及基本功能实现
通过监听BluetoothAdapter.ACTION_STATE_CHANGED监听蓝牙状态的改变
fanfan
2022/05/07
1.5K0
带你解锁蓝牙skill(三)
蓝牙这块儿算是系统中的一个大块儿,刚开始分析确实很容易没有头绪,所以在进入庞大的源码之前先确定一个分析顺序,也好避免越学越乱。 对于源码的分析不外乎whw(what—how—why) 对于蓝牙各协议的功能以及如何演示都已经分析完了,具体可以参考 带你解锁蓝牙skill(一)以及带你解锁蓝牙skill(二)。 本文以Android7.0为例进行源码分析。开始分析源码之前,先来看看蓝牙相关的都有什么东西 4,如何开始 在对一个新事物进行研究之前,我们已经了解了他是什么,那么接下来就是庖丁解牛了
fanfan
2018/01/24
1.6K0
Android蓝牙详析 | 蓝牙的适配、权限、开启、搜索发现等处理
本系列笔记概述 蓝牙传输优势:功耗低,传输距离还可以; 蓝牙聊天室案例 Android中蓝牙设备的使用 蓝牙权限(本文的讲解内容之一) 蓝牙功能开启(本文的讲解内容之一) 搜索蓝牙设备(本文的讲解内容之一) 与外设搭建RFCOMM通道(射频通道) 蓝牙设备双向数据传输 蓝牙聊天室案例框架 蓝牙权限 执行蓝牙通信需要权限BLUETOOTH, 例如:请求连接、接收连接和传输数据等; 如果需要启动设备 或 操作蓝牙设置,则需声明BLUETOOTH_ADMIN权限 <uses-permiss
凌川江雪
2019/05/17
6.6K0
Android蓝牙开发教程(一)——搜索蓝牙设备[通俗易懂]
i.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0); 最后的参数设置为0,可以让蓝牙设备一直处于可发现状态。当我们需要设置具体可被发现的时间时,最多只能设置300秒。 i.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
全栈程序员站长
2022/09/13
6.4K1
Android蓝牙开发教程(一)——搜索蓝牙设备[通俗易懂]
android开发之蓝牙主动配对连接手机
上一篇介绍了手机配对连接的三种方式,这篇以完整的一个代码实例介绍如何搜索周围的蓝牙设备,以及主动配对,连接。
全栈程序员站长
2022/03/11
7540
Android 蓝牙开发,蓝牙连打印机。
1.添加jar包,在app目录下新建libs文件夹,拷入jar文件并Add As Library
yechaoa
2022/06/10
2.8K0
Android 蓝牙开发,蓝牙连打印机。
Android 蓝牙开发(扫描设备、绑定、解绑)Kotlin版
之前写了一个蓝牙的小Demo,看的人还是有一些的,也有人私信我说,在学Kotlin,能不能出一版Kotlin的博客讲述这个蓝牙开发,这个想法还是不错的,不过就怕写了没有人看,因为在国内Kotlin是受众群体确实比较少,当然了也是有大的方向在往这边推动的,但是小公司依然不会去用Kotlin,如果你看不惯我这个说法也不要告诉我。我只是把这个博客当成是笔记而已,如果能在写作的时候帮助到别人也是乐意的,不能就自勉吧。
晨曦_LLW
2020/11/18
5K0
Android蓝牙开发(一)之打开蓝牙和设备搜索
https://blog.csdn.net/huangliniqng/article/details/82185635
黄林晴
2019/01/10
2.4K0
android开发之手机与单片机蓝牙模块通信
之前两篇都是在说与手机的连接,连接方法,和主动配对连接,都是手机与手机的操作,做起来还是没问题的,但是最终的目的是与单片机的蓝牙模块的通信。
全栈程序员站长
2022/03/11
8160
[Android实例] android 蓝牙开发浅析
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
易寒
2021/12/21
5450
Android 蓝牙开发(一)蓝牙通信「建议收藏」
<uses-permissionandroid:name=”android.permission.BLUETOOTH” />
全栈程序员站长
2022/09/14
4.2K0
Android 蓝牙开发(扫描设备、绑定、解绑)
公司最近给我丢了一个蓝牙开发的项目,不了解怎么办呢,那当然是从最基础的开始了,所以这里相当于做笔记了。
晨曦_LLW
2020/09/25
4.9K0
android 十八 蓝牙及Wi-Fi
蓝牙是一种重要的短距离无线通信技术,它被广泛应用于各种设备,比如计算机、手机、汽车等,支持设备之间的近距离通信,从而是数据传输更加快捷有效。Wi-Fi是一种高速的无线通信协议,它具有传输速度高,传输距离长的特点。通过WiFi,手机、PDA、电脑等移动设备可以以无线方式连接网络。本节中我们主要来学习Android开发中如何调用系统中蓝牙以及wifi的功能。
用户9184480
2024/12/17
1140
android 十八 蓝牙及Wi-Fi
一个给蓝牙模块升级的Android应用小工具
本文为呱牛笔记原创文章,转载无需和我联系,但请注明来自呱牛笔记 ,it3q.com
呱牛笔记
2023/11/28
4090
一个给蓝牙模块升级的Android应用小工具
浅谈Bluetooth蓝牙开发
前言:项目用到蓝牙开发,具体蓝牙获取硬件传感器中的数据。 因为没有蓝牙开发的相关经验,决定先了解一些蓝牙开发的知识,再去看之前同事写的蓝牙相关代码。 --------------------------------------------------------------------------------------------------- 一、蓝牙开发相关类 1、BluetoothAdapter  显而易见,蓝牙适配器。  通过这个类我们进行以下操作: 1、开关蓝牙设备 2、扫描蓝牙设备 3、设置/
听着music睡
2018/05/18
1.5K0
【Android 应用开发】Android之Bluetooth编程
android开发中使用AndroidManiFest.xml静态注册的BroadCastReceiver没有作用是什么原因?
韩曙亮
2023/03/27
4670
相关推荐
蓝牙API介绍及基本功能实现
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验