The company is going to do a Bluetooth project. The demand for Bluetooth is to connect medical devices with Bluetooth. After the data is measured by the device, it will be sent to the mobile phone/tablet through Bluetooth. The time is limited, so I found a Bluetooth open source library on GitHub, and it works well.
Address: https://github.com/Jasonchenlijian/FastBle/wiki
Since there are only library files and calling codes, so I wrote a Bluetooth tool library myself, which contains various calling methods of Bluetooth
package com.dhy.health.blefast;
import android.app.Activity;
import android.app.Application;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Context;
import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleGattCallback;
import com.clj.fastble.callback.BleIndicateCallback;
import com.clj.fastble.callback.BleMtuChangedCallback;
import com.clj.fastble.callback.BleNotifyCallback;
import com.clj.fastble.callback.BleReadCallback;
import com.clj.fastble.callback.BleRssiCallback;
import com.clj.fastble.callback.BleScanAndConnectCallback;
import com.clj.fastble.callback.BleScanCallback;
import com.clj.fastble.callback.BleWriteCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.clj.fastble.scan.BleScanRuleConfig;
import java.util.List;
import java.util.UUID;
/**
* Created by Forrest.
* User: Administrator:ZYJ
* Date: 2020/11/25
* Description:蓝牙管理工具类
*/
public class BLEFastUtils {
private OnScanListener scanlistener;
private OnConnectListener connectListener;
private OnDataChangeListener dataChangeListener;
public void setOnDataChangeCallBack(OnScanListener scanlistener,OnConnectListener connectListener,OnDataChangeListener dataChangeListener) {
this.scanlistener = scanlistener;
this.connectListener = connectListener;
this.dataChangeListener = dataChangeListener;
}
//扫描蓝牙返回接口
public interface OnScanListener{
void onScanStarted(boolean success);//蓝牙搜索中
void onScanning(BleDevice bleDevice);
void onScanFinished(List<BleDevice> scanResultList);
}
//连接蓝牙返回接口
public interface OnConnectListener{
void onStartConnect();
void onConnectFail(BleDevice bleDevice, BleException exception);
void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status);
void onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status);
}
//数据返回接口
public interface OnDataChangeListener {
void onNotifySuccess();
void onNotifyFailure(BleException exception);
void onCharacteristicChanged(byte[] data);
}
/**
* 初始化和全局配置,写在application里面
*/
public void Initialization() {
//初始化
// BleManager.getInstance().init(application);
//扫描全局配置
BleManager.getInstance()
.enableLog(true)//默认打开库中的运行日志,如果不喜欢可以关闭
.setReConnectCount(1, 5000)//设置连接时重连次数和重连间隔(毫秒),默认为0次不重连
.setSplitWriteNum(20)//设置分包发送的时候,每一包的数据长度,默认20个字节
.setConnectOverTime(10000)//设置连接超时时间(毫秒),默认10秒
.setOperateTimeout(5000);//设置readRssi、setMtu、write、read、notify、indicate的超时时间(毫秒),默认5秒
}
/**
* 扫描配置
* - 在扫描设备之前,可以配置扫描规则,筛选出与程序匹配的设备
* - 不配置的话均为默认参数
* - 在2.1.2版本及之前,必须先配置过滤规则再扫描;在2.1.3版本之后可以无需配置,开启默认过滤规则的扫描。
*/
public void initScanRule(UUID[] service_uuid, String ble_name, String mac, boolean isAutoConnect) {
BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder()
.setServiceUuids(service_uuid) // 只扫描指定的服务的设备,可选
.setDeviceName(true, ble_name) // 只扫描指定广播名的设备,可选
// .setDeviceMac(mac) // 只扫描指定mac的设备,可选
// .setAutoConnect(isAutoConnect) // 连接时的autoConnect参数,可选,默认false
.setScanTimeOut(10000) // 扫描超时时间,可选,默认10秒;小于等于0表示不限制扫描时间
.build();
BleManager.getInstance().initScanRule(scanRuleConfig);
}
/**
* 开始扫描
* - 扫描及过滤过程是在工作线程中进行,所以不会影响主线程的UI操作,最终每一个回调结果都会回到主线程。
*/
public void startScan() {
BleManager.getInstance().scan(new BleScanCallback() {
@Override
public void onScanStarted(boolean success) {
// 开始扫描(主线程)
scanlistener.onScanStarted(success);
}
@Override
public void onScanning(BleDevice bleDevice) {
// 扫描到一个符合扫描规则的BLE设备(主线程)
scanlistener.onScanning(bleDevice);
}
@Override
public void onScanFinished(List<BleDevice> scanResultList) {
// 扫描结束,列出所有扫描到的符合扫描规则的BLE设备(主线程)
scanlistener.onScanFinished(scanResultList);
}
});
}
/**
* 通过扫描到的BleDevice对象进行连接。
* - 在某些型号手机上,connectGatt必须在主线程才能有效。非常建议把连接过程放在主线程。
* - 连接失败后重连:框架中包含连接失败后的重连机制,可以配置重连次数和时间间隔。当然也可以自行在`onConnectFail`回调方法中延时调用`connect`方法。
* - 连接断开后重连:可以在`onDisConnected`回调方法中再次调用`connect`方法。
* - 为保证重连成功率,建议断开后间隔一段时间之后进行重连。
* - 某些机型上连接失败后会短暂地无法扫描到设备,可以通过设备对象或设备mac直连,而不经过扫描。
*/
public void connectDevice(BleDevice bleDevice) {
BleManager.getInstance().connect(bleDevice, new BleGattCallback() {
@Override
public void onStartConnect() {
// 开始连接
connectListener.onStartConnect();
}
@Override
public void onConnectFail(BleDevice bleDevice, BleException exception) {
// 连接失败
connectListener.onConnectFail(bleDevice,exception);
}
@Override
public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
// 连接成功,BleDevice即为所连接的BLE设备
connectListener.onConnectSuccess(bleDevice,gatt,status);
}
@Override
public void onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status) {
// 连接中断,isActiveDisConnected表示是否是主动调用了断开连接方法
connectListener.onDisConnected(isActiveDisConnected,bleDevice,gatt,status);
}
});
}
/**
* 通过Mac连接蓝牙
* Tips:
* - 此方法可以不经过扫描,尝试直接连接周围复合该Mac的BLE设备。
* - 在很多使用场景,我建议APP保存用户惯用设备的Mac,然后使用该方法进行连接可以大大提高连接效率。
*/
public void connectMac(String mac) {
BleManager.getInstance().connect(mac, new BleGattCallback() {
@Override
public void onStartConnect() {
// 开始连接
}
@Override
public void onConnectFail(BleDevice bleDevice, BleException exception) {
// 连接失败
}
@Override
public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
// 连接成功,BleDevice即为所连接的BLE设备
}
@Override
public void onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status) {
// 连接中断,isActiveDisConnected表示是否是主动调用了断开连接方法
}
});
}
/**
* 扫描并连接
* 扫描到首个符合扫描规则的设备后,便停止扫描,然后连接该设备。
* Tips:
* - 扫描及过滤过程是在工作线程中进行,所以不会影响主线程的UI操作,但每一个回调结果都会回到主线程。 连接操作会在主线中进行。
*/
public void scanConnect(BleScanAndConnectCallback callback) {
BleManager.getInstance().scanAndConnect(new BleScanAndConnectCallback() {
@Override
public void onScanStarted(boolean success) {
// 开始扫描(主线程)
}
@Override
public void onScanning(BleDevice bleDevice) {
// 扫描到一个符合扫描规则的BLE设备(主线程)
}
@Override
public void onScanFinished(BleDevice scanResult) {
// 扫描结束,结果即为扫描到的第一个符合扫描规则的BLE设备,如果为空表示未搜索到(主线程)
}
@Override
public void onStartConnect() {
// 开始连接(主线程)
}
@Override
public void onConnectFail(BleDevice bleDevice, BleException exception) {
// 连接失败(主线程)
}
@Override
public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
// 连接成功,BleDevice即为所连接的BLE设备(主线程)
}
@Override
public void onDisConnected(boolean isActiveDisConnected, BleDevice device, BluetoothGatt gatt, int status) {
// 连接断开,isActiveDisConnected是主动断开还是被动断开(主线程)
}
});
}
/**
* 扫描过程中,中止扫描操作
* Tips:
* - 调用该方法后,如果当前还处在扫描状态,会立即结束,并回调`onScanFinished`方法。
*/
public void stopScan() {
BleManager.getInstance().cancelScan();
}
/**
* 订阅通知notify
*/
public void notify(BleDevice bleDevice, String uuid_service, String uuid_characteristic_notify) {
BleManager.getInstance().notify(
bleDevice,
uuid_service,
uuid_characteristic_notify,
new BleNotifyCallback() {
@Override
public void onNotifySuccess() {
// 打开通知操作成功
dataChangeListener.onNotifySuccess();
}
@Override
public void onNotifyFailure(BleException exception) {
// 打开通知操作失败
dataChangeListener.onNotifyFailure(exception);
}
@Override
public void onCharacteristicChanged(byte[] data) {
// 打开通知后,设备发过来的数据将在这里出现
dataChangeListener.onCharacteristicChanged(data);
}
});
}
/**
* 取消订阅通知notify,并移除数据接收的回调监听
*/
public void stopNotify(BleDevice bleDevice, String uuid_service, String uuid_characteristic_notify) {
BleManager.getInstance().stopNotify(bleDevice, uuid_service, uuid_characteristic_notify);
}
/**
* 订阅通知indicate
*/
public void indicate(BleDevice bleDevice, String uuid_service, String uuid_characteristic_indicate) {
BleManager.getInstance().indicate(
bleDevice,
uuid_service,
uuid_characteristic_indicate,
new BleIndicateCallback() {
@Override
public void onIndicateSuccess() {
// 打开通知操作成功
}
@Override
public void onIndicateFailure(BleException exception) {
// 打开通知操作失败
}
@Override
public void onCharacteristicChanged(byte[] data) {
// 打开通知后,设备发过来的数据将在这里出现
}
});
}
/**
* 取消订阅通知indicate,并移除数据接收的回调监听
*/
public void stopIndicate(BleDevice bleDevice, String uuid_service, String uuid_characteristic_indicate) {
BleManager.getInstance().stopIndicate(bleDevice, uuid_service, uuid_characteristic_indicate);
}
/**
* 向蓝牙写入数据
* Tips:
* - 在没有扩大MTU及扩大MTU无效的情况下,当遇到超过20字节的长数据需要发送的时候,需要进行分包。参数`boolean split`表示是否使用分包发送;无`boolean split`参数的`write`方法默认对超过20字节的数据进行分包发送。
* - 关于`onWriteSuccess`回调方法: `current`表示当前发送第几包数据,`total`表示本次总共多少包数据,`justWrite`表示刚刚发送成功的数据包。
* - 对于分包发送的辅助策略,可以选择发送上一包数据成功之后发送下一包,或直接发送下一包,参数`sendNextWhenLastSuccess`表示是否待收到`onWriteSuccess`之后再进行下一包的发送。默认true。
* - 参数`intervalBetweenTwoPackage`表示延时多长时间发送下一包,单位ms,默认0。
*/
public void write(BleDevice bleDevice, String uuid_service, String uuid_characteristic_write, byte[] data) {
BleManager.getInstance().write(
bleDevice,
uuid_service,
uuid_characteristic_write,
data,
new BleWriteCallback() {
@Override
public void onWriteSuccess(int current, int total, byte[] justWrite) {
// 发送数据到设备成功
}
@Override
public void onWriteFailure(BleException exception) {
// 发送数据到设备失败
}
});
}
/**
* 读取蓝牙数据
*/
public void read(BleDevice bleDevice, String uuid_service, String uuid_characteristic_read, BleReadCallback callback) {
BleManager.getInstance().read(
bleDevice,
uuid_service,
uuid_characteristic_read,
new BleReadCallback() {
@Override
public void onReadSuccess(byte[] data) {
// 读特征值数据成功
}
@Override
public void onReadFailure(BleException exception) {
// 读特征值数据失败
}
});
}
/**
* 获取设备的信号强度Rssi
* 获取设备的信号强度,需要在设备连接之后进行。
* 某些设备可能无法读取Rssi,不会回调onRssiSuccess(),而会因为超时而回调onRssiFailure()。
*/
public void readRssi(BleDevice bleDevice) {
BleManager.getInstance().readRssi(
bleDevice,
new BleRssiCallback() {
@Override
public void onRssiFailure(BleException exception) {
// 读取设备的信号强度失败
}
@Override
public void onRssiSuccess(int rssi) {
// 读取设备的信号强度成功
}
});
}
/**
* 设置最大传输单元MTU
* Tips:
* 设置MTU,需要在设备连接之后进行操作。
* 默认每一个BLE设备都必须支持的MTU为23。
* MTU为23,表示最多可以发送20个字节的数据。
* 在Android 低版本(API-17 到 API-20)上,没有这个限制。所以只有在API21以上的设备,才会有拓展MTU这个需求。
* 该方法的参数mtu,最小设置为23,最大设置为512。
* 并不是每台设备都支持拓展MTU,需要通讯双方都支持才行,也就是说,需要设备硬件也支持拓展MTU该方法才会起效果。调用该方法后,可以通过onMtuChanged(int mtu)查看最终设置完后,设备的最大传输单元被拓展到多少。如果设备不支持,可能无论设置多少,最终的mtu还是23。
* */
public void setMtu(BleDevice bleDevice, int mtu, BleMtuChangedCallback callback) {
BleManager.getInstance().setMtu(bleDevice, mtu, new BleMtuChangedCallback() {
@Override
public void onSetMTUFailure(BleException exception) {
// 设置MTU失败
}
@Override
public void onMtuChanged(int mtu) {
// 设置MTU成功,并获得当前设备传输支持的MTU值
}
});
}
/**
* 断开某个设备
* */
public void disconnect(BleDevice bleDevice){
BleManager.getInstance().disconnect(bleDevice);
}
/**
* 断开所有设备
* */
public void disconnectAllDevice(){
BleManager.getInstance().disconnectAllDevice();
}
/**
* 退出使用,清理资源
* */
public void destroy(){
BleManager.getInstance().destroy();
}
/**
* 判断某个设备是否已连接bleDevice
* */
public boolean isConnectedBleDevice(BleDevice bleDevice){
return BleManager.getInstance().isConnected(bleDevice);
}
/**
* 判断某个设备是否已连接mac
* */
public boolean isConnectedMac(String mac){
return BleManager.getInstance().isConnected(mac);
}
/**
* 判断某个设备的当前连接状态
* */
public int getConnectState(BleDevice bleDevice){
return BleManager.getInstance().getConnectState(bleDevice);
}
/**
* 获取所有已连接设备
* */
public List<BleDevice> getAllConnectedDevice(){
return BleManager.getInstance().getAllConnectedDevice();
}
/**
* 获取某个已连接设备的所有Service
* */
public List<BluetoothGattService> getBluetoothGattServices(BleDevice bleDevice){
return BleManager.getInstance().getBluetoothGattServices(bleDevice);
}
/**
*获取某个Service的所有Characteristic
* */
public List<BluetoothGattCharacteristic> getBluetoothGattCharacteristics(BluetoothGattService service){
return BleManager.getInstance().getBluetoothGattCharacteristics(service);
}
/**
* 获取某个已连接设备的BluetoothGatt
* */
public BluetoothGatt getBluetoothGatt(BleDevice bleDevice){
return BleManager.getInstance().getBluetoothGatt(bleDevice);
}
}
call method
package com.dhy.health.blefast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattService;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleGattCallback;
import com.clj.fastble.callback.BleNotifyCallback;
import com.clj.fastble.callback.BleScanCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.clj.fastble.scan.BleScanRuleConfig;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private String blename = "Bene";
private String service_uuid = "";
private String char_uuid = "";
private Button mSaomiao;
private Button mTzsaomiao;
private BLEFastUtils bleFastUtils;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//蓝牙初始化配置
BleManager.getInstance().init((Application) getApplicationContext());
//扫描全局配置
BleManager.getInstance()
.enableLog(true)//默认打开库中的运行日志,如果不喜欢可以关闭
.setReConnectCount(1, 5000)//设置连接时重连次数和重连间隔(毫秒),默认为0次不重连
.setSplitWriteNum(20)//设置分包发送的时候,每一包的数据长度,默认20个字节
.setConnectOverTime(10000)//设置连接超时时间(毫秒),默认10秒
.setOperateTimeout(5000);//设置readRssi、setMtu、write、read、notify、indicate的超时时间(毫秒),默认5秒
mSaomiao = findViewById(R.id.saomiao);
mTzsaomiao=findViewById(R.id.tzsaomiao);
mSaomiao.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//扫描
bleFastUtils.startScan();
}
});
setPermissions();
bleFastUtils = new BLEFastUtils();
bleFastUtils.setOnDataChangeCallBack(
// TODO 扫描返回接口
new BLEFastUtils.OnScanListener() {
@Override
public void onScanStarted(boolean success) {
// 开始扫描(主线程)
Log.e("onScanStarted", "" + success);
}
@Override
public void onScanning(BleDevice bleDevice) {
Log.e("onScanning", "" + bleDevice.getName());
// 扫描到一个符合扫描规则的BLE设备(主线程)
if (bleDevice.getName() != null) {
if (bleDevice.getName().contains(blename)) {
Log.e("onScanStopScan", "停止扫描");
bleFastUtils.stopScan();
}
}
}
@Override
public void onScanFinished(List<BleDevice> scanResultList) {
// 扫描结束,列出所有扫描到的符合扫描规则的BLE设备(主线程)
for (int i = 0; i < scanResultList.size(); i++) {
if (scanResultList.get(i).getName() != null) {
Log.e("onScanFinished", "" + scanResultList.get(i).getName());
if (scanResultList.get(i).getName().contains(blename)) {
Log.e("onScanFinished", "" + scanResultList.get(i).getMac());
bleFastUtils.connectDevice(scanResultList.get(i));
Log.e("onScanFinished2", "" + scanResultList.get(i).getMac());
}
}
}
}
}
//TODO 连接返回接口
, new BLEFastUtils.OnConnectListener() {
@Override
public void onStartConnect() {
//开始连接
Log.e("onScan开始连接", "1");
}
@Override
public void onConnectFail(BleDevice bleDevice, BleException exception) {
// 连接失败
Log.e("onScan连接失败", "2");
}
@Override
public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
// 连接成功,BleDevice即为所连接的BLE设备
Log.e("onScan连接成功", "3" + gatt.getServices().get(0).getUuid());
for (BluetoothGattService s : gatt.getServices()) {
Log.e("onScan连接成功1", "31" + s.getUuid().toString());
}
bleFastUtils.notify(bleDevice, service_uuid, char_uuid);
}
@Override
public void onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status) {
// 连接中断,isActiveDisConnected表示是否是主动调用了断开连接方法
Log.e("onScan连接中断", "4");
gatt.close();
}
}
//TODO 数据传输返回接口
, new BLEFastUtils.OnDataChangeListener() {
@Override
public void onNotifySuccess() {
// 打开通知操作成功
Log.e("onScan订阅成功", "1");
}
@Override
public void onNotifyFailure(BleException exception) {
// 打开通知操作失败
Log.e("onScan订阅失败", "2*" + exception.getCode() + exception.getDescription());
}
@Override
public void onCharacteristicChanged(final byte[] data) {
// 打开通知后,设备发过来的数据将在这里出现
Log.e("onScan接收数据", "3" + data);
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for (byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
Log.e(TAG, "new string -->" + new String(data) + "\n" + stringBuilder.toString());
displayData(new String(data) + "\n" + stringBuilder.toString());
}
}
});
}
public void saomiao() {
BleManager.getInstance().scan(new BleScanCallback() {
@Override
public void onScanStarted(boolean success) {
// 开始扫描(主线程)
Log.e("onScanStarted", "" + success);
}
@Override
public void onScanning(BleDevice bleDevice) {
// 扫描到一个符合扫描规则的BLE设备(主线程)
if (bleDevice.getName() != null) {
Log.e("onScanning", "" + bleDevice.getName());
if (bleDevice.getName().contains(blename)) {
BleManager.getInstance().cancelScan();
}
}
}
@Override
public void onScanFinished(List<BleDevice> scanResultList) {
// 扫描结束,列出所有扫描到的符合扫描规则的BLE设备(主线程)
for (int i = 0; i < scanResultList.size(); i++) {
if (scanResultList.get(i).getName() != null) {
Log.e("onScanFinished", "" + scanResultList.get(i).getName());
if (scanResultList.get(i).getName().contains(blename)) {
Log.e("onScanFinished", "" + scanResultList.get(i).getMac());
setLianjie(scanResultList.get(i));
Log.e("onScanFinished2", "" + scanResultList.get(i).getMac());
}
}
}
}
});
}
public void setLianjie(final BleDevice mac) {
Log.e("onScan进入链接", "" + mac);
// BleManager.getInstance().connect(mac, new BleGattCallback() {
// @Override
// public void onStartConnect() {
// Log.e("onScan连接开始","");
// // 开始连接
// }
//
// @Override
// public void onConnectFail(BleDevice bleDevice, BleException exception) {
// // 连接失败
// Log.e("onScan连接失败","");
// }
//
// @Override
// public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
// // 连接成功,BleDevice即为所连接的BLE设备
// Log.e("onScan连接成功","");
// }
//
// @Override
// public void onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status) {
// // 连接中断,isActiveDisConnected表示是否是主动调用了断开连接方法
// Log.e("onScan连接中断","");
// }
// });
BleManager.getInstance().connect(mac, new BleGattCallback() {
@Override
public void onStartConnect() {
// 开始连接
Log.e("onScan连接开始", "1");
}
@Override
public void onConnectFail(BleDevice bleDevice, BleException exception) {
// 连接失败
Log.e("onScan连接失败", "2");
}
@Override
public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
// 连接成功,BleDevice即为所连接的BLE设备
Log.e("onScan连接成功", "3");
setDingyue(mac, service_uuid, char_uuid);
}
@Override
public void onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status) {
// 连接中断,isActiveDisConnected表示是否是主动调用了断开连接方法
Log.e("onScan连接中断", "4");
}
});
}
//dingyue
public void setDingyue(BleDevice bleDevice, String uuid_service, String uuid_characteristic_notify) {
BleManager.getInstance().notify(
bleDevice,
uuid_service,
uuid_characteristic_notify,
new BleNotifyCallback() {
@Override
public void onNotifySuccess() {
// 打开通知操作成功
Log.e("onScan订阅成功", "1");
}
@Override
public void onNotifyFailure(BleException exception) {
// 打开通知操作失败
Log.e("onScan订阅失败", "2");
}
@Override
public void onCharacteristicChanged(byte[] data) {
// 打开通知后,设备发过来的数据将在这里出现
Log.e("onScan接收数据", "3" + data);
setJiexishuju(data);
}
});
}
StringBuilder sb = new StringBuilder();
public void setJiexishuju(final byte[] data) {
try {
int length = data.length;
final String tmpValue = new String(data, "UTF-8");
runOnUiThread(new Runnable() {
@Override
public void run() {
//拼接data
sb.append(Bytes2HexString(data));
Log.e("MainActivity", "sb=" + sb);
//如果sb没拼接到结束符就继续往下走,拼接到了就停止拼接,然后根据ODOA分割成若干部分
if (sb.toString().contains("0D0A0D0A0D0A")) {
String line = sb.toString();
String[] leu = line.split("0D0A");
for (int i = 0; i < leu.length; i++) {
System.out.println("1MainActivity" + i + "=" + leu[i]);//43484F4C3A3C3130306D672F644C
System.out.println("2MainActivity" + i + "=" + hexStringToString(leu[i]));//CHOL:<100mg/dL
}
sb = new StringBuilder();
}
}
});
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* byte[] 转为16进制String
*
* @param b
*/
public static String Bytes2HexString(byte[] b) {
String ret = "";
for (int i = 0; i < b.length; i++) {
String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
ret += hex.toUpperCase();
}
return ret;
}
/**
* 16进制转换成为string类型字符串
*
* @param s
* @return
*/
public static String hexStringToString(String s) {
if (s == null || s.equals("")) {
return null;
}
s = s.replace(" ", "");
byte[] baKeyword = new byte[s.length() / 2];
for (int i = 0; i < baKeyword.length; i++) {
try {
baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
} catch (Exception e) {
e.printStackTrace();
}
}
try {
s = new String(baKeyword, "UTF-8");
new String();
} catch (Exception e1) {
e1.printStackTrace();
}
return s;
}
/**
* get measure result
* "2.0" above protocol "03" package length:12
* "1.0" protocol "03" package length:14
*
* @param data received package data
*/
private void showContent(byte[] data) {
if (null == data) return;
byte index0 = data[0];
if (index0 != 85) return;
byte index2 = data[2];
if (index2 == 3) {//Device upload results
byte index3 = data[3];//Year
byte index4 = data[4];//Month
byte index5 = data[5];//Day
byte index6 = data[6];//Hour
byte index7 = data[7];//Minute
byte[] valueArr = {data[10], data[9]};
//10+9 Convert to decimal,And then divide by 100,get the temperature
String strValue = ZHexUtil.encodeHexStr(valueArr);
int value = Integer.valueOf(strValue, 16);
//跟体温计结果显示保持一致:丢弃小数点后第二位
String valueStr = StringUtil.formatTo1ROUNDDOWN((double) value / 100);
// tvTwNum.setText("" + valueStr);
Log.e("onScan得到的数据是", "value --" + valueStr);
} else if (index2 == 5) {
//收到测量结束包
}
}
private void displayData(String data) {
if (data != null) {
int index = data.indexOf("24 50 43 4C 41");
if (index != -1) {
// isShowData = true;
String str = data.substring(data.indexOf("24 50 43 4C 41"));
Log.e(TAG, "截取: " + str);
String[] strArray = str.toString().split(" ");
String data1 = strArray[strArray.length - 2];
String data2 = strArray[strArray.length - 3];
Log.e(TAG, "data1 = " + data1 + "\ndata2 = " + data2);
String hexData = data1 + data2;
Log.e(TAG, "hexData = " + hexData);
float resultFloat = ((float) Integer.valueOf(hexData, 16)) / 18;
BigDecimal b = new BigDecimal(resultFloat); // 四舍五入
final float resultFloat2 = b.setScale(1, BigDecimal.ROUND_HALF_UP).floatValue();
Log.i(TAG, "血糖值是 = " + resultFloat2);
// mDataField.setText(String.valueOf(resultFloat2));
// if (listener != null)
// listener.onBloodSugarData(resultFloat2 + "");//血糖
}
int index2 = data.indexOf("24 50 43 4C 51");
if (index2 != -1) {
// isShowData = true;
String str = data.substring(data.indexOf("24 50 43 4C 51"));
String[] strArray = str.toString().split(" ");
String data1 = strArray[strArray.length - 2];
String data2 = strArray[strArray.length - 3];
String hexData = data1 + data2;
float resultFloat = ((float) Integer.valueOf(hexData, 16)) / (float) 168.1;
BigDecimal b = new BigDecimal(resultFloat); // 四舍五入
final float resultFloat2 = b.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
Log.i(TAG, "尿酸值是 = " + resultFloat2);
// mDataField.setText(String.valueOf(resultFloat2));
// if (listener != null)
// listener.onUricAcidData(resultFloat2 + ""); //尿酸
}
int index3 = data.indexOf("24 50 43 4C 61");
if (index3 != -1) {
// isShowData = true;
String str = data.substring(data.indexOf("24 50 43 4C 61"));
String[] strArray = str.toString().split(" ");
String data1 = strArray[strArray.length - 2];
String data2 = strArray[strArray.length - 3];
String hexData = data1 + data2;
float resultFloat = ((float) Integer.valueOf(hexData, 16)) / (float) 38.66;
BigDecimal b = new BigDecimal(resultFloat); // 四舍五入
final float resultFloat2 = b.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
Log.i(TAG, "胆固醇值是 = " + resultFloat2);
// mDataField.setText(String.valueOf(resultFloat2));
// if (listener != null)
// listener.onCholesterolData(resultFloat2 + ""); //胆固醇
}
}
}
/**
* set location permission, open bluetooth
* 设置权限(定位权限),打开蓝牙
*/
private void setPermissions() {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {//未开启定位权限
//开启定位权限
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}
, 0);
} else {
//申请蓝牙权限
if (mBluetoothAdapter == null) {
Toast.makeText(MainActivity.this, "" +
"this is not support bluetooth", Toast.LENGTH_LONG).show();
} else if (!mBluetoothAdapter.isEnabled()) {
//启动蓝牙
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
/**
* 定位权限后的回调
*/
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 0:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//申请蓝牙权限
if (mBluetoothAdapter == null) {
Toast.makeText(MainActivity.this, "this is not support bluetooth", Toast.LENGTH_LONG).show();
} else if (!mBluetoothAdapter.isEnabled()) {
//启动蓝牙
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
break;
}
}
}
Don't forget to add bluetooth related permissions
I'm pushing another one, haven't tried this one yet