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. sql-server-next-version-ctp-1-4-now-available

    https://blogs.technet.microsoft.com/dataplatforminsider/2017/03/17/sql-server-next-version-ctp-1-4-n ...

  2. asyncTask 的execute和executeOnExecutor 方法

    asyncTask.execute Android.os.Build.VERSION_CODES.DONUT, this was changed to a pool of threads allowi ...

  3. 45个非常有用的Oracle查询语句(转自开源中国社区)

    日期/时间 相关查询 获取当前月份的第一天 运行这个命令能快速返回当前月份的第一天.你可以用任何的日期值替换 “SYSDATE”来指定查询的日期. SELECT TRUNC (SYSDATE, 'MO ...

  4. linux删除空行操作:awk、grep、tr、sed

    如下:如何删除空行 shen\nshen\\n sen seh sehe she she 真正删除空行,可以使用vim: 通过命令模式删除空行.vim在命令模式下(在vim里输入英文字符:进入命令模式 ...

  5. 转: 浅析Fusion-IO和Intel SSD

    from: http://alanwu.blog.51cto.com/3652632/865235 标签:SSD 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否 ...

  6. python(25)- 面向对象补充Ⅰ

    一.如何使用类 1.实例化:创建对象 类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征. 例子一 x=int(10) print(x) python中一切 ...

  7. Spring Boot中使用RSocket

    1. 概述 RSocket应用层协议支持 Reactive Streams语义, 例如:用RSocket作为HTTP的一种替代方案.在本教程中, 我们将看到RSocket用在spring boot中, ...

  8. bootstrap table api

    http://blog.csdn.net/rickiyeat/article/details/56483577

  9. Unity3D 调用Java,Java调用Unity3D

    1.无返回值 AndroidJavaClass fee = new AndroidJavaClass("com.wiker.Test"); fee.CallStatic(" ...

  10. lua 字符串处理

    匹配模式(pattern) . 任何单个字符 %a 任何字母 %c 任何控制字符 %d 任何数字 %g 任何除空白符外的可打印字符 %l 所有小写字母 %p 所有标点符号 %s 所有空白字符 %u 所 ...