低功耗蓝牙(BLE)和传感器的使用(蓝牙低功耗模块)
nanshan 2024-11-14 16:38 22 浏览 0 评论
一、低功耗蓝牙的使用
Android中关于蓝牙的开发文档,可以参考Google提供的官方蓝牙文档:https://developer.android.google.cn/guide/topics/connectivity/bluetooth.html
在Android开发中,应用可通过官方提供的蓝牙API执行以下操作:
- 扫描其他蓝牙设备
- 查询本地蓝牙适配器的配对蓝牙设备
- 建立 RFCOMM 通道
- 通过服务发现连接到其他设备
- 与其他设备进行双向数据传输
- 管理多个连接
蓝牙
一个近距离无线通信技术,最早是由爱立信研发出来。蓝牙 Bluetooth 这个词是一个丹麦的国王的绰号,当时研发它的工程师正在看一个关于这个国王的书,就起了这个名字。蓝牙的技术特点是:
- 近距离通信:典型距离是 10 米以内;
- 传输效率:传输速度最高可达 24 Mbps
- 多连接:蓝牙技术支持多设备连接、安全性高
蓝牙从被发明到目前,经过了几个版本的变化:
- 1.0版本:99年发布
- 2.1版本:使用范围最广泛,经典蓝牙
- 3.0版本:高速蓝牙,最高传输速度达到24Mbps
- 4.0/4.1版本:新增低功耗蓝牙
- 5.0版本:物联网
低功耗蓝牙
低功耗蓝牙全称为Bluetooth Low Energy,简称为BLE,最大特点就是低功耗,另外低功耗蓝牙还具备成本低,连接速度快,安全性高的特点。当然,低功耗蓝牙也相应的会有一些不足,比如说:低功耗对应的是低传输效率,因此低功耗蓝牙主要用来传输少量数据,结合低功耗的特点,非常适合用在移动智能设备上。
低功耗蓝牙分为两种模式:单模和双模。
- 单模:只能执行低功耗协议栈,即只支持BLE。
- 双模:既支持传统蓝牙又支持BLE蓝牙。
注意:需要在Android 4.3及以上版本才能支持具备低功耗功能的蓝牙4.0。
BLE协议栈
首先来看一下使用蓝牙的基本流程:
先简单来了解一下低功耗蓝牙的协议框架,在BLE协议栈中,大致分为三个部分,从下到上依次为:控制器(Controller) 、主机(Host)、应用(Applications)。
- 控制器:协议栈的最底层,直接与硬件相关,由厂商直接实现。
- 主机:硬件层的抽象层,与具体的硬件和常见无关,可以理解为接口。
- 应用层:使用Host层提供的API,进而开发的应用。
协议层从下往上,依次包含如下协议:
- Attribute Protocol:简称为 ATT,属性协议,Host层的一个协议,是BLE通信的基础。ATT 把数据封装,向外暴露为“属性”,提供“属性”的为服务端,获取“属性”的为客户端。ATT 是专门为低功耗蓝牙设计的,结构非常简单,数据长度很短。每个属性都有一个唯一的UUID,属性以characteristics and services的形式传输。
- Generic Attribute Profile:简称为GATT,通用属性配置文件,建立在前面说的 ATT 的基础上,对 ATT 进行进一步的逻辑封装,定义数据的交互方式和含义。GATT 按照层级定义了三个概念:
- Service:服务,一个 Service 包含若干个 Characteristic。
- Characteristic:特征,一个 Characteristic 可以包含若干 Descriptor。
- Descriptor:描述,数据的读写操作。
- Generic Access Profile:简称为GAP,通用访问控制配置文件,用来控制设备连接和广播,GAP使你的设备被其他设备可见,并决定了你的设备是否可以或者怎样与合同设备进行交互。
Android BLE API
- Android SDK 中 BLE 相关的 API 都在 android.bluetooth.* 中。
- 5.0版本中:android.bluetooth.le*
权限
- 要在 APP 中使用蓝牙功能,需要在 Manifest 中申请蓝牙相关的权限。
- Android 6.0及以上版本:蓝牙 + 定位权限。为什么会有定位权限?BLE有定位的功能和能力。
BLE核心API
- BluetoothManager:蓝牙管理服务。在Android基本框架中可以发现蓝牙属于最底层的驱动模块中,可以公国context.getSystemService(Context.BLUETOOTH_SERVICE) 来进行获取。
- BluetoothAdapter:本地设备蓝牙适配器。BluetoothAdapter可以完成:启动设备发现,查询已绑定(配对)设备的列表,使用已知MAC地址实例化 BluetoothDevice,并创建一个 BluetoothServerSocket 以监听来自其他设备的连接请求,并启动扫描蓝牙LE设备等操作,该类属于核心中的核心。
- BluetoothAdapter.LeScanCallback:BLE扫描结果回调接口,在 Android 5.0以上 使用抽象类 ScanCallback。
- BluetoothLeScanner:蓝牙LE设备执行扫描相关操作类,使用该API要求Android 5.0(API21)以上。
- BluetoothDevice:远程蓝牙设备,BluetoothDevice允许创建与相应设备的连接或关于它的查询信息,例如名称,地址,类和绑定状态等。
- BluetoothProfile:配置文件代理。每个公共配置文件实现这个接口。它有几个直接子类,每个子类再不同场景中使用,如 BluetoothA2dp, BluetoothGatt, BluetoothGattServer, BluetoothHeadset, BluetoothHealth。在当前例子中使用到的是 BluetoothGatt。
- BluetoothGatt:提供蓝牙GATT功能,以实现与蓝牙智能或智能就绪设备的通信。使用该类做连接、断开、关闭等操作。
- BluetoothGattCallback:设备连接时的回调接口。
UUID
UUID 是全局唯一标识,是128bit的值,为了便于识别和阅读,一般标示成:8-4-4-12 的16进制格式。
Android 中提供了 UUID.randomUUID() 来生成一个随机的 UUID。
在低功耗蓝牙中,长度为128bit的UUID数据长度是受限的,因此蓝牙中又产生出来了16bit和32bit的UUID,本质上和128bit的UUID一样。
Android 中BLE的操作步骤
- ① 获取到BluetoothAdapter:代表设备自己的蓝牙适配器,整个系统只有一个蓝牙适配器,应用程序可以使用此对象与其交互。获取方法是通过 BluetoothManager 获取。
- ② 启用蓝牙设备:isEnable() 查看是否启用,通过 BluetoothAdapter.ACTION_REQUEST_ENABLE 来启动
- ③ 查找BLE设备:通过startLeScan(callBack); 方法来开启扫描;另外还可以使用BluetoothLeScanner来扫描。
与Android BLE设备通信
开发BLE应用,主要有两大类:
- 基于非连接的通信应用:使用的是BLE的广播机制,又称作是Beacon。共有两个角色:发送方负责发送广播,称之为Boradcaster,另外一方为监听方,监听广播信号,称之为Observer。
- 基于连接的通信应用:基于连接的通信是通过建立GATT连接,让后进行数据的收发。也有两个角色:连接发起方,称之为中心设备(Central),另外一方是被连接的设备,称之为外设Peripheral。
本篇文章中,我们来讨论面向连接的通信的情况。如果要与另外一个BLE设备进行通信,需要经过连接,确认状态,然后再通信的过程。首先是开启连接,然后会触发对应的连接回调,然后发现服务,触发发现服务回调,获取服务内部的特征值,对其读写命令(和 BLE 共同约束的规范),就是这么一个过程,比较简单。
- 连接到GATT服务器:如果要与BLE进行通信,第一步就是要连接到该设备的 GATT 服务。使用connectGatt方法链接,有三个参数,最后一个参数为连接的回调函数,表是处理链接的状态,所有交互均从回调中进行处理。
- 读 BLE 属性:一旦Android设备连接到GATT的服务器并且发现了BLE服务,则可以读取或者写入相关的属性,执行相关的操作了。
- 释放GATT:当操作完成后,要记得关闭设备bluetoothGatt.close()。
二、WIFI的使用
每个移动智能设备几乎都带有WIFI连接功能,在Android系统中,同样也提供了WIFI开发的相关的API。
WIFI API
Android系统提供的WIFI API,主要包含在两个包中:
- android.net.wifi包
- android.net.wifi.p2p包
和wifi相关的核心API主要有以下几个内容:
- WifiManager:提供管理WiFI连接的大部分API
- ScanResult:已经检测出的接入点(包括接入点的地址、名称、身份认证、频率、信号强度)
- WifiConfiguration:WiFi连接的网络配置(包括安全配置等)
- WifiInfo:WiFi无线连接的描述,主要包括接入点、网络连接状态、隐藏的接入点、IP地址、连接速度、MAC地址、网络ID、信号强度等等信息。
- WifiManager.WifiLock:通常情况下当用户在一段时间内没有任何操作的时候,WiFi网络会自动关闭。我们使用WifiLock来锁定WiFi网络,使其一直保持连接,直到这个锁被释放。多个应用程序可能有多个锁,当多有的应用程序的锁都被释放的时候,WiFi才被关闭。
WIFI 使用说明
- WifiManager:context.getSystemService(Context.WIFI_SERVICE);
- 打开WiFi:mWifiManager.setWifiEnabled(true); 关闭wifi为false
- 创建一个WifiLock:mWifiManager.createWifiLock("lock_name");
- 锁定WifiLock:mWifiLock.acquire();
- 释放WifiLock:mWifiLock.release();
- WiFi连接:
public void addNetworkAndConn(WifiConfiguration wcg) {
int netId = mWifiManager.addNetwork(wcg);
mWifiManager.enableNetwork(netId, true);
}
- 断开一个指定ID的WiFi:
public void disconnectWifi(int netId) {
mWifiManager.disableNetwork(netId);
mWifiManager.disconnect();
}
- 扫描可接入的WiFi:
public void startScan() {
mWifiManager.startScan();
// 得到扫描结果
List<ScanResult> wifiList = mWifiManager.getScanResults();
// 得到配置好的网络连接
List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks();
}
WIFI 权限
在进行wifi开发时,既要用到网络,也要用到硬件资源,因此需要申请一些必要的权限,而且涉及到的还比较的多,主要的权限如下:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES"></uses-permission>
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"></uses-permission>
WIFI直连
WIFI Direct 意为通过 WIFI 直接建立连接。允许无线网络中的设备无须通过无线路由器即可相互连接。这种标准支持 WIFI 的无线设备像蓝牙那样以点对点的形式互连,但是在传输速度与传输距离方面都比蓝牙有大幅提升。
WIFI Direct 提供 WifiP2pManager 类,其功能主要分为以下三部分:
- WifiP2pManager 类提供相关 API 用于发现可连接的点,并进行请求和建立连接。
- 每个 WifiP2pManager 的方法都要求传入对应的监听器,用于监听对该方法是否成功运行。
- 当检测到特定事件,如可连接的点减少或者发现了新的可连接的点,WIFI Direct 框架会通过 Intent 通知用户。
WifiP2pManager的核心API用法说明如下所示:
- initialize:为应用程序注册 WIFI 框架。该方法必须在任何其他 WIFI Direct 方法被调用前调用,常放在Application中调用。
- connect:与具有指定配置的 WIFI 设备建立点对点连接
- cancelConnect:断开连接
- requestConnectInfo:获取设备的连接信息
- createGroup:以当前设备为拥有者创建一个点对点组
- removeGroup:删除当前的点对点组
- requestGroupInfo:获取点对点组的信息
- discoverPeers:初始化发现对等点设备服务
- requestPeers:获取当前已发现的对等点设备列表
在WifiP2pManager使用时,同样支持使用各种监听回调接口:
- ActionListener:Wifi连接过程中的某个动作监听。主要包括:connect、cancelConnect、createGroup、removeGroup、discoverPeers等回调函数
- ChannelListener:initialize初始化的回调
- ConnectionInfoListener:请求连接的回调,回传连接信息
- GroupInfoListener:点对点组的监听信息
- PeerListListener:点对点设备的监听回调接口
三、传感器
Android 传感器属于虚拟设备,可提供来自以下各种物理传感器的数据:
- 加速度计
- 陀螺仪
- 磁力计、
- 气压计
- 湿度传感器
- 压力传感器
- 光传感器
- 近程传感器
- 心率传感器
以上的这些均可以归纳为传感器类别,在Android中,这些传感器有一个相同的定义文件,存在一个 sensors.h文件,其中定义了Android系统支持的每一种传感器。格式为:ENSOR_TYPE_传感器名称。
该图为Android系统中传感器的的架构和分层。可以看出,几乎和Android系统整体的架构一样。从上层到下层,从应用层到底层内核层。
传奇器核心API
Android传感器框架放在android.hardware包中,核心的API如下所示:
- SensorManager:用于创建传感器服务实例。该类提供了访问和罗列传感器的各种方法,用于注册和注销传感器事件监听器并获取方向信息。该类也提供了几个常量,用于报告传感器的精度、数据获取率和校正传感器。
- Sensor:用作创建某个特定传感器的实例。该类提供了用于确定传感器能力的各种方法。
- SensorEvent:创建传感器事件对象。传感器事件对象包含传感器事件的相关信息,包括原始的传感器数据、传感器类型、产生的事件、事件精度以及事件发生的时间戳等。
- SensorEventListener:是一个接口,包含两个回调方法。当传感器的值发生改变或者传感器的精度发生改变时,相关方法就会自动被调用。
传感器核心操作
无论如何变化,其实通过上面的描述和介绍,我们看到,传感器是底层系统提供的,数据也是相关的API返回获取的。因此,在涉及到传感器开发时,开发者的核心操作只有两个:
- 分析需求,明确使用哪个一个类别的传感器,明确要获取的传感器数据。
- 调用系统的API方法,监听传感器的的回调时间,获取数据。
因此,Android中的传感器部分的应用开发,重点不是在于传感器的使用,是开发者自己特定的应用,在获取到数据后,对数据的处理和挖掘,是重中之重。
Android传感器分类
Android中支持的传感器分为很多类别,主要有:
- TYPE_ACCELEROMETER:运动探测传感器,硬件传感器
- TYPE_AMBIENT_TEMPERATURE:环境温度传感器,硬件传感器
- TYPE_GRAVITY:运动探测,软件或者硬件传感器
- TYPE_GYROSCOPE:旋转,硬件传感器
- TYPE_LIGHT:屏幕亮度传感器,属于硬件传感器
- TYPE_LINEAR_ACCELERATION:加速度传感器,软件或者硬件都有
- TYPE_ORIENTATION:方向传感器,属于软件传感器
- TYPE_PRESSURE:空气压力传感器,属于硬件传感器
- TYPE_PROXIMITY:距离传感器,用于监测打电话时手机与耳朵的距离,属于硬件传感器
四、SystemService
经过本篇文档的介绍,结合之前的课程内容,我们可以总结出一个规律。在Android开发时,很多情况下我们都可以直接通过某个上下文,获取xxxManager,往往是某个管理者。这些管理者是Android系统提供的系统服务,我们可以统称为SystemService,现在我们了解一下SystemService有关的内容,并做个总结。
SystemService
SystemService是系统提供给开发者的调用系统层的控制接口,应用层的开发者只需要了解这些接口的使用方式,就可以非常方便的进行系统控制,完成自己想要的功能操作,获取系统的相关信息,而不需要了解接口的具体内部实现方式。这些SystemManager是在framework层或者更底层进行实现的。
相反的对于Framework层的开发者而言,需要了解XXXManager服务的实现细节和方式,并维护Manager接口,扩展或者实现新接口等。
我们可以列举一下我们在学习过程中遇到的Manager,比如:
- WindowManager:窗口操作的窗口管理服务
- NotifacationManager:通知管理
- AudioManager:Android系统的音频管理者
- LocationManager:GPS定位服务管理
- StatusBarManager:状态栏的管理者
除此以外,还有很多很多,以上这些管理者,其实背后都是有一个系统服务SystemService。
getSystemService
getSystemService是Android很重要的一个API,它是Activity的一个方法,根据传入的NAME来取得对应的Object,然后转换成相应的服务对象。
相关推荐
- 使用nginx配置域名及禁止直接通过IP访问网站
-
前段时间刚搭建好这个网站,一直没有关注一个问题,那就是IP地址也可以访问我的网站,今天就专门研究了一下nginx配置问题,争取把这个问题研究透彻。1.nginx配置域名及禁止直接通过IP访问先来看n...
- 如何在 Linux 中使用 PID 号查找进程名称?
-
在Linux的复杂世界中,进程是系统运行的核心,每个进程都由一个唯一的「进程ID」(PID)标识。无论是系统管理员在排查失控进程,还是开发者在调试应用程序,知道如何将PID映射到对应的进程名称都是一项...
- Linux服务器硬件信息查询与日常运维命令总结
-
1.服务器硬件信息查询1.1CPU信息查询命令功能描述示例lscpu显示CPU架构、核心数、线程数等lscpucat/proc/cpuinfo详细CPU信息(型号、缓存、频率)cat/proc/c...
- Ubuntu 操作系统常用命令详解(ubuntu常用的50个命令)
-
UbuntuLinux是一款流行的开源操作系统,广泛应用于服务器、开发、学习等场景。命令行是Ubuntu的灵魂,也是高效、稳定管理系统的利器。本文按照各大常用领域,详细总结Ubuntu必学...
- 从 0 到 1:打造基于 Linux 的私有 API 网关平台
-
在当今微服务架构盛行的时代,API网关作为服务入口和安全屏障,其重要性日益凸显。你是否想过,不依赖商业方案,完全基于开源组件,在Linux上构建一个属于自己的私有API网关平台?今天就带你...
- Nginx搭建简单直播服务器(nginx 直播服务器搭建)
-
前言使用Nginx+Nginx-rtmp-module在Ubuntu中搭建简单的rtmp推流直播服务器。服务器环境Ubuntu16.04相关概念RTMP:RTMP协议是RealTi...
- Linux连不上网?远程卡?这篇网络管理指南你不能错过!
-
大家好!今天咱们聊个所有Linux用户都躲不开的“老大难”——网络管理。我猜你肯定遇到过这些崩溃时刻:新装的Linux系统连不上Wi-Fi,急得直拍桌子;远程服务器SSH连不上,提示“Connecti...
- 7天从0到上线!手把手教你用Python Flask打造爆款Web服务
-
一、为什么全网开发者都在疯学Flask?在当今Web开发的战场,Flask就像一把“瑞士军刀”——轻量级架构让新手3天速成,灵活扩展能力又能支撑百万级用户项目!对比Django的“重型装甲”,Flas...
- nginx配置文件详解(nginx反向代理配置详解)
-
Nginx是一个强大的免费开源的HTTP服务器和反向代理服务器。在Web开发项目中,nginx常用作为静态文件服务器处理静态文件,并负责将动态请求转发至应用服务器(如Django,Flask,et...
- 30 分钟搞定 Docker 安装与 Nginx 部署,轻松搭建高效 Web 服务
-
在云计算时代,利用容器技术快速部署应用已成为开发者必备技能。本文将手把手教你在阿里云轻量应用服务器上,通过Docker高效部署Nginx并发布静态网站,全程可视化操作,新手也能轻松上手!一、准...
- Nginx 配置实战:从摸鱼到部署,手把手教你搞定生产级配置
-
各位摸鱼搭子们!今天咱不聊代码里的NullPointerException,改聊点「摸鱼必备生存技能」——Nginx配置!先灵魂拷问一下:写了一堆接口却不会部署?服务器被恶意请求打崩过?静态资源加载...
- 如何使用 Daphne + Nginx + supervisor部署 Django
-
前言:从Django3.0开始支持ASGI应用程序运行,使Django完全具有异步功能。Django目前已经更新到5.0,对异步支持也越来越好。但是,异步功能将仅对在ASGI下运行的应用程序可用...
- Docker命令最全详解(39个最常用命令)
-
Docker是云原生的核心,也是大厂的必备技能,下面我就全面来详解Docker核心命令@mikechen本文作者:陈睿|mikechen文章来源:mikechen.cc一、Docker基本命令doc...
- ubuntu中如何查看是否已经安装了nginx
-
在Ubuntu系统中,可以通过以下几种方法检查是否已安装Nginx:方法1:使用dpkg命令(适用于Debian/Ubuntu)bashdpkg-l|grepnginx输出...
- OVN 概念与实践(德育概念的泛化在理论和实践中有什么弊端?)
-
今天我们来讲解OVN的概念和基础实践,要理解本篇博客的内容,需要前置学习:Linux网络设备-Bridge&VethPairLinux网络设备-Bridge详解OVS+Fa...
你 发表评论:
欢迎- 一周热门
-
-
UOS服务器操作系统防火墙设置(uos20关闭防火墙)
-
极空间如何无损移机,新Z4 Pro又有哪些升级?极空间Z4 Pro深度体验
-
手机如何设置与显示准确时间的详细指南
-
NAS:DS video/DS file/DS photo等群晖移动端APP远程访问的教程
-
如何在安装前及安装后修改黑群晖的Mac地址和Sn系列号
-
如何修复用户配置文件服务在 WINDOWS 上登录失败的问题
-
一加手机与电脑互传文件的便捷方法FileDash
-
日本海上自卫队的军衔制度(日本海上自卫队的军衔制度是什么)
-
10个免费文件中转服务站,分享文件简单方便,你知道几个?
-
爱折腾的特斯拉车主必看!手把手教你TESLAMATE的备份和恢复
-
- 最近发表
-
- 使用nginx配置域名及禁止直接通过IP访问网站
- 如何在 Linux 中使用 PID 号查找进程名称?
- Linux服务器硬件信息查询与日常运维命令总结
- Ubuntu 操作系统常用命令详解(ubuntu常用的50个命令)
- 从 0 到 1:打造基于 Linux 的私有 API 网关平台
- Nginx搭建简单直播服务器(nginx 直播服务器搭建)
- Linux连不上网?远程卡?这篇网络管理指南你不能错过!
- 7天从0到上线!手把手教你用Python Flask打造爆款Web服务
- nginx配置文件详解(nginx反向代理配置详解)
- 30 分钟搞定 Docker 安装与 Nginx 部署,轻松搭建高效 Web 服务
- 标签列表
-
- linux 查询端口号 (58)
- docker映射容器目录到宿主机 (66)
- 杀端口 (60)
- yum更换阿里源 (62)
- internet explorer 增强的安全配置已启用 (65)
- linux自动挂载 (56)
- 禁用selinux (55)
- sysv-rc-conf (69)
- ubuntu防火墙状态查看 (64)
- windows server 2022激活密钥 (56)
- 无法与服务器建立安全连接是什么意思 (74)
- 443/80端口被占用怎么解决 (56)
- ping无法访问目标主机怎么解决 (58)
- fdatasync (59)
- 405 not allowed (56)
- 免备案虚拟主机zxhost (55)
- linux根据pid查看进程 (60)
- dhcp工具 (62)
- mysql 1045 (57)
- 宝塔远程工具 (56)
- ssh服务器拒绝了密码 请再试一次 (56)
- ubuntu卸载docker (56)
- linux查看nginx状态 (63)
- tomcat 乱码 (76)
- 2008r2激活序列号 (65)