Commit 8d79fc34 authored by 18600395998's avatar 18600395998

添加 Android 原生蓝牙库,并在原生蓝牙处实现

parent d5948155
......@@ -71,5 +71,8 @@ flutter {
}
dependencies {
implementation files('libs/uhf.jar')
implementation files('libs/uhf.jar')
//蓝牙4.0第三方库
implementation 'cn.wandersnail:easyble-x:1.4.4'
implementation 'cn.wandersnail:commons-android:1.3.5'
}
......@@ -111,6 +111,11 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service
android:name=".ble.BleService"
android:enabled="true"
android:exported="true" />
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
......
......@@ -53,12 +53,15 @@ public class ConnectManger {
*/
public String getRm70xxVersion() {
if (connectManger.getBoardSerialNumber() == 0) {
if (connectManger.getBoardSoftVersion() == 0) {
if (connectManger.getSoftwareVersion() == 0) {
if (connectManger.getHardwareVersion() == 0) {
if (getBoardSerialNumber() == 0) {
if (getBoardSoftVersion() == 0) {
if (getSoftwareVersion() == 0) {
if (getHardwareVersion() == 0) {
Log.e("lei", "getRm70xxVersion: "+String.format("设备连接:%s" + "\n软件版本:%s" + "\n硬件版本:%s" + "\n设备软件版本:%s" + "\n设备硬件版本:%s", "蓝牙已连接",
RM70XX_VERSION, RM70XX_SERIAL_VERSION, VERSION, SERIAL_VERSION));
if (!RM70XX_VERSION.equals("-2") && !RM70XX_SERIAL_VERSION.equals("-2") && !VERSION.equals("-1") && !SERIAL_VERSION.equals("-1")) {
return String.format("设备连接:%s" + "\n软件版本:%s" + "\n硬件版本:%s" + "\n设备软件版本:%s" + "\n设备硬件版本:%s", "蓝牙已连接", RM70XX_VERSION, RM70XX_SERIAL_VERSION, VERSION, SERIAL_VERSION);
return String.format("设备连接:%s" + "\n软件版本:%s" + "\n硬件版本:%s" + "\n设备软件版本:%s" + "\n设备硬件版本:%s", "蓝牙已连接",
RM70XX_VERSION, RM70XX_SERIAL_VERSION, VERSION, SERIAL_VERSION);
} else {
return "设备连接失败";
}
......
package com.phlx.anchor_collect_flutter;
import cn.wandersnail.ble.EasyBLE;
import cn.wandersnail.ble.ScanConfiguration;
import cn.wandersnail.ble.ScannerType;
import cn.wandersnail.commons.poster.ThreadMode;
import io.flutter.embedding.android.FlutterActivity;
import android.bluetooth.le.ScanSettings;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.embedding.engine.FlutterEngine;
......@@ -15,8 +23,28 @@ public class MainActivity extends FlutterActivity {
public void configureFlutterEngine(FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ScanConfiguration scanConfig = new ScanConfiguration()
.setScanSettings(new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_BALANCED)
.build())
.setScanPeriodMillis(15000)//搜索一次的毫秒值
.setAcceptSysConnectedDevice(true)
.setOnlyAcceptBleDevice(true);
EasyBLE ble = EasyBLE.getBuilder().setScanConfiguration(scanConfig)
.setObserveAnnotationRequired(true)
.setMethodDefaultThreadMode(ThreadMode.BACKGROUND)//指定回调方法和观察者方法的默认线程
.setScannerType(ScannerType.LEGACY)
.build();
ble.setLogEnabled(true);
ble.initialize(getApplication());
}else {
EasyBLE.getInstance().initialize(getApplication());
}
flutterEngine.getPlugins().add(new RfidPlugin());
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}
......
package com.phlx.anchor_collect_flutter.ble;
import android.app.ActivityManager;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import cn.wandersnail.ble.Connection;
import cn.wandersnail.ble.ConnectionConfiguration;
import cn.wandersnail.ble.Device;
import cn.wandersnail.ble.EasyBLE;
import cn.wandersnail.ble.RequestBuilder;
import cn.wandersnail.ble.RequestBuilderFactory;
import cn.wandersnail.ble.WriteCharacteristicBuilder;
import cn.wandersnail.ble.WriteOptions;
import cn.wandersnail.ble.callback.ReadCharacteristicCallback;
import cn.wandersnail.ble.callback.ScanListener;
/**
* <pre>
* author : lei
* e-mail : 18600395998@163.com
* time : 2019/09/03
* desc :
* version: 1.0
* </pre>
*/
public class BleManagers {
private Context mContext;
private static BleManagers bleManagers;
private Intent bleService;//蓝牙服务声明
public Connection getConnection() {
return connection;
}
private Connection connection;
private Map<String, String> devicesNameMap;
/**
* 从给定的上下文中获取btUtils
*
* @param context context
* @return btUtils的一个实例
*/
public static BleManagers from(Context context) {
if (bleManagers == null) {
synchronized (BleManagers.class) {
if (bleManagers == null) {
bleManagers = new BleManagers(context);
}
}
}
return bleManagers;
}
/**
* 唯一的构造函数
*
* @param context context
*/
private BleManagers(Context context) {
mContext = context;
bleService = new Intent(mContext.getApplicationContext(), BleService.class);
}
/**
* 搜索设备
*
* @param listener 监听接口
*/
public void searchBleDevices(OnBleSearchListener listener) {
//扫描前,先停止上一次扫描
cancelBLESearch();
EasyBLE.getInstance().addScanListener(new ScanListener() {
@Override
public void onScanStart() {
if (devicesNameMap == null) {
devicesNameMap = new HashMap<>();
} else {
devicesNameMap.clear();
}
listener.onStartDiscovery();
}
@Override
public void onScanStop() {
//搜索停止
}
@Override
public void onScanResult(@NonNull Device device, boolean isConnectedBySys) {
if (!devicesNameMap.containsKey(device.getAddress())) {
devicesNameMap.put(device.getAddress(), device.getName());
listener.onBleDeviceFound(device);
}
}
@Override
public void onScanError(int errorCode, @NonNull String errorMsg) {
switch (errorCode) {
case ScanListener.ERROR_LACK_LOCATION_PERMISSION://缺少定位权限
listener.onBleError("缺少定位权限");
break;
case ScanListener.ERROR_LOCATION_SERVICE_CLOSED://位置服务未开启
listener.onBleError("位置服务未开启");
break;
case ScanListener.ERROR_SCAN_FAILED://搜索失败
listener.onBleError("搜索失败");
break;
}
}
});
EasyBLE.getInstance().startScan();
}
/**
* 取消搜索设备
*/
public void cancelBLESearch() {
if (EasyBLE.getInstance().isInitialized()) {
EasyBLE.getInstance().stopScan();
}
}
/**
* 连接蓝牙
*/
public void connectBleDevice(Device device) {
//连接配置,举个例随意配置两项
ConnectionConfiguration config = new ConnectionConfiguration();
config.setConnectTimeoutMillis(10000);
config.setRequestTimeoutMillis(1000);
config.setTryReconnectMaxTimes(0);
config.setAutoReconnect(false);
//观察者监听连接状态
connection = EasyBLE.getInstance().connect(device, config);
}
/**
* 断开一连接的蓝牙设备
*/
public void disConnectBLE(Device device) {
//清空已存设备地址列表
devicesNameMap.clear();
if (device != null && connection != null) {
EasyBLE.getInstance().disconnectConnection(device);//断开指定连接
connection = null;
}
//关闭蓝牙服务
stopBleService();
}
public void writeCharacteristic(UUID uuid_service, UUID uuid_write, byte[] bytes) {
WriteCharacteristicBuilder builder =
new RequestBuilderFactory().getWriteCharacteristicBuilder(uuid_service,
uuid_write, bytes);
//根据需要设置写入配置
builder.setWriteOptions(new WriteOptions.Builder()
.setPackageSize(20)
.setPackageWriteDelayMillis(5)
.setRequestWriteDelayMillis(10)
.setWaitWriteResult(true)
.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT)
.build());
//不设置回调,使用观察者模式接收结果
builder.build().execute(connection);
}
public void readCharacteristic(UUID uuid_service, UUID uuid_read) {
RequestBuilder<ReadCharacteristicCallback> builder =
new RequestBuilderFactory().getReadCharacteristicBuilder(uuid_service, uuid_read);
builder.setTag(UUID.randomUUID().toString());
builder.setPriority(Integer.MAX_VALUE);//设置请求优先级
builder.build().execute(connection);
}
public void startBleService() {
if (!isServiceRunning(mContext)) {
mContext.startService(bleService);
}
}
public void stopBleService() {
if (isServiceRunning(mContext)) {
mContext.stopService(bleService);
}
}
/**
* 判断服务是否在运行中
*
* @param context 即为Context对象
* @return 是否在运行中
*/
private boolean isServiceRunning(Context context) {
if (context != null) {
ActivityManager activityManager
= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
ArrayList<ActivityManager.RunningServiceInfo> runningServiceInfoList
=
(ArrayList<ActivityManager.RunningServiceInfo>) activityManager.getRunningServices(100);
for (ActivityManager.RunningServiceInfo runningServiceInfo : runningServiceInfoList) {
if ("com.phlx.anchor_collect_flutter.ble.BleService".equals(runningServiceInfo.service.getClassName())) {
return true;
}
}
} else {
return false;
}
return false;
}
}
package com.phlx.anchor_collect_flutter.ble;
import static com.phlx.anchor_collect_flutter.ble.Configs.uuid_service;
import static com.phlx.anchor_collect_flutter.ble.Configs.uuid_write;
import android.app.Service;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.phlx.anchor_collect_flutter.RfidPlugin;
import com.uhf.structures.OnBluetoothListener;
import java.util.List;
import java.util.UUID;
import cn.wandersnail.ble.Connection;
import cn.wandersnail.ble.ConnectionState;
import cn.wandersnail.ble.Device;
import cn.wandersnail.ble.EasyBLE;
import cn.wandersnail.ble.EventObserver;
import cn.wandersnail.ble.Request;
import cn.wandersnail.ble.RequestBuilder;
import cn.wandersnail.ble.RequestBuilderFactory;
import cn.wandersnail.ble.RequestType;
import cn.wandersnail.ble.callback.MtuChangeCallback;
import cn.wandersnail.ble.callback.NotificationChangeCallback;
import cn.wandersnail.commons.observer.Observe;
import cn.wandersnail.commons.poster.RunOn;
import cn.wandersnail.commons.poster.Tag;
import cn.wandersnail.commons.poster.ThreadMode;
/**
* <pre>
* author : lei
* e-mail : 18600395998@163.com
* time : 2019/04/12
* desc : 蓝牙接收数据服务
* version: 1.0
* </pre>
*/
public class BleService extends Service implements OnBluetoothListener, EventObserver {
private static final String TAG = BleService.class.getSimpleName();
private BleManagers bleManagers;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
RfidPlugin.getLinkage().setOnBluetoothListener(this);
EasyBLE.getInstance().registerObserver(this);
bleManagers = BleManagers.from(this);
Log.e(TAG, "onCreate: -----服务起了" );
}
@Override
public void getBluetoothData(byte[] bytes) {
if (bytes != null && bytes.length > 0) {
bleManagers.writeCharacteristic(uuid_service, uuid_write, bytes);
Log.e("Data:Send", bytes.length + "<--" + bytesToHexString(bytes, bytes.length));
}
}
@Tag("onCharacteristicChanged")
@RunOn(ThreadMode.BACKGROUND)
@Observe
@Override
public void onCharacteristicChanged(Device device, UUID service, UUID characteristic,
byte[] value) {
RfidPlugin.getLinkage().pushRemoteRFIDData(value);
Log.e("Data:notify", value.length + "<--" + bytesToHexString(value, value.length));
}
/**
* 连接状态 监听
*
* @param device
*/
/**
* 写入状态监听
*
* @param request
* @param value
*/
@Tag("onCharacteristicWrite")
@RunOn(ThreadMode.BACKGROUND)
@Observe
@Override
public void onCharacteristicWrite(@NonNull Request request, @NonNull byte[] value) {
Log.e("写入状态监听-",
"成功写入:" + cn.wandersnail.commons.util.StringUtils.toHex(value, " "));
// if (uuid_read != null && uuid_notify == null) {
// bleManagers.readCharacteristic(uuid_service, uuid_read);
// }
}
@Override
public void onCharacteristicRead(@NonNull Request request, @NonNull byte[] value) {
if (value.length > 0) {
RfidPlugin.getLinkage().pushRemoteRFIDData(value);
// Log.e("Data:read", value.length + "<--" + bytesToHexString(value, value.length));
}
}
@Override
public void onDestroy() {
EasyBLE.getInstance().unregisterObserver(this);
}
public static String bytesToHexString(byte src[], int length) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0 || length <= 0) {
return null;
}
for (int i = 0; i < length && i < src.length; i++) {
int v = src[i] & 0xff;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv + " ");
}
return stringBuilder.toString().toUpperCase();
}
}
\ No newline at end of file
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
class Config {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment