github地址:https://github.com/qindachang/BluetoothLE-Multi-Library

BluetoothLE-Multi-Library

一个能够连接多台蓝牙设备的库,它可以作为client端,也可以为server端。支持主机/从机,外围设备连接。
在发送消息时,它内部支持队列控制,避免因蓝牙间隔出现操作失败的情况。

开始使用

1. 主机client

扫描

BluetoothLeScannerCompat scannerCompat = BluetoothLeScannerCompat.getScanner();
ScanSettings scanSettings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setReportDelay(int reportDelayMillis) //0 or above >0
.setUseHardwareBatchingIfSupported(false)
.build(); //设置过滤扫描
List<ScanFilter> filters = new ArrayList<>(); ScanFilter builder = new ScanFilter.Builder().setDeviceName(deviceName).build();
filters.add(builder); ScanFilter builder = new ScanFilter.Builder().setDeviceAddress(deviceAddress).build();
filters.add(builder); ScanFilter builder = new ScanFilter.Builder()
.setServiceUuid(ParcelUuid.fromString(serviceUUID.toString())).build();
filters.add(builder); scannerCompat.startScan(filters, scanSettings, scanCallback);

扫描回调

private ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(final int callbackType, final ScanResult result) { } @Override
public void onBatchScanResults(final List<ScanResult> results) { } @Override
public void onScanFailed(final int errorCode) { }
};

连接

//创建连接的一个对象,后续将使用该对象来访问操作
private BluetoothLeConnector connector = BluetoothLe.newConnector();
private BluetoothGatt mBluetoothGatt; //配置连接对象
connector.setConfig(new BluetoothConfig.Builder()
.enableQueueInterval(true)//开启操作时间间隔
.setQueueIntervalTime(BluetoothConfig.AUTO)//单位ms,这里为自动
.build());
//连接蓝牙
connector.connect(true, mBluetoothDevice);
connector.connect(true, mBluetoothDevice, BluetoothLeConnector.TRANSPORT_AUTO);//最后一个参数设置连接通道
//开启indicate通知
connector.enableIndication(true,UUID_SERVICE,UUID_INDICATION);
//开启notify通知
connector.enableNotification(true, UUID_SERVICE, UUID_NOTIFICATION);
//写数据
connector.writeCharacteristic(new byte[]{0x01, 0x02}, UUID_SERVICE, UUID_WRITE);
//自定义写数据
BluetoothGattService service = mBluetoothGatt.getService(UUID_SERVICE);
BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID_WRITE);
characteristic.setValue(byte[] value);
characteristic.setValue(int value, int formatType, int offset);
characteristic.setValue(int mantissa, int exponent, int formatType, int offset);
characteristic.setValue(String value);
connector.writeCharacteristic(characteristic);
//读数据
connector.readCharacteristic(UUID_SERVICE, UUID_READ);
//断开连接
connector.disconnect();
//关闭gatt
connector.close();

回调监听

//连接状态监听
private ConnectListener mConnectListener = new ConnectListener() {
@Override
public void connecting() { } @Override
public void connected() { } @Override
public void disconnected() { } @Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) { } @Override
public void error(ConnBleException e) { }
};
connector.addConnectListener(mConnectListener);

更多的回调监听如下:

mBleManager.addConnectListener(...)
mBleManager.addNotificationListener(...)
mBleManager.addIndicationListener(...)
mBleManager.addWriteCharacteristicListener(...)
mBleManager.addReadCharacteristicListener(...)
mBleManager.addRssiListener(...)

移除回调监听(好的程序员要懂避免内存泄漏):

connector.removeListener(mConnectListener);

2. 从机Server

广播

private GattServer mGattServer = new GattServer();

mGattServer.startAdvertising(UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb"));//该uuid可提供给主机client过滤扫描

mGattServer.stopAdvertising();

伺服器server

1. 启动startServer
mGattServer.startServer(context);
2. 关闭closeServer
mGattServer.closeServer();
3. 添加服务addService
List<ServiceProfile> list = new ArrayList<>();

//设置一个写的特征
ServiceProfile profile = new ServiceProfile();
profile.setCharacteristicUuid(UUID.fromString("0000fff3-0000-1000-8000-00805f9b34fb"));
profile.setCharacteristicProperties(BluetoothGattCharacteristic.PROPERTY_WRITE);
profile.setCharacteristicPermission(BluetoothGattCharacteristic.PERMISSION_WRITE);
profile.setDescriptorUuid(GattServer.CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID);
profile.setDescriptorPermission(BluetoothGattDescriptor.PERMISSION_READ);
profile.setDescriptorValue(new byte[]{0});
list.add(profile); //设置一个读的特征
ServiceProfile profile1 = new ServiceProfile();
profile1.setCharacteristicUuid(UUID.fromString("0000fff2-0000-1000-8000-00805f9b34fb"));
profile1.setCharacteristicProperties(BluetoothGattCharacteristic.PROPERTY_READ);
profile1.setCharacteristicPermission(BluetoothGattCharacteristic.PERMISSION_READ);
profile1.setDescriptorUuid(GattServer.CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID);
profile1.setDescriptorPermission(BluetoothGattDescriptor.PERMISSION_READ);
profile1.setDescriptorValue(new byte[]{1});
list.add(profile1); //设置一个notify通知
ServiceProfile profile2 = new ServiceProfile();
profile2.setCharacteristicUuid(UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb"));
profile2.setCharacteristicProperties(BluetoothGattCharacteristic.PROPERTY_NOTIFY);
profile2.setCharacteristicPermission(BluetoothGattCharacteristic.PERMISSION_READ);
profile2.setDescriptorUuid(GattServer.CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID);
profile2.setDescriptorPermission(BluetoothGattDescriptor.PERMISSION_WRITE);
profile2.setDescriptorValue(new byte[]{1});
list.add(profile2); final ServiceSettings serviceSettings = new ServiceSettings.Builder()
.setServiceUuid(UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb"))//服务uuid
.setServiceType(BluetoothGattService.SERVICE_TYPE_PRIMARY)
.addServiceProfiles(list)//上述设置添加到该服务里
.build(); mGattServer.addService(serviceSettings);

回调监听

        mGattServer.setOnAdvertiseListener(new OnAdvertiseListener() {
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
setContentText("开启广播 成功,uuid:0000fff0-0000-1000-8000-00805f9b34fb");
} @Override
public void onStartFailure(int errorCode) {
setContentText("开启广播 失败,uuid:0000fff0-0000-1000-8000-00805f9b34fb");
} @Override
public void onStopAdvertising() {
setContentText("停止广播,uuid:0000fff0-0000-1000-8000-00805f9b34fb");
}
}); mGattServer.setOnServiceAddedListener(new OnServiceAddedListener() {
@Override
public void onSuccess(BluetoothGattService service) {
setContentText("添加服务成功!");
} @Override
public void onFail(BluetoothGattService service) {
setContentText("添加服务失败");
}
}); mGattServer.setOnConnectionStateChangeListener(new OnConnectionStateChangeListener() {
@Override
public void onChange(BluetoothDevice device, int status, int newState) { } @Override
public void onConnected(BluetoothDevice device) {
setContentText("连接上一台设备 :{ name = " + device.getName() + ", address = " + device.getAddress() + "}");
mBluetoothDevice = device;
} @Override
public void onDisconnected(BluetoothDevice device) {
setContentText("设备断开连接 :{ name = " + device.getName() + ", address = " + device.getAddress() + "}");
}
}); mGattServer.setOnWriteRequestListener(new OnWriteRequestListener() {
@Override
public void onCharacteristicWritten(BluetoothDevice device, BluetoothGattCharacteristic characteristic, byte[] value) {
setContentText("设备写入特征请求 : device = " + device.getAddress() + ", characteristic uuid = " + characteristic.getUuid().toString() + ", value = " + Arrays.toString(value));
} @Override
public void onDescriptorWritten(BluetoothDevice device, BluetoothGattDescriptor descriptor, byte[] value) {
setContentText("设备写入描述请求 : device = " + device.getAddress() + ", descriptor uuid = " + descriptor.getUuid().toString() + ", value = " + Arrays.toString(value));
}
});

Download

dependencies {
compile 'will be come soon..'
}

BluetoothLE-Multi-Library的更多相关文章

  1. BIOS MCSDK 2.0 学习笔记(二)————使用Platform Library创建工程

    [TOC] Platform Library提供了一组适用于开发板的API函数.我们可以使用它来快速入手开发板. 1.启动CCS,建立一个空的工程 2.添加include路径 "C:\Pro ...

  2. library cache lock和cursor: pin S wait on X等待

    1.现象: 客户10.2.0.4 RAC环境,出现大量的library cache lock和cursor: pin S wait on X等待,经分析是由于统计信息收集僵死导致的.数据库在8点到9点 ...

  3. Save results to different files when executing multi SQL statements in DB Query Analyzer 7.01

        1 About DB Query Analyzer DB Query Analyzer is presented by Master Genfeng,Ma from Chinese Mainl ...

  4. Multi-Targeting and Porting a .NET Library to .NET Core 2.0

    Creating a new .NET Standard Project The first step for moving this library is to create a new .NET ...

  5. library Makefiles

    libpng library Makefile LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LS_C=$(subst $(1)/,,$(wild ...

  6. Intro to Jedis – the Java Redis Client Library

    转自:http://www.baeldung.com/jedis-java-redis-client-library 1. Overview This article is an introducti ...

  7. Online handwriting recognition using multi convolution neural networks

    w可以考虑从计算机的“机械性.重复性”特征去设计“低效的”算法. https://www.codeproject.com/articles/523074/webcontrols/ Online han ...

  8. rac数据库默认sql tuning advisor,导致大量library cache lock

    rac数据库默认sql tuning advisor,导致大量library cache lock 问题现象:客户反映周六周日固定十点钟,一个程序会特别慢(大概10分钟),平时1到2秒.查看当时的日志 ...

  9. DYNAMIC LINK LIBRARY - DLL

    https://www.tenouk.com/ModuleBB.html MODULE BB DYNAMIC LINK LIBRARY - DLL Part 1: STORY What do we h ...

  10. 记一个mvn奇怪错误: Archive for required library: 'D:/mvn/repos/junit/junit/3.8.1/junit-3.8.1.jar' in project 'xxx' cannot be read or is not a valid ZIP file

    我的maven 项目有一个红色感叹号, 而且Problems 存在 errors : Description Resource Path Location Type Archive for requi ...

随机推荐

  1. Ext grid单元格编辑时获取获取Ext.grid.column.Column

    item2.width = 80; //item2.flex = 1; item2.align = 'center'; item2.menuDisabled = true; //禁止显示列头部右侧菜单 ...

  2. Java Static Import的用法

    在头部使用的imoirt static ***方式叫做静态引入,在Java SE 1.5.0(JDK 5)引入的特性. 官方文档的介绍: 为了访问静态成员,有必要限定它们来自的类的引用.例如,必须这样 ...

  3. BT原理分析(转)

    BT种子文件结构分析,参考:http://www.cnblogs.com/EasonJim/p/6601047.html BT下载,参考:http://baike.baidu.com/item/BT下 ...

  4. linux下安装程序(dep/tgz/rpm)

    1.tgz本身就是压缩包,所以前提是先解压出来 tar zxvf test.tgz 而对于安装,可以是程序包本身包含安装,也可以是通过特定shell脚本运行,毕竟这个是不安装包,而只是压缩包. 2.d ...

  5. ChsLLVMDocs

    https://github.com/wuye9036/ChsLLVMDocs/blob/master/CodeGen.md

  6. 邁向IT專家成功之路的三十則鐵律 鐵律二十:IT人證照之道-收斂

    這是一個各行各業都講究專業證照的世代,彷彿證照只要比別人少一些就感覺自己遜掉了.現今IT領域的證照肯定是所有行業中最複雜的,無論是想求職升遷的還是想轉進IT跑道的,許多人由於受到媒體與廣告的影響,都不 ...

  7. 邁向IT專家成功之路的三十則鐵律 鐵律十二:IT人養生之道-德行

    所謂的「養生」在中國古代裡所指的是針對內在精神層面修為的提升,到了近代中醫所謂的養生,則除了包含最根本的內在精神層面之外,還涵蓋了外在身體的養護.在現今各行各業的人士當中,嚴格來說都應該要有一套專屬的 ...

  8. 如何让你的服务屏蔽Shodan扫描

    1. 前言 在互联网中,充斥着各种各样的网络设备,shodan等搜索引擎提供给了我们一个接口,让我们可以在输入一些过滤条件就可以检索出网络中相关的设备. 对于我们的一些可能有脆弱性或者比较隐私的服务, ...

  9. iOS集成百度地图方法步骤

    前言:app中的导航功能越来越流行,现在我自己做的项目中也有此需求,做过了后记录下笔记.  由于源代码保密所以这里仅仅提供demo,下面是效果图 一:iOS地图SDK 1.打开 百度地图api链接 i ...

  10. Aws Dynamodb数据导出到S3

    本节将描写叙述怎样从一个或多个DynamoDB的表导出数据到S3的bucket中.在运行导出之前你须要提前创建好S3的bucket. 注意 假设你还没有使用过AWS Data Pipeline,在运行 ...