2024年Android最新Android BLE 蓝牙通信库,面试大厂ui

总结

这次面试问的还是还是有难度的,要求当场写代码并且运行,也是很考察面试者写代码
因为Android知识体系比较庞大和复杂的,涉及到计算机知识领域的方方面面。在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

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

需要这份系统化学习资料的朋友,可以戳这里获取

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

所有接口都通过 BluetoothClient 调用,涉及的常量如回调的错误码都在 Constants 类中。

设备扫描


支持经典蓝牙和 BLE 设备混合扫描,可自定义扫描策略。每次扫描都要创建新的 SearchRequest,不能复用。

SearchRequest request = new SearchRequest.Builder()

.searchBluetoothLeDevice(3000, 3) // 先扫 BLE 设备 3 次,每次 3s

.searchBluetoothClassicDevice(5000) // 再扫经典蓝牙 5s

.searchBluetoothLeDevice(2000) // 再扫 BLE 设备 2s

.build();

mClient.search(request, new SearchResponse() {

@Override

public void onSearchStarted() {

}

@Override

public void onDeviceFounded(SearchResult device) {

Beacon beacon = new Beacon(device.scanRecord);

BluetoothLog.v(String.format(“beacon for %s\n%s”, device.getAddress(), beacon.toString()));

}

@Override

public void onSearchStopped() {

}

@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) {

最后

希望大家能有一个好心态,想进什么样的公司要想清楚,并不一定是大公司,我选的也不是特大厂。当然如果你不知道选或是没有规划,那就选大公司!希望我们能先选好想去的公司再投或内推,而不是有一个公司要我我就去!还有就是不要害怕,也不要有压力,平常心对待就行,但准备要充足。最后希望大家都能拿到一份满意的 offer !如果目前有一份工作也请好好珍惜好好努力,找工作其实挺累挺辛苦的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

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

需要这份系统化学习资料的朋友,可以戳这里获取

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

{

最后

希望大家能有一个好心态,想进什么样的公司要想清楚,并不一定是大公司,我选的也不是特大厂。当然如果你不知道选或是没有规划,那就选大公司!希望我们能先选好想去的公司再投或内推,而不是有一个公司要我我就去!还有就是不要害怕,也不要有压力,平常心对待就行,但准备要充足。最后希望大家都能拿到一份满意的 offer !如果目前有一份工作也请好好珍惜好好努力,找工作其实挺累挺辛苦的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

[外链图片转存中…(img-stx6s3ht-1715644626312)]

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

需要这份系统化学习资料的朋友,可以戳这里获取

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

  • 29
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值