Android BLE 蓝牙通信库,2024年最新应届生面试销售岗位的面试问题技巧_android蓝牙通信-程序员宅基地

技术标签: 2024年程序员学习  面试  android  职场和发展  

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
img

正文

}

@Override

public void onSearchCanceled() {

}

});

如果扫描不出来,可将 targetSdk 调到低于 6.0.

可以随时停止扫描:

mClient.stopSearch();

蓝牙开关


打开关闭蓝牙:

mClient.openBluetooth();

mClient.closeBluetooth();

判断蓝牙是否打开:

mClient.isBluetoothOpened();

蓝牙打开或关闭需要一段时间,可以注册回调监听状态,回调的参数如果是 true 表示蓝牙已打开,false 表示蓝牙关闭

mClient.registerBluetoothStateListener(mBluetoothStateListener);

private final BluetoothStateListener mBluetoothStateListener = new BluetoothStateListener() {

@Override

public void onBluetoothStateChanged(boolean openOrClosed) {

}

};

mClient.unregisterBluetoothStateListener(mBluetoothStateListener);

设备配对


监听设备配对状态变化

private final BluetoothBondListener mBluetoothBondListener = new BluetoothBondListener() {

@Override

public void onBondStateChanged(String mac, int bondState) {

// bondState = Constants.BOND_NONE, BOND_BONDING, BOND_BONDED

}

};

mClient.registerBluetoothBondListener(mBluetoothBondListener);

mClient.unregisterBluetoothBondListener(mBluetoothBondListener);

Beacon 解析


可以在广播中携带设备的自定义数据,用于设备识别,数据广播,事件通知等,这样手机端无需连接设备就可以获取设备推送的数据。

扫描到的 beacon 数据为 byte[],在 SearchResult 的 scanRecord 中,按如下形式生成 Beacon 对象,

Beacon beacon = new Beacon(device.scanRecord);

Beacon 数据结构如下:

public class Beacon {

public byte[] mBytes;

public List mItems;

}

BeaconItem 是按 type 来区分的,

public class BeaconItem {

/**

  • 广播中声明的长度

*/

public int len;

/**

  • 广播中声明的 type

*/

public int type;

/**

  • 广播中的数据部分

*/

public byte[] bytes;

}

然后根据自定义的协议,解析对应的 BeaconItem 中的 bytes,首先创建一个 BeaconParser,传入对应的 BeaconItem,然后根据协议不断读取数据, 如果协议中某个字段占 1 个字节,则调用 readByte,若占用两个字节则调用 readShort,如果要取某个字节的某个 bit 则调用 getBit。注意 parser 每读一次数据,指针就会相应向后移动,可以调用 setPosition 设置当前指针的位置。

BeaconItem beaconItem; // 设置成 beacon 中对应的 item

BeaconParser beaconParser = new BeaconParser(beaconItem);

int firstByte = beaconParser.readByte(); // 读取第 1 个字节

int secondByte = beaconParser.readByte(); // 读取第 2 个字节

int productId = beaconParser.readShort(); // 读取第 3,4 个字节

boolean bit1 = beaconParser.getBit(firstByte, 0); // 获取第 1 字节的第 1bit

boolean bit2 = beaconParser.getBit(firstByte, 1); // 获取第 1 字节的第 2bit

beaconParser.setPosition(0); // 将读取起点设置到第 1 字节处

BLE 设备通信


● 连接

连接过程包括了普通的连接(connectGatt)和发现服务(discoverServices),这里收到回调时表明服务发现已完成。回调参数 BleGattProfile 包括了所有的 service 和 characteristic 的 uuid。返回的 code 表示操作状态,包括成功,失败或超时等,所有常量都在 Constants 类中。

mClient.connect(MAC, new BleConnectResponse() {

@Override

public void onResponse(int code, BleGattProfile profile) {

if (code == REQUEST_SUCCESS) {

}

}

});

可以配置连接参数如下,

BleConnectOptions options = new BleConnectOptions.Builder()

.setConnectRetry(3) // 连接如果失败重试 3 次

.setConnectTimeout(30000) // 连接超时 30s

.setServiceDiscoverRetry(3) // 发现服务如果失败重试 3 次

.setServiceDiscoverTimeout(20000) // 发现服务超时 20s

.build();

mClient.connect(MAC, options, new BleConnectResponse() {

@Override

public void onResponse(int code, BleGattProfile data) {

}

});

● 连接状态

如果要监听蓝牙连接状态可以注册回调,只有两个状态:连接和断开。

mClient.registerConnectStatusListener(MAC, mBleConnectStatusListener);

private final BleConnectStatusListener mBleConnectStatusListener = new BleConnectStatusListener() {

@Override

public void onConnectStatusChanged(String mac, int status) {

if (status == STATUS_CONNECTED) {

} else if (status == STATUS_DISCONNECTED) {

}

}

};

mClient.unregisterConnectStatusListener(MAC, mBleConnectStatusListener);

也可以主动获取连接状态:

int status = mClient.getConnectStatus(MAC);

// Constants.STATUS_UNKNOWN

// Constants.STATUS_DEVICE_CONNECTED

// Constants.STATUS_DEVICE_CONNECTING

// Constants.STATUS_DEVICE_DISCONNECTING

// Constants.STATUS_DEVICE_DISCONNECTED

● 断开连接

mClient.disconnect(MAC);

● 读 Characteristic

mClient.read(MAC, serviceUUID, characterUUID, new BleReadResponse() {

@Override

public void onResponse(int code, byte[] data) {

if (code == REQUEST_SUCCESS) {

}

}

});

● 写 Characteristic

要注意这里写的 byte[]不能超过 20 字节,如果超过了需要自己分成几次写。建议的办法是第一个 byte 放剩余要写的字节的长度。

mClient.write(MAC, serviceUUID, characterUUID, bytes, new BleWriteResponse() {

@Override

public void onResponse(int code) {

if (code == REQUEST_SUCCESS) {

}

}

});

这个写是带了 WRITE_TYPE_NO_RESPONSE 标志的,实践中发现比普通的 write 快 2~3 倍,建议用于固件升级。

mClient.writeNoRsp(MAC, serviceUUID, characterUUID, bytes, new BleWriteResponse() {

@Override

public void onResponse(int code) {

if (code == REQUEST_SUCCESS) {

}

}

});

● 读 Descriptor

mClient.readDescriptor(MAC, serviceUUID, characterUUID, descriptorUUID, new BleReadResponse() {

@Override

public void onResponse(int code, byte[] data) {

}

});

● 写 Descriptor

mClient.writeDescriptor(MAC, serviceUUID, characterUUID, descriptorUUID, bytes, new BleWriteResponse() {

@Override

public void onResponse(int code) {

}

});

● 打开 Notify

这里有两个回调,onNotify 是接收通知的。

mClient.notify(MAC, serviceUUID, characterUUID, new BleNotifyResponse() {

@Override

public void onNotify(UUID service, UUID character, byte[] value) {

}

@Override

public void onResponse(int code) {

if (code == REQUEST_SUCCESS) {

学习分享,共勉

Android高级架构师进阶之路

题外话,我在阿里工作多年,深知技术改革和创新的方向,Android开发以其美观、快速、高效、开放等优势迅速俘获人心,但很多Android兴趣爱好者所需的进阶学习资料确实不太系统,完整。今天我把我搜集和整理的这份学习资料分享给有需要的人

  • Android进阶知识体系学习脑图

  • Android进阶高级工程师学习全套手册

  • 对标Android阿里P7,年薪50w+学习视频

  • 大厂内部Android高频面试题,以及面试经历

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

迅速俘获人心,但很多Android兴趣爱好者所需的进阶学习资料确实不太系统,完整。今天我把我搜集和整理的这份学习资料分享给有需要的人

  • Android进阶知识体系学习脑图

[外链图片转存中…(img-HEBxmDfB-1713642554709)]

  • Android进阶高级工程师学习全套手册

[外链图片转存中…(img-zoKmpgYC-1713642554709)]

  • 对标Android阿里P7,年薪50w+学习视频

[外链图片转存中…(img-YnFrAEhD-1713642554710)]

  • 大厂内部Android高频面试题,以及面试经历

[外链图片转存中…(img-rml6PIdN-1713642554710)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-Hac2iWIS-1713642554710)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/2401_84102759/article/details/138019120

智能推荐

go上传文件-程序员宅基地

文章浏览阅读102次。【代码】go上传文件。

【转】目前常用AD/DA芯片简介_分辨率0.5的ad芯片-程序员宅基地

文章浏览阅读2.9k次。_分辨率0.5的ad芯片

一个简单的dw网页制作作业,学生个人html静态网页制作成品代码——怪盗基德动漫主题网页成品(15页)_dw简单网页制作成品-程序员宅基地

文章浏览阅读6.9k次,点赞6次,收藏57次。精彩专栏推荐 【作者主页——获取更多优质源码】 【web前端期末大作业——毕设项目精品实战案例(1000套)】1 网页简介:此作品为学生个人主页网页设计题材,HTML+CSS 布局制作,web前端期末大作业,大学生网页设计作业源码,这是一个不错的网页制作,画面精明,代码为简单学生水平, 非常适合初学者学习使用。2.网页编辑:网页作品代码简单,可使用任意HTML编辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Web..._dw简单网页制作成品

Android TBS X5内核 64位手机无法加载x5(libmttwebview.so is 32-bit instead of 64-bit)_libmtttrace.so-程序员宅基地

文章浏览阅读3k次。前言这个问题之前出现过但是稀里糊涂的解决了 没有记录详细的解决方案今天又碰到了 自己研究了一天刚刚找到解决方案错误提示dlopen failed: "/system/app/googlewebview85/lib/arm/libwebviewchromium.so“ is 32-bit instead of 64在使用tbs x5内核时 一直崩溃说没有64位的.so包腾讯官方TBS的文档也有这方面的知识点 但是没有解决方案需要靠自己摸索 你说气人不?新版本SDK已支持64位,请更新至官网_libmtttrace.so

java玫瑰花代码_java程序员不一样浪漫,表白玫瑰花送给你的那个她-程序员宅基地

文章浏览阅读3k次。原标题:java程序员不一样浪漫,表白玫瑰花送给你的那个她这篇文章主要讲解了Java版给爱人表白的玫瑰花程序代码,具有很好的参考价值,希望对大家有所帮助,一起跟随小编过来看看吧 小编推荐一个学Java的学习裙【二零二,二五零,一九四】,无论你是大牛还是小白,是想转行还是想入行都可以来了解一起进步一起学习!裙内有很多干货和技术分享!1 书写表白语句的frame(渐入功能)?1234567891011..._java玫瑰花代码

Hibernate(映射继承关系、 Hibernate 检索策略、Hibernate 检索方式HQL (迫切)左外连接HQL (迫切)内连接QBC 检索和本地 SQL 检索二级缓存,管理session_hql 非空约束-程序员宅基地

文章浏览阅读203次。上一篇映射继承关系Hibernate支持三种继承映射策略:使用 subclass 进行映射:将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系数据模型中考虑域模型中的继承关系和多态。使用 joined-subclass 进行映射: 对于继承关系中的子类使用同一个表,这就需要在数据库表中增加额外的区分子类类型的字段。使用 union-subclass 进行映射:域模型中的每个类映射到一个表,通过关系数据模型中的外键来描述表之间的继承关系。这也就相当于按照域模型的结构来建立数据库中的_hql 非空约束

随便推点

python学习导航线_python点线导航-程序员宅基地

文章浏览阅读122次。文章目录python学习导航线一、seleniumpython-selenium二、python基础知识python的聊天室python学习导航线一、seleniumpython-selenium二、python基础知识python的聊天室_python点线导航

静态成员-静态成员变量-程序员宅基地

文章浏览阅读3.4k次,点赞4次,收藏22次。静态成员静态成员都是用static修饰,它的特点是不论创建多少个对象,程序都只创建一个静态成员。最主要的特点:共享什么是共享呢?例如:统计超市中所有商品数量的总和,商品数量的总和是随着每一个数量的变化而变化的,这是我们就可以用静态成员处理。(代码下面有写)静态成员又分为静态成员变量和静态成员函数。(一)静态成员变量特点:1、所有对象共享一份数据。 2、在编译阶段分配内存。 3、类内声明,类外初始化。#include<io..._静态成员变量

HTML5七夕情人节表白网页制作【情人节满屏爱心HTML5特效】HTML+CSS+JavaScript html生日快乐祝福网页制作_html 满屏爱心-程序员宅基地

文章浏览阅读879次,点赞21次,收藏20次。1 网页简介:基于HTML+CSS+JavaScript 制作七夕情人节表白网页、生日祝福、七夕告白、 求婚、浪漫爱情3D相册、炫酷代码,快来制作一款高端的表白网页送(他/她)浪漫的告白,制作修改简单,可自行更换背景音乐,文字和图片即可使用等任意html编辑软件进行运行及修改编辑等操作)。_html 满屏爱心

【易飞】易飞ERP自动审核程序功能_易飞单据审批设置-程序员宅基地

文章浏览阅读492次,点赞9次,收藏5次。【代码】【易飞】易飞ERP自动审核程序功能。_易飞单据审批设置

青少年CTF擂台挑战赛 2024 #Round 1_xyctf高校新生联合赛 2024-程序员宅基地

文章浏览阅读1.6k次,点赞15次,收藏30次。文件打开是一个print数组v4的地址和read函数,并且nx好像可写,输入长度可以利用,进行一个栈上写好自己的shell,然后在构造一个回到v4的地址,这样子就可以重新读取到写buf段上的shell,这里要注意shell的隔断用/00截断然后构造好栈上数据。一个sql注入题目,尝试使用二分查找,但只能爆出表名和列名,值一直出不来,后来采用布尔盲注,fuzz测试后发现没有加任何过滤,直接写脚本。第二题:为了求解方程 (5 + sqrt{x} = 8),我们可以分离平方根项,然后求解 (x)。_xyctf高校新生联合赛 2024

spring数据源配置:Tomcat/weblogic数据源切换配置_tomcat 数据库切换-程序员宅基地

文章浏览阅读1.4k次。数据配置方式一般是三种:1.org.springframework.jdbc.datasource.DriverManagerDataSource(没有池概念,有连接就建立一个connection)2.org.apache.commons.dbcp.BasicDataSource(连接池技术)3.org.springframework.jndi.JndiObjectFactoryBea..._tomcat 数据库切换

推荐文章

热门文章

相关标签