Android 手机扫描不到wifi可以通过 BLE 被扫描到吗

后使用快捷导航没有帐号?
积分威望贡献
中级创客, 积分 1182, 距离下一级还需 1318 积分
中级创客, 积分 1182, 距离下一级还需 1318 积分
Android Ble简析
&&&& 浏览:6126
&只看该作者&
本帖最后由 Liu 于
10:38 编辑
& && & 蓝牙BLE设备是目前比较热门的设备。由于BLE有低功耗等特点,被广泛应用到身边的电子产品上。如智能手表、手环、防丢器等各种产品上。最近研究一下android上的ble应用开发。跟大家分享一下相关的内容。
& && & 我的实现使用两台android手机做ble相关的通信,一台机器作为服务端接收发过来的消息,另一台作为客户端发送消息。
& && & 客户端基本流程如下:
ble.png (262.13 KB, 下载次数: 42)
11:52 上传
1.添加蓝牙相关权限
&uses-permission android:name=&android.permission.BLUETOOTH&/&
&uses-permission android:name=&android.permission.BLUETOOTH_ADMIN&/&复制代码2.BLE设备扫描
使用BluetoothAdapter.startLeScan来扫描发现设备,这个方法需要参数BluetoothAdapter.LeScanCallback,所以还需要实现此回调方法,来获取扫描结果。
注意:BLE扫描耗电量比较大,尽可能缩短扫描时间。发现用户所需连接的设备后立即停止扫描
public class DeviceScanActivity extends ListActivity {
& & private BluetoothAdapter mBluetoothA
& & private boolean mS
& & private Handler mH
& & // 10秒后停止寻找.
& & private static final long SCAN_PERIOD = 10000;
& & ...
& & private void scanLeDevice(final boolean enable) {
& && &&&if (enable) {
& && && && &// 经过预定扫描期后停止扫描
& && && && &mHandler.postDelayed(new Runnable() {
& && && && && & @Override
& && && && && & public void run() {
& && && && && && &&&mScanning =
& && && && && && &&&mBluetoothAdapter.stopLeScan(mLeScanCallback);
& && && && && & }
& && && && &}, SCAN_PERIOD);
& && && && &mScanning =
& && && && &mBluetoothAdapter.startLeScan(mLeScanCallback);
& && &&&} else {
& && && && &mScanning =
& && && && &mBluetoothAdapter.stopLeScan(mLeScanCallback);
& && &&&}
& && &&&...
& & }
...
}
复制代码BLE扫描结果的接口,下面是BluetoothAdapter.LeScanCallback的实现。可以获取到扫描到设备的蓝牙名称和蓝牙地址等。
private LeDeviceListAdapter mLeDeviceListA
...
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
& & new BluetoothAdapter.LeScanCallback() {
& & @Override
& & public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
& && &&&runOnUiThread(new Runnable() {
& & @Override
& & public void run() {
& && && &device.getName();//获得扫描到设备名称
& && && &device.getAddress();//获取设备蓝牙地址
& && &&&}
& &&&});
& &}
};
复制代码3.连接
先获取BluetoothAdapterd,再获取BluetoothDevice。根据扫描的蓝牙设备地址获取BluetoothDevice对象。使用BluetoothDevice.connectGatt进行连接。返回BluetoothGatt实例。
然后使用connectGatt( )方法进行链接。这个方法需要三个参数:一个Context对象,自动连接(boolean值,表示只要BLE设备可用是否自动连接到它),和BluetoothGattCallback调用。后面会详细介绍BluetoothGattCallback的实现。BluetoothManager mBluetoothManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter();
BluetoothDevice mDevice = mBluetoothAdapter.getRemoteDevice(address);
复制代码4.发现BLE设备服务
mBluetoothGatt.discoverServices();复制代码5.发送Characteristic
发送消息通过读写Characteristic来完成,app完成与GATT服务端连接和发现services后,就可以读写 writeCharacteristic,每个服务和characteristic都有一个UUID来唯一确定,所有想要开发BLE必须知道你想要用哪个服务的那个characteristic也就是要知道对应的UUID。private void writeCharacteristic(String writeValue) {
& && &&&BluetoothGattCharacteristic characteristic =
& && &&&getCharacteristic(CHARACTERISTIC_UUID);
& && &&&if (characteristic == null)
& && &&&characteristic.setValue(writeValue);
& && &&&mBluetoothGatt.writeCharacteristic(characteristic);
}
private void readCharacteristic() {
& && &&&BluetoothGattCharacteristic characteristic =
& && && &getCharacteristic(CHARACTERISTIC_UUID);
& && &&&if (characteristic != null) mBluetoothGatt.readCharacteristic(characteristic);
}
复制代码6.BluetoothGattCallback实现
根据BluetoothGattCallback判断当前状态。获取是否连接成功、是否断开连接、读写Characteristic是否成功等。
private final BluetoothGattCallback mGattCallbacks = new BluetoothGattCallback() {
& &&&@Override
& &&&//获取连接状态方法,BLE设备连接上或断开时,会调用到此方
& &&&public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
& && && &if (DEBUG) Log.d(TAG, &onConnectionStateChange&);
& && && &if (status == BluetoothGatt.GATT_SUCCESS) {
& && && &if (newState == BluetoothProfile.STATE_CONNECTED) {
& && && && & showMessage(&Bluetooth LE connected&);
& && &&&}
& && &&&else if (status == BluetoothProfile.STATE_DISCONNECTED) {
& && && && & showMessage(&Bluetooth LE disconnected&);
& && && &}
& && &}
& & }
& &
& &&&//成功发现设备的services时,调用此方法
& &&&@Override
& &&&public void onServicesDiscovered(BluetoothGatt gatt, int status) {
& && && &if ((status == BluetoothGatt.GATT_SUCCESS) &&
& && && &(mBluetoothGatt.getService(SERVICE_UUID) != null)) {
& && && && & showMessage(&Discover service Successful !!!&);
& && && &}
& && &}
& & //读写characteristic时会调用到以下方法
& &&&@Override
& &&&public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
& && && &if ((status == BluetoothGatt.GATT_SUCCESS) &&
& && && && & (characteristic.getUuid().equals(CHARACTERISTIC_UUID))) {
& && && && && &&&showMessage(characteristic.getStringValue(0));
& && && && &}
& &&&}
& &&&@Override
& &&&public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
& && && & BluetoothGattCharacteristic mCharacteristic =
& && && && & getCharacteristic(CHARACTERISTIC_UUID);
& && && && &if ((status == BluetoothGatt.GATT_SUCCESS) &&
& && && && && & (characteristic.getStringValue(0).equals(mCharacteristic.getStringValue(0)))) {
& && && && && & showMessage(&CharacteristicWrite Successful !!!&);
& && && && &}
& && &&&}
& & };
复制代码7.断开链接
mBluetoothGatt.disconnect();复制代码
以上是客户端(进行消息发送)的实现,下面介绍服务端实现方法。
服务端实现比较简单,首先创建BluetoothManager,使用openGattServer实例mGattServer。openGattServer需要一个BluetoothGattServerCallback回调。创建BluetoothGattService,再把BluetoothGattService添加到BluetoothGattServer中。BluetoothManager&&mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothGattServer mGattServer = mBluetoothManager.openGattServer(this, mCallbacks);
BluetoothGattService mService = createService();
mGattServer.addService(mService);复制代码BluetoothGattServerCallback回调的实现,在这个回调里面可以获取到服务端发送过来的消息,连接状态等
& && && && && && && && && && & private final BluetoothGattServerCallback mCallbacks = new BluetoothGattServerCallback() {
& & @Override
& & //获取连接状态方法,BLE设备连接上或断开时,会调用到此方
& & public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
& && &&&if (DEBUG) Log.d(TAG, &onConnectionStateChange: newState=& + newState);
& && &&&if (status == BluetoothGatt.GATT_SUCCESS) {
& && && && &if (newState == BluetoothProfile.STATE_CONNECTED) {
& && && && && & mDevice =
& && && && && & String devicename = device.getName();
& && && && && & String address = device.getAddress();
& && && && && & notifyConnected(devicename);
& && && && && & beginNotification();
& && && && &} else if (status == BluetoothProfile.STATE_DISCONNECTED) {
& && && && && & stopNotification();
& && && && && & notifyDisconnected();
& && && && && & mDevice =
& && && && &}
& && &&&}
& & }
& & //service添加成功会调用此方
& & @Override
& & public void onServiceAdded(int status, BluetoothGattService service) {
& && &&&if (DEBUG) Log.d(TAG, &onServiceAdded()&);
& && &&&if (status == BluetoothGatt.GATT_SUCCESS) notifyServiceAdded();
& & }
& &
& & //读写Characteristic,在此获得客户端发来的消息
& & @Override
& & public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,BluetoothGattCharacteristic characteristic,
& && &&&boolean preparedWrite, boolean responseNeeded,int offset, byte[] value) {
& && &&&if (DEBUG) Log.d(TAG, &onCharacteristicWriteRequest: preparedWrite=& + preparedWrite);
& && && && &try{
& && && && && & mCharacteristicString = new String(value); //客户端发来的消息
& && && && &}catch(Exception e){
& && && && &}
& && && && &notifyCharacteristicWriteRequest(mCharacteristicString);
& && &&&}
& & }
& &&&@Override
& & public void onCharacteristicReadRequest(BluetoothDevice device, int requestId,
& && &&&int offset, BluetoothGattCharacteristic characteristic) {
& && &&&if (DEBUG) Log.d(TAG, &onCharacteristicReadRequest()&);
& && && && &notifyCharacteristicReadRequest();
& && &&&}
};
复制代码android ble的内容就暂时介绍到这里,上面介绍的实现方法,是有一台android手机来模拟一个BLE的设备。拿到真实的BLE设备(防丢器),还会继续发帖分享给大家,希望大家继续关注!!
再发几张我这个测试应用的操作截图
1.在server端点击Start Server,上面文本提示BLE SERVICE ADDED
1server.png (16.98 KB, 下载次数: 36)
10:22 上传
2.在Client端,输入服务端手机的蓝牙地址,然后点在onnect
1client.png (43.42 KB, 下载次数: 37)
10:26 上传
3.进行配对,两台手机分别点击配对
2.png (84.3 KB, 下载次数: 34)
10:28 上传
4.客户端点击Discover service,Toast提示Discover service Successful。
& & 服务端显示Device Connect。
3.png (64.93 KB, 下载次数: 35)
10:28 上传
5.客户端输入要发送的字符&123456&,点击Write Characteristic。
& &服务端接收到发送过来的字符,显示Device Write:123456
4.png (68.85 KB, 下载次数: 34)
10:28 上传
6.客户端点击Disconnect断开连接
& &服务端显示Device Disconnected
5.png (69.23 KB, 下载次数: 35)
10:28 上传
评分威望 +20
有没有做过android 和IOS之间的BLE连接
积分威望贡献
&只看该作者&
楼主有心整理了,学习了!
Android BLE现在运用挺广泛的,低功耗市场很大,期待楼主有更深入的技术介绍
积分威望贡献
技术小白, 积分 10, 距离下一级还需 190 积分
技术小白, 积分 10, 距离下一级还需 190 积分
&只看该作者&
楼主威武呀!能否分享一下你用的是什么版本的android和机型...
我手里的小米只能当client,作为server无法发现,不知道啥原因了!
积分威望贡献
中级创客, 积分 1182, 距离下一级还需 1318 积分
中级创客, 积分 1182, 距离下一级还需 1318 积分
&只看该作者&
楼主威武呀!能否分享一下你用的是什么版本的android和机型...
我手里的小米只能当client,作为server无法 ...
手机只能模拟成BLE设备,不能做真实的设备来使用。
模拟设备时可能出现扫描不到的情况。可以跳过扫描,直接通过手机的蓝牙地址进行链接使用。
手机是ANDROID4.4。
积分威望贡献
技术小白, 积分 2, 距离下一级还需 198 积分
技术小白, 积分 2, 距离下一级还需 198 积分
&只看该作者&
您好楼主,我在学习BLE,我用的是SONY的 手机,android 系统4.4.2 KitKat,BLE sensortag 在做。
mBluetoothAdapter.startLeScan(mLeScanCallback);
上面的这个方法在API 19已经不能使用了,然而我换用mBluetoothAdapter.startScan(mLeScanCallback);
请帮忙解决一下!谢谢了。
积分威望贡献
技术小白, 积分 8, 距离下一级还需 192 积分
技术小白, 积分 8, 距离下一级还需 192 积分
&只看该作者&
楼主,我这里怎么也链接不上。能分享下代码吗?
Copyright & 2014 Firefly. All Rights Reserved.
产品分销 &: sales@
样板申请 &: apply@
行业定制 &: product@
教育用户 &: education@
联系电话 &: (+86)
综合支持 &: service@
MiniPC (①群) &:
MiniPC (②群) &:
Fireduino (QQ群) &:
友情链接 :一BluetoothAdapter简介;1.继承关系;该类仅继承了Object类;;2.该类作用;BluetoothAdapter代表了移动设备的;启动设备发现(startDiscovery),;获取已配对设备(getBoundedDevice;通过mac蓝牙地址获取蓝牙设备(getRemot;从其它设备创建一个监听连接(listenUsin;Bluetoo
一 BluetoothAdapter简介
1.继承关系
该类仅继承了Object类;
2.该类作用
BluetoothAdapter代表了移动设备的本地的蓝牙适配器, 通过该蓝牙适配器可以对蓝牙进行基本操作, 例如 :
启动设备发现(startDiscovery),
获取已配对设备(getBoundedDevices),
通过mac蓝牙地址获取蓝牙设备(getRemoteDevice),
从其它设备创建一个监听连接(listenUsingRfcommWithServiceRecord);
BluetoothAdapter.getDefaultAdapter()该静态方法可以获取该适配器对象
3.蓝牙权限
android.permission.BLUETOOTH
允许程序连接到已配对的蓝牙设备, 请求连接/接收连接/传输数据需要改权限, 主要用于对配对后进行操作;
android.permission.BLUETOOTH_ADMIN
允许程序发现和配对蓝牙设备, 该权限用来管理蓝牙设备, 有了这个权限, 应用才能使用本机的蓝牙设备, 主要用于对配对前的操作;
优先级 : BLUETOOTH权限是BLUETOOTH_ADMIN权限的前提, 如果没有BLUETOOTH权限, 就不能使用BLUETOOTH_ADMIN权限;
二 API详解
1.常量介绍
(1)开关状态值
蓝牙关闭 : int STATE_OFF , 值为10, 蓝牙模块处于关闭状态;
蓝牙打开中 : int STATE_TURNING_ON , 值为11, 蓝牙模块正在打开;
蓝牙开启 : int STATE_ON , 值为12, 蓝牙模块处于开启状态;
蓝牙开启中 : int STATE_TURNING_OFF , 值为13, 蓝牙模块正在关闭;
蓝牙开关状态顺序 : STATE_OFF --& STATE_TURNING_ON --& STATE_ON --&
STATE_TURNING_OFF --& STATE_OFF;
(2)扫描状态值
无功能状态 : int SCAN_MODE_NONE , 值为20, 查询扫描和页面扫描都失效, 该状态下蓝牙模块既不能扫描其它设备, 也不可见;
扫描状态 : int SCAN_MODE_CONNECTABLE , 值为21, 查询扫描失效, 页面扫描有效, 该状态下蓝牙模块可以扫描其它设备, 从可见性来说只对已配对的蓝牙设备可见, 只有配对的设备才能主动连接本设备;
可见状态 : int SCAN_MODE_CONNECTABLE_DISCOVERABLE, 值为23, 查询扫描和页面扫描都有效;
查询扫描功能 : 其它设备可以扫描到本设备 , 指的是可见性可见;
页面扫描功能 : 可以主动扫描其它设备;
(3)蓝牙操作接收的广播
开始搜索广播 : String ACTION_DISCOVERY_STARTED, 蓝牙适配器开始搜索远程设备, 值为
&android.bluetooth.action.DISCOVERY_START&, 蓝牙适配器开始搜索之后, 会先有12秒的查询扫描(12s内可见), 查询扫描后进行页面扫描(主动搜索), 需要BLUETOOTH权限;
如果搜索到蓝牙设备, 就会收到BluetoothDevice.ACTION_FOUND广播, 可以从Intent中获取存放在其中的BluetoothDevice对象,
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
设备查找非常消耗资源, 在查找的过程中, 不能连接远程的蓝牙设备, 已经存在的连接也要限制带宽, 如果想要执行除查找外的其它操作, 之前最好调用cancelDiscovery();
搜索完成广播 : String ACTION_DISCOVERY_FINISHED,蓝牙S适配器完成搜索发出的广播, 值为&android.bluetooth.adapter.action.DISCOVERY_FINISHED&, 需要BLUETOOTH权限;
蓝牙名称改变广播 : String ACTION_LOCAL_NAME_CHANGED, 本地的蓝牙适配器改变了自己的名称, 值为&android.bluetooth.adapter.action.LOCAL_NAME_CHANGED&, 注意改变的是本设备名称, 不是远程设备的.这个广播包含一个EXTRA_LOCAL_NAME附加域, 需要BLUETOOTH权限;
扫描模式变化广播 : String ACTION_SCAN_MODE_CHANGED, 蓝牙模块扫描模式发生了变化, 值为&android.bluetooth.adapter.action.SCAN_MODE_CHANGED&, 该Intent对象包含了
EXTRA_SCAN_MODE和EXTRA_PREVIOUS_SCAN_MODE, 两个附加域分别是新的和旧的扫描模式, 这里可以根据前后扫描模式的不同做出不同的操作, 需要BLUETOOTH权限;
开关模式变化广播 : String ACTION_STATE_CHANGED, 蓝牙模块被打开或者关闭, 值为
&android.bluetooth.adapter.action.STATE_CHANGED&, 该广播的Intent中包含
EXTRA_STATE和EXTRA_PREVIOUS_STATE两个附加域, 需要BLUETOOTH权限;
(4)蓝牙操作请求的广播
开启蓝牙 : String ACTION_REQUEST_ENABLE, 打开蓝牙, 值为
&android.bluetooth.adapter.action.REQUEST_ENABLE&,
Intent intent = new Intent (BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, requestCode);
可以在Activity中的onActivityResult()方法中处理结果, 如果蓝牙模块打开成功, 则返回结果吗
RESULT_OK; 如果蓝牙模块打开失败, 则返回结果码RESULT_CANCELED;
打开和关闭蓝牙模块, 都可以通过ACTION_STATE_CHANGED广播来监听;
蓝牙可见 : String ACTION_REQUEST_DISCOVERABLE, 使蓝牙可见, 值为
&android.bluetooth.adapter.action.REQUEST_DISCOVERABLE&, 默认的可见时间为120s, 可以在广播中添加附加域, 设置任意的可见时间, 附加域为EXTRA_DISCOVERABLE_DURATION, 需要BLUETOOTH权限;
可以在Activity中的onActivityResult()方法中处理结果, 如果蓝牙模块设置可见成功, 则返回结果吗RESULT_OK; 如果蓝牙模块设置可见失败, 则返回结果码RESULT_CANCELED;
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0); startActivityForResult(discoverableIntent,resultCode)
附加域是放在Intent中的, 使用Intent.putExtra(附加域,附加值)方法添加附加域;
扫描模式附加域 : 这两个附加域的值是扫描模式, 可以为SCAN_MODE_NONE,
SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE_DISCOVERABLE;
String EXTRA_SCAN_MODE : 值为&android.bluetooth.adapter.extra.SCAN_MODE&; String EXTRA_PREVIOUS_SCAN_MODE : 值为
&android.bluetooth.adapter.extra.PREVIOUS_SCAN_MODE&;
开关状态附加域 : 这两个附加域的值是开关状态, 可以为STATE_OFF, STATE_ON,
STATE_TURNING_OFF, STATE_TURNING_ON;
String EXTRA_STATE : 值为&android.bluetooth.adapter.extra.STATE&;
String EXTRA_PREVIOUS_STATE : 值为
&android.bluetooth.adapter.extra.PREVIOUS_STATE&;
蓝牙名称附加域 : String EXTRA_LOCAL_NAME , 存放ACTION_LOCAL_NAME_CHANGED附加域的附加值 , 值为&android.bluetooth.adapter.extra.LOCAL_NAME&;
可见时间附加域 : String EXTRA_DISCOVERABLE_DURATION, 存放的是
ACTION_REQUEST_DISCOVERABLE广播的可见时长, 值为
&android.bluetooth.adapter.extra.DISCOVERABLE_DURATION&;
int ERROR , 这个值用来标记错误 , 方便自己使用的 , 没有实际意义;
2.State状态相关方法
(1)获取蓝牙适配器
public static sychronized BluetoothAdapter getDefaultAdapter();
返回值 : 本地蓝牙适配器 BluetoothAdapter对象;
(2)获取state状态方法
public int getState();
作用 : 获取是否可用
返回值 : 返回当前的State状态值, STATE_ON, STATE_OFF, STATE_TURNING_ON,
STATE_TURNING_OFF;
权限 : BLUETOOTH;
(3)蓝牙是否可用
public boolean isEnable();
作用 : 获取当前设备蓝牙模块是否可用;
返回值 : 返回当前蓝牙模块是否可用, true 可用, false 不可用;
权限 : BLUETOOTH权限;
(4)打开蓝牙
public boolean enable();
作用 : 打开本地蓝牙适配器;
返回值 : 如果打开成功则返回true, 如果打开失败返回
权限 : BLUETOOTH_ADMIN权限;
(5)关闭蓝牙
public boolean disable();
作用 : 关闭本地设备蓝牙;
返回值 : 如果关闭蓝牙成功, 返回 如果关闭蓝牙失败, 返回
权限 : BLUETOOTH_ADMIN权限;
3. 扫描相关方法
(1)开始扫描
public boolean startDiscovery();
作用 : 开始查找远程蓝牙设备, 先进行12秒的查询扫描(被动可见), 之后进行页面扫描(主动搜索); 搜索过成功不能尝试对远程设备的连接, 同时已连接的设备的带宽也会被压缩, 等待时间变长; 使用cancelDiscovery()可以终止搜索;
返回值 : 如果成功则返回true, 失败返回
BLUETOOTH_ADMIN权限;
(2)是否在扫描中
public boolean isDiscovering();
作用 : 是否正在搜索;
返回值 : 如果设备正在搜索, 返回 如果设备没有进行蓝牙搜索, 返回
权限 : BLUETOOTH权限;
(3)取消查找
public boolean cancelDiscovery();
三亿文库包含各类专业文献、文学作品欣赏、生活休闲娱乐、各类资格考试、外语学习资料、专业论文、android BLE简介35等内容。 
 Android BLE 与终端通信(五)―― Google API BLE4.0 低功耗蓝牙文档解 读之案例初探一.概述 我们直接翻译 Generic Attribute Profile(GATT)―GATT 配置文件是一个...  Android BLE 与终端通信(三)――客 户端与服务端通信过程以及实现数据通 信一.蓝牙数据传输 蓝牙数据传输其实跟我们的 Socket(套接字)有点类似,如果有不懂的,...  Android BLE与终端通信(二)――Android Bluetooth基础搜索蓝牙设备显示列表_互联网...蓝牙简介 蓝牙这个名称来自于第十世纪的一位丹麦国王哈拉尔蓝牙王,Blatand 在英文...  Android L新特性 整理_互联网_IT/计算机_专业资料。根据网上的资料进行整理的Android 5.0新特性安卓5.0Lollipop 带来了全新的用户界面,并且拥有 64 位计算、ART 运行...  Android BLE与终端通信(四)――实现服务器与客户端即时通讯功能_计算机软件及应用_IT/计算机_专业资料。Android BLE与终端通信(四)――实现服务器与客户端即时通讯...  运行结果如下: 二.Serialiazble 和 Parcelable 的用法 1.总体描述: 在 Android 开发过程中, 经常要在 Activity 之间传递参数, 使用 Android 系统提供的方法可以...  将会 android:baselineAli setBaselineAligned(boolea 阻止该布局管理器与其 gned n) 它的子元素的基线对齐 setDividerDrawable(Drawa android:divider ble) 设置垂直...  android:id:该属性指定了该控件的唯一标识,在 Java 程序 中可通过 findView...{R.drawable.img1,R.drawable.img2,R.drawable.img3,R.drawa ble.img4,R...  摘要: 通过两个主要的 API, Android 提供了一个直接在位图上进行脸部检测的...(), R.drawa ble.face3); 18.mFaceBitmap = b.copy(Bitmap.Config.RGB_...AndroidBleManager项目地址:简介:Android-支持 BLE,ibeacon 的扫描,单连接,多连接管理更多:&&&&&&&&&标签:AndroidBleManager
强大的蓝牙工具库
集成 Android 蓝牙(支持 Ibeacon)扫描,单个设备连接,多设备同时连接,连接 Gatt 服务扫描及属性读取封装
使用简单快捷,一键集成
经过实际场景测试,实际产品的使用
将下面的代码增加到 build.gradle 文件中,${latest.version} is
dependencies {
compile 'com.blakequ.androidblemanager:bluetooth-manager-lib:${latest.version}'
&dependency&
&groupId&com.blakequ.androidblemanager&/groupId&
&artifactId&bluetooth-manager-lib&/artifactId&
&version&${latest.version}&/version&
&type&pom&/type&
&/dependency&
1. 功能特性
支持低版本扫描兼容。对 SDK=23 的蓝牙扫描进行了封装,对外没有区别,自动识别使用的扫描接口(可指定低版本扫描,有些手机使用低版本才能扫描到)
支持低功耗扫描。支持不间断扫描同时考虑功耗,支持在前台高频扫描后台低频扫描,原理和测试参考
支持 Ibeacon 识别。自动识别 Ibeacon 设备并解析 ibeacon 的数据
支持循环扫描(可暂停),启动后台扫描时节约 60%的电量
1.2 单个设备连接
支持单个设备连接。完善的 Gatt 管理机制,防止连接多个设备,具有连接排他性,保证永远只有一个设备连接
简化连接接口。不用关注连接细节和切换断开时资源释放问题(133 错误经常发生)
支持断开后自动重连。当连接断开后支持自动重连,重连时间和下一次连接时间成正比增加,防止不间断重连
支持连接状态实时监听。使用回调监听连接状态(连接中,连接上,断开)
1.3 多个设备连接
支持同时连接多个蓝牙设备(最多连接设备数可设置)。完善的 Gatt 管理机制,不用担心多设备连接时资源释放问题。
支持多设备连接状态实时监听。
支持多设备断开后自动重连。并且自动重连的时间间隔会随着重连次数增加自动增长(防止不间断连接)
使用简单:添加多个设备-开始连接-最后释放资源即可(支持连接过程中动态添加设备)
2. 图片预览
3. 使用说明
获取扫描管理器
BluetoothScanManager scanManager = BleManager.getScanManager(context);
scanManager.addScanFilterCompats(new ScanFilterCompat.Builder().setDeviceName(&oby&).build());
scanManager.setScanOverListener(new ScanOverListener() {
public void onScanOver() {
//scan over of one times
scanManager.setScanCallbackCompat(new ScanCallbackCompat() {
public void onBatchScanResults(List&ScanResultCompat& results) {
super.onBatchScanResults(results);
public void onScanFailed(final int errorCode) {
super.onScanFailed(errorCode);
public void onScanResult(int callbackType, ScanResultCompat result) {
super.onScanResult(callbackType, result);
//scan result
//start scan
scanManager.startCycleScan(); //不会立即开始,可能会延时
//scanManager.startScanNow(); //立即开始扫描
scanManager.stopCycleScan();
//is scanning
scanManager.isScanning()
scanManager.release();
getPowerSaver(); //可以参考具体使用方法 BackgroundPowerSaver,可以设置循环扫描前台和后台扫描和间隔的时间
startScanOnce(); //单次扫描,只扫描一次
setAPI21ScanningDisabled(false); //禁止使用新的扫描方式
扫描结果回调已经放在了主线程,可直接使用并更新视图 UI
3.2 单设备连接
获取连接管理器BluetoothConnectManager connectManager = BleManager.getConnectManager(context);
连接状态监听
//如果不用需要移除状态监听 removeConnectStateListener
connectManager.addConnectStateListener(new ConnectStateListener() {
public void onConnectStateChanged(String address, ConnectState state) {
switch (state){
case CONNECTING:
case CONNECTED:
case NORMAL:
connectManager.setBluetoothGattCallback(new BluetoothGattCallback() {
//注意:里面的回调方法都是在非主线程
蓝牙读写数据与通知
为了简化蓝牙连接,已经自动封装了蓝牙 Gatt 的读写和通知。
- 传统方式
private BluetoothGatt mBluetoothG
BluetoothGattCharacter
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
- 封装使用
//start subscribe auto
//1.set service uuid(将要读取 GattService 的 UUID)
connectManager.setServiceUUID(serverUUid.toString());
//2.clean history descriptor data(清除历史订阅读写通知)
connectManager.cleanSubscribeData();
//3.add subscribe params(读写和通知)
connectManager.addBluetoothSubscribeData(
new BluetoothSubScribeData.Builder().setCharacteristicRead(characteristic.getUuid()).build());//read characteristic
connectManager.addBluetoothSubscribeData(
new BluetoothSubScribeData.Builder().setCharacteristicNotify(characteristic.getUuid()).build()); //notify
connectManager.addBluetoothSubscribeData(
new BluetoothSubScribeData.Builder().setCharacteristicWrite(characteristic.getUuid()).build()); //write characteristic
connectManager.addBluetoothSubscribeData(
new BluetoothSubScribeData.Builder().setCharacteristicWrite(characteristic.getUuid(), byteData).build();
//还有读写 descriptor
//start subscribe(注意,在使用时当回调 onServicesDiscovered 成功时会自动调用该方法,所以只需要在连接之前完成 1,3 步即可),如果需要单独读写某些属性,则可以单独调用该方法,并且同样使用步骤 2,3 然后调用该方法手动启动订阅
boolean isSuccess = connectManager.startSubscribe(gatt); //返回是否成功实现订阅
连接与断开
connect(macAddress);
disconnect(macAddress);
closeAll(); //关闭所有连接设备
getConnectedDevice(); //获取当前已经连接的设备列表
getCurrentState(); //获取当前设备状态
scanManager.release();
设备的连接,断开尽量在主线程中完成,否则在某些机型(三星)会出现许多意想不到的错误。
3.3 多设备连接
获取多设备连接管理器
MultiConnectManager multiConnectManager = BleManager.getMultiConnectManager(context);
添加状态监听
//如果不用需要移除状态监听 removeConnectStateListener
connectManager.addConnectStateListener(new ConnectStateListener() {
public void onConnectStateChanged(String address, ConnectState state) {
switch (state){
case CONNECTING:
case CONNECTED:
case NORMAL:
connectManager.setBluetoothGattCallback(new BluetoothGattCallback() {
//注意:里面的回调方法都是在非主线程
添加待设备到队列
如果添加的设备超过了最大连接数,将会自动移除多余的设备
addDeviceToQueue(deviceList);
//手动移除多余的连接设备
removeDeviceFromQueue(macAddress);
蓝牙读写数据与通知
//start subscribe auto
//1.set service uuid(将要读取 GattService 的 UUID)
connectManager.setServiceUUID(serverUUid.toString());
//2.clean history descriptor data(清除历史订阅读写通知)
connectManager.cleanSubscribeData();
//3.add subscribe params(读写和通知)
connectManager.addBluetoothSubscribeData(
new BluetoothSubScribeData.Builder().setCharacteristicRead(characteristic.getUuid()).build());//read characteristic
connectManager.addBluetoothSubscribeData(
new BluetoothSubScribeData.Builder().setCharacteristicNotify(characteristic.getUuid()).build()); //notify
connectManager.addBluetoothSubscribeData(
new BluetoothSubScribeData.Builder().setCharacteristicWrite(characteristic.getUuid()).build()); //write characteristic
connectManager.addBluetoothSubscribeData(
new BluetoothSubScribeData.Builder().setCharacteristicWrite(characteristic.getUuid(), byteData).build();
//还有读写 descriptor
//start descriptor(注意,在使用时当回调 onServicesDiscovered 成功时会自动调用该方法,所以只需要在连接之前完成 1,3 步即可)
connectManager.startSubscribe(gatt);
startConnect();
//连接其中的指定设备
startConnect(String);
scanManager.release();
getQueueSize(); //当前队列中设备数
setMaxConnectDeviceNum(); //设置最大连接数量
getMaxLen(); //获取最大的连接数量
getConnectedDevice(); //获取已经连接的设备
getDeviceState(macAddress); //获取当前设备连接状态
getAllDevice();
getAllConnectedDevice();
getAllConnectingDevice();
3.4 个性化扫描和连接配置
可设置参数如下:boolean isDebugMode = //是否为 debug 模式,建议使用 BuildConfig.DEBUG 设置,如果为 true 则打印日志
long foregroundScanPeriod = 10000; //在前台时(可见扫描界面)扫描持续时间
long foregroundBetweenScanPeriod = 5000; //在前台时(可见扫描界面)扫描间隔暂停时间,我们扫描的方式是间隔扫描
long backgroundScanPeriod = 10000; //在后台时(不可见扫描界面)扫描持续时间
long backgroundBetweenScanPeriod = 5 * 60 * 1000; //在后台时(不可见扫描界面)扫描间隔暂停时间,我们扫描的方式是间隔扫描
int maxConnectDeviceNum = 5;//一次最多连接设备个数
int reconnectStrategy = 3; //如果连接自动断开之后的重连策略(ConnectConfig.RECONNECT_LINEAR,ConnectConfig.RECONNECT_EXPONENT,ConnectConfig.RECONNECT_LINE_EXPONENT,ConnectConfig.RECONNECT_FIXED_TIME)
int reconnectMaxTimes = Integer.MAX_VALUE; //最大重连次数,默认可一直进行重连
long reconnectBaseSpaceTime = 8000; //重连基础时间间隔 ms,重连的时间间隔
int reconnectedLineToExponentTimes = 5; //快速重连的次数(线性到指数,只在 reconnectStrategy=ConnectConfig.RECONNECT_LINE_EXPONENT 时有效)
int connectTimeOutTimes = 15000; //连接超时时间 15s,15s 后自动检测蓝牙状态(如果设备不在连接范围或蓝牙关闭,则重新连接的时间会很长,或者一直处于连接的状态,现在超时后会自动检测当前状态)
使用方法BleManager.setBleParamsOptions(new BleParamsOptions.Builder()
.setBackgroundBetweenScanPeriod(5 * 60 * 1000)
.setBackgroundScanPeriod(10000)
.setForegroundBetweenScanPeriod(5000)
.setForegroundScanPeriod(10000)
.setDebugMode(BuildConfig.DEBUG)
.setMaxConnectDeviceNum(5)
.setReconnectBaseSpaceTime(8000)
.setReconnectMaxTimes(Integer.MAX_VALUE)
.setReconnectStrategy(ConnectConfig.RECONNECT_LINE_EXPONENT)
.setReconnectedLineToExponentTimes(5)
.setConnectTimeOutTimes(20000)
.build());
使用时需要如下权限
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
if SDK &= 23, 增加权限
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
5.更新日志
v1.0(): 完成基本框架(扫描,设备连接)
v1.0(): 修复多设备连接 bug
v1.0(): 增加 demo 权限检查
v2.0(): 完善 demo,增加多设备单个设备的单独连接入口
v2.1(): 增加扫描和连接的个性化配置
v2.1.1(): 修复多个设备连接时,无法移除某个设备
v2.1.2(): 新增重连策略,每次断开之后重连按照固定时间,如每次断开之后 10s 就启动重连;新增超时连接设置,当连接过程中超时会自动检测蓝牙状态,并可设置超时时间;修复多连接时调用 startConnect()无法立即启动重连的问题
v2.1.3(): 修复无法立即停止扫描和设置扫描间隔无法立即生效的问题
:删除 fir,更新 demo,增加扫描过滤,可以调整扫描周期间隔
如果无法扫描到任何设备,请检查当前 APP 运行 SDK 是否&=23, 如果 SDK&=23 的手机必须申请位置权限并且打开位置信息,否则无法扫描到设备(是 23 的最新限制,当然如果知道 mac 地址可直接连接),检查可通过如下代码
///questions//bluetooth-low-energy-startscan-on-android-6-0-does-not-find-devices/45489
private boolean checkLocationPermission() {
return checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION) || checkPermission(Manifest.permission.ACCESS_FINE_LOCATION);
private boolean checkPermission(final String permission) {
return ContextCompat.checkSelfPermission(mContext, permission) == PackageManager.PERMISSION_GRANTED;
public static boolean isGpsProviderEnabled(Context context){
LocationManager service = (LocationManager) context.getSystemService(context.LOCATION_SERVICE);
return service.isProviderEnabled(LocationManager.GPS_PROVIDER);
动态打开关闭日志 BleManager.getInstance().setLogDebugMode(BuildConfig.DEBUG);
设置连接参数ConnectConfig.updateMaxConnectNumber(5);//多连接时,最大连接个数
ConnectConfig.updateReconnectNumber(4); //重连的次数(小于该次数时,间隔重连时间为:断开时间+断开次数*间隔时间;大于该次数时,间隔重连时间呈指数增长)
ConnectConfig.updateReconnectSpaceTime(4000); //间隔重连时间
7. 链接参考
其中 ibeacon 封装和扫描部分代码参考如下开源库,在此感谢作者的无私奉献。}

我要回帖

更多关于 邮政可以通过手机号码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信