diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 41ab6bf3..3542eacd 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -116,6 +116,7 @@
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt
index 97e166d1..3f312cd7 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt
@@ -22,6 +22,7 @@ class MainActivity : FlutterFragmentActivity() {
PlatformBridge(flutterEngine, this).create()
OpenTokPlatformBridge(flutterEngine, this).create()
BleManager.init(this)
+
BleBridge(flutterEngine, this).createBleBridge(BleScanManager()) { name, bluetoothDevice ->
// Handle the scan result here
Log.d("MainActivity", "Received scan result: $name, $bluetoothDevice")
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/ble/BleBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/ble/BleBridge.kt
index 7da5d779..548e66ee 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/ble/BleBridge.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/ble/BleBridge.kt
@@ -31,6 +31,11 @@ import com.cloud.diplomaticquarterapp.utils.UiChannel
import com.google.gson.Gson
import com.jeremyliao.liveeventbus.LiveEventBus
import com.jstyle.blesdk2301.Util.BleSDK
+import com.jstyle.blesdk2301.Util.BleSDK.GetDynamicHRWithMode
+import com.jstyle.blesdk2301.Util.BleSDK.GetHRVDataWithMode
+import com.jstyle.blesdk2301.Util.BleSDK.GetStaticHRWithMode
+import com.jstyle.blesdk2301.Util.BleSDK.GetTemperature_historyData
+import com.jstyle.blesdk2301.Util.BleSDK.Oxygen_data
import com.jstyle.blesdk2301.callback.BleConnectionListener
import com.jstyle.blesdk2301.constant.BleConst
import com.lepu.blepro.event.EventMsgConst
@@ -106,6 +111,11 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
private const val CONNECT_DEVICE_SMART_RING = "connectDeviceSmartRing"
private const val DISCONNECT_DEVICE_SMART_RING = "disConnectDeviceSmartRing"
private const val GET_BATTERY_LEVEL_SMART_RING = "getBatteryLevelSmartRing"
+ private const val GET_TEMPERATURE_SMART_RING = "getTemperatureSmartRing"
+ private const val GET_DYNAMIC_HEART_RATE_SMART_RING = "getDynamicHeartRateSmartRing"
+ private const val GET_STATIC_HEART_RATE_SMART_RING = "getStaticHeartRateSmartRing"
+ private const val GET_HRV_SMART_RING = "getHRVSmartRing"
+ private const val GET_BLOOD_OXYGEN_SMART_RING = "getBloodOxygenSmartRing"
val scan = BleScanManager()
@@ -120,6 +130,11 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
eventSink?.success(deviceInfoString)
}
+ var modeStart: Byte = 0x00 //开始获取数据 start getting data
+
+ var modeContinue: Byte = 0x02 //继续读取数据 continue reading data
+
+ var modeDelete = 0x99.toByte()
var mUserData: MutableList = java.util.ArrayList()
@@ -243,6 +258,7 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
@SuppressLint("NewApi")
fun createBleBridge(bleScanManager: BleScanManager, scanResultHandler: (String, BluetoothDevice) -> Unit) {
+ subscribeForSmartRingEvents();
channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
Echannel = EventChannel(flutterEngine.dartExecutor.binaryMessenger, EVENTCHANNEL)
channel.setMethodCallHandler { methodCall: MethodCall, result: MethodChannel.Result ->
@@ -292,6 +308,16 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
disConnectDeviceSmartRing()
} else if (methodCall.method == GET_BATTERY_LEVEL_SMART_RING) {
getBatteryLevelSmartRing();
+ } else if (methodCall.method == GET_TEMPERATURE_SMART_RING) {
+ getTemperatureSmartRing(modeStart);
+ } else if (methodCall.method == GET_DYNAMIC_HEART_RATE_SMART_RING) {
+ getDynamicHeartRateSmartRing(modeStart);
+ } else if (methodCall.method == GET_STATIC_HEART_RATE_SMART_RING) {
+ getStaticHeartRateSmartRing(modeStart);
+ } else if (methodCall.method == GET_HRV_SMART_RING) {
+ getHRVSmartRing(modeStart);
+ } else if (methodCall.method == GET_BLOOD_OXYGEN_SMART_RING) {
+ getBloodOxygenSmartRing(modeStart);
} else {
result.notImplemented()
}
@@ -1054,6 +1080,7 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
override fun ConnectionSucceeded() { //连接设备成功 Successfully connected the device
Log.e("BleStatus", "ConnectionSucceeded")
+ getBatteryLevelSmartRing()
}
override fun Connecting() { //设备连接中 Device is connected
@@ -1072,7 +1099,6 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
Log.e("BleStatus", "BluetoothSwitchIsTurnedOff")
}
})
-
}
private fun disConnectDeviceSmartRing() {
@@ -1084,15 +1110,150 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
sendValue(BleSDK.GetDeviceBatteryLevel());
}
+ private fun getTemperatureSmartRing(mode: Byte) {
+ sendValue(GetTemperature_historyData(mode, ""))
+ }
+
+ private fun getDynamicHeartRateSmartRing(mode: Byte) {
+ sendValue(GetDynamicHRWithMode(mode, ""))
+ }
+
+ private fun getStaticHeartRateSmartRing(mode: Byte) {
+ sendValue(GetStaticHRWithMode(mode, ""))
+ }
+
+ private fun getHRVSmartRing(mode: Byte) {
+
+ sendValue(GetHRVDataWithMode(mode, ""))
+ }
+
+ private fun getBloodOxygenSmartRing(mode: Byte) {
+
+ sendValue(Oxygen_data(mode))
+ }
+
+ private var temperatureDataCount = 0
+ private var dynamicHeartRateDataCount = 0
+ private var staticHeartRateDataCount = 0
+ private var hrvDataCount = 0
+ private var bloodOxygenDataCount = 0
override fun dataCallback(maps: Map?) {
super.dataCallback(maps)
val dataType = getDataType(maps)
Log.d("dataCallbackType", dataType.toString())
+ val finish = getEnd(maps!!)
when (dataType) {
BleConst.GetDeviceBatteryLevel -> {
Log.d("BatteryLevel", maps.toString())
+ val returnData = mapOf("type" to "BatteryLevelSmartRing", "data" to gson.toJson(maps))
+ eventSink?.success(returnData)
+ }
+
+ BleConst.Temperature_history -> {
+ temperatureDataCount++
+ if (finish) {
+ temperatureDataCount = 0
+ Log.d("TemperatureSmartRing", maps.toString())
+ val returnData = mapOf("type" to "TemperatureSmartRing", "data" to gson.toJson(maps))
+ eventSink?.success(returnData)
+ }
+ if (temperatureDataCount == 50) {
+ temperatureDataCount = 0
+ if (finish) {
+ Log.d("TemperatureSmartRing", maps.toString())
+ val returnData = mapOf("type" to "TemperatureSmartRing", "data" to gson.toJson(maps))
+ eventSink?.success(returnData)
+ } else {
+ getTemperatureSmartRing(modeContinue)
+ }
+ }
+ }
+
+ BleConst.GetDynamicHR -> {
+ dynamicHeartRateDataCount++
+ if (finish) {
+ dynamicHeartRateDataCount = 0
+ Log.d("DynamicHRSmartRing", maps.toString())
+ val returnData = mapOf("type" to "DynamicHeartRateSmartRing", "data" to gson.toJson(maps))
+ eventSink?.success(returnData)
+ }
+ if (dynamicHeartRateDataCount == 50) {
+ dynamicHeartRateDataCount = 0
+ if (finish) {
+ Log.d("DynamicHRSmartRing", maps.toString())
+ val returnData = mapOf("type" to "DynamicHeartRateSmartRing", "data" to gson.toJson(maps))
+ eventSink?.success(returnData)
+ } else {
+ getDynamicHeartRateSmartRing(modeContinue)
+ }
+ }
+
+ }
+
+
+ BleConst.GetStaticHR -> {
+ staticHeartRateDataCount++
+ if (finish) {
+ staticHeartRateDataCount = 0
+ Log.d("StaticHRSmartRing", maps.toString())
+ val returnData = mapOf("type" to "StaticHeartRateSmartRing", "data" to gson.toJson(maps))
+ eventSink?.success(returnData)
+ }
+ if (staticHeartRateDataCount == 50) {
+ staticHeartRateDataCount = 0
+ if (finish) {
+ Log.d("StaticHRSmartRing", maps.toString())
+ val returnData = mapOf("type" to "StaticHeartRateSmartRing", "data" to gson.toJson(maps))
+ eventSink?.success(returnData)
+ } else {
+ getStaticHeartRateSmartRing(modeContinue)
+ }
+ }
+
+ }
+
+ BleConst.GetHRVData -> {
+ hrvDataCount++
+ if (finish) {
+ hrvDataCount = 0
+ Log.d("HrvSmartRing", maps.toString())
+ val returnData = mapOf("type" to "HrvSmartRing", "data" to gson.toJson(maps))
+ eventSink?.success(returnData)
+ }
+ if (hrvDataCount == 50) {
+ if (finish) {
+ hrvDataCount = 0
+ Log.d("HrvSmartRing", maps.toString())
+ val returnData = mapOf("type" to "HrvSmartRing", "data" to gson.toJson(maps))
+ eventSink?.success(returnData)
+ } else {
+ getHRVSmartRing(modeContinue)
+ }
+ }
+ }
+
+ BleConst.Blood_oxygen -> {
+ bloodOxygenDataCount++
+ if (finish) {
+ bloodOxygenDataCount = 0
+ Log.d("BloodOxygenSmartRing", maps.toString())
+ val returnData = mapOf("type" to "BloodOxygenSmartRing", "data" to gson.toJson(maps))
+ eventSink?.success(returnData)
+ }
+ if (bloodOxygenDataCount == 50) {
+ bloodOxygenDataCount = 0
+ if (finish) {
+ bloodOxygenDataCount = 0
+ Log.d("BloodOxygenSmartRing", maps.toString())
+ val returnData = mapOf("type" to "BloodOxygenSmartRing", "data" to gson.toJson(maps))
+ eventSink?.success(returnData)
+ } else {
+
+ getBloodOxygenSmartRing(modeContinue)
+ }
+ }
}
}
}
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/smart_ring_2301/BaseActivity.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/smart_ring_2301/BaseActivity.kt
index 8aca9482..4748d532 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/smart_ring_2301/BaseActivity.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/smart_ring_2301/BaseActivity.kt
@@ -19,12 +19,12 @@ import javax.annotation.Nullable
open class BaseActivity : AppCompatActivity(), DataListener2301 {
private var subscription: Disposable? = null
- override fun onCreate(@Nullable savedInstanceState: Bundle?) {
+ public override fun onCreate(@Nullable savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- subscribe()
+// subscribeForSmartRingEvents()
}
- protected open fun subscribe() {
+ protected open fun subscribeForSmartRingEvents() {
subscription = RxBus.instance.toObservable(BleData::class.java).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe { bleData ->
val action = bleData.action
if (action == BleService.ACTION_DATA_AVAILABLE) {
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/smart_ring_2301/BleService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/smart_ring_2301/BleService.kt
index bdefbb24..3c868808 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/smart_ring_2301/BleService.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/smart_ring_2301/BleService.kt
@@ -1 +1 @@
-package com.cloud.diplomaticquarterapp.smart_ring_2301
import android.annotation.SuppressLint
import android.app.Service
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCallback
import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothGattDescriptor
import android.bluetooth.BluetoothGattService
import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothProfile
import android.content.Context
import android.content.Intent
import android.os.Binder
import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.text.TextUtils
import android.util.Log
import com.cloud.diplomaticquarterapp.smart_ring_2301.Util.BleData
import com.cloud.diplomaticquarterapp.smart_ring_2301.Util.ResolveData.byte2Hex
import com.cloud.diplomaticquarterapp.smart_ring_2301.Util.ResolveData.decodeDeviceName
import com.cloud.diplomaticquarterapp.smart_ring_2301.Util.RxBus.Companion.instance
import com.jstyle.blesdk2301.callback.BleConnectionListener
import java.util.LinkedList
import java.util.Queue
import java.util.UUID
@SuppressLint("MissingPermission")
class BleService : Service() {
private var NeedReconnect = false
var fastconnect = false //是否连接成功过设备
var hasp = HashMap()
private val kBinder: IBinder = LocalBinder()
private val gattHash = HashMap()
private var bluetoothManager: BluetoothManager? = null
private var mBluetoothAdapter: BluetoothAdapter? = null
private var mGatt: BluetoothGatt? = null
var isConnected = false
private set
private val handler = Handler()
override fun onBind(intent: Intent): IBinder? {
initAdapter()
return kBinder
}
override fun onUnbind(intent: Intent): Boolean {
return super.onUnbind(intent)
}
/**
* 初始化BLE 如果已经连接就不用再次连
*
* @param bleDevice
* @return
*/
private var address: String? = null
private var mContext: Context? = null
protected var bleConnectionListener: BleConnectionListener? = null
fun initBluetoothDevice(address: String?, context: Context?, needReconnect: Boolean, bleConnectionListener1: BleConnectionListener?) {
if (null != bleConnectionListener1) {
bleConnectionListener = bleConnectionListener1
NeedReconnect = needReconnect
}
//MyLog.i("开始连接");
fastconnect = false
this.address = address
mContext = context
val device = mBluetoothAdapter!!.getRemoteDevice(address)
if (isConnected) return
if (null != mGatt) {
refreshDeviceCache(mGatt)
mGatt = null
}
mGatt = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
device.connectGatt(context, false, bleGattCallback, BluetoothDevice.TRANSPORT_LE)
} else {
device.connectGatt(context, false, bleGattCallback)
}
if (mGatt == null) {
println(device.address + "gatt is null")
}
if (null != bleConnectionListener) {
bleConnectionListener!!.Connecting()
}
// this.mContext=context;
// reconnect(true);
}
private var scanToConnect = true
private var isScaning = false
@SuppressLint("MissingPermission")
fun startScan(enable: Boolean) {
Log.i(TAG, "startScan: $enable")
if (!mBluetoothAdapter!!.isEnabled) {
return
}
if (scanToConnect) {
startScanDevice(true)
} else {
initBluetoothDevice(address, mContext, NeedReconnect, bleConnectionListener)
}
scanToConnect = !scanToConnect
}
@SuppressLint("MissingPermission")
private fun startScanDevice(enable: Boolean) {
if (enable) {
if (isScaning) return
handler.postDelayed({
mBluetoothAdapter!!.stopLeScan(mLeScanCallback)
isScaning = false
startScan(true)
}, 20000)
fastconnect = false
mBluetoothAdapter!!.startLeScan(mLeScanCallback)
} else {
if (isScaning) {
mBluetoothAdapter!!.stopLeScan(mLeScanCallback)
handler.removeCallbacksAndMessages(null)
}
}
isScaning = enable
}
private val mLeScanCallback = BluetoothAdapter.LeScanCallback { device, rssi, scanRecord ->
if (device.address == address) {
val name = decodeDeviceName(device, scanRecord)
if (!TextUtils.isEmpty(name) && name == "DfuTarg") return@LeScanCallback
if (mGatt != null) return@LeScanCallback
handler.post {
startScanDevice(false)
mGatt = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
device.connectGatt(mContext, false, bleGattCallback, BluetoothDevice.TRANSPORT_LE)
} else {
device.connectGatt(mContext, false, bleGattCallback)
}
if (mGatt == null) {
println("gatt is null ")
}
}
}
}
private fun initAdapter() {
if (bluetoothManager == null) {
bluetoothManager = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
if (bluetoothManager == null) {
return
}
}
mBluetoothAdapter = bluetoothManager!!.adapter
}
/**
* 断开连接
*/
fun disconnect() {
NeedReconnect = false
broadcastUpdate(ACTION_GATT_DISCONNECTED)
if (mGatt != null) {
mGatt = if (isConnected) {
mGatt!!.disconnect()
mGatt!!.close()
null
} else {
Log.i(TAG, "close: ")
mGatt!!.close()
null
}
}
isConnected = false
}
/**
* 根据设备的Mac地址断开连接
*
* @param address
*/
fun disconnect(address: String) {
val gatts = ArrayList()
for (gatt in arrayGatts) {
if (gatt != null && gatt.device.address == address) {
gatts.add(gatt)
// gatt.disconnect();
gatt.close()
// gatt = null;
}
}
arrayGatts.removeAll(gatts)
}
inner class LocalBinder : Binder() {
val service: BleService
get() = this@BleService
}
private var discoverCount = 0
private val ob = Any()
private val bleGattCallback: BluetoothGattCallback = object : BluetoothGattCallback() {
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
var gatt: BluetoothGatt? = gatt
if (status == 133 || newState == 0) {
if (null != bleConnectionListener) {
bleConnectionListener!!.BleStatus(status, newState)
}
if (mGatt != null) {
mGatt!!.disconnect()
mGatt!!.close()
refreshDeviceCache(mGatt)
mGatt = null
}
if (gatt != null) {
gatt.disconnect()
gatt.close()
refreshDeviceCache(gatt)
gatt = null
}
if (NeedReconnect) startScan(true)
return
}
var action: String? = null
Log.i(TAG, "onConnectionStateChange: status$status newstate $newState")
if (newState == BluetoothProfile.STATE_CONNECTED) {
try {
gatt!!.discoverServices()
} catch (e: Exception) {
e.printStackTrace()
}
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
if (null != bleConnectionListener) {
bleConnectionListener!!.ConnectionFailed()
}
isConnected = false
Log.i(TAG, "onConnectionStateChange: " + ACTION_GATT_DISCONNECTED)
if (mGatt != null) {
mGatt!!.close()
mGatt = null
}
queues.clear()
if (!NeedReconnect) {
action = ACTION_GATT_DISCONNECTED
broadcastUpdate(action)
}
if (!NeedReconnect) {
} else {
if (fastconnect) {
fastconnect = false
Log.e(TAG, "发送异常断开")
}
if (status == 133) {
refreshDeviceCache(gatt)
}
if (null != bleConnectionListener) {
bleConnectionListener!!.OnReconnect()
}
startScan(true)
}
} else {
Log.e("MainActivity", "onConnectionStateChange: status$status newstate $newState")
if (0 == status && 0 == newState) {
if (null != bleConnectionListener) {
bleConnectionListener!!.BluetoothSwitchIsTurnedOff()
}
} else {
if (null != bleConnectionListener) {
bleConnectionListener!!.BleStatus(status, newState)
}
}
}
}
/*
* 搜索device中的services (non-Javadoc)
*
* @see
* android.bluetooth.BluetoothGattCallback#onServicesDiscovered(android
* .bluetooth.BluetoothGatt, int)
*/
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
super.onServicesDiscovered(gatt, status)
// if (mGatt == null)
// return;
if (status == BluetoothGatt.GATT_SUCCESS) {
val address = gatt.device.address
val name = mBluetoothAdapter!!.getRemoteDevice(address)
.name
setCharacteristicNotification(true)
/* if (gatt != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
gatt.requestMtu(512);
}else{
setCharacteristicNotification(true);
}*/discoverCount = 0
} else {
// mGatt = null;
Log.w(
"servieDiscovered", "onServicesDiscovered received: "
+ status
)
}
}
override fun onMtuChanged(gatt: BluetoothGatt, mtu: Int, status: Int) {
super.onMtuChanged(gatt, mtu, status)
if (BluetoothGatt.GATT_SUCCESS == status) {
setCharacteristicNotification(true)
} else {
gatt.requestMtu(153)
}
}
/*
* 读取特征�?(non-Javadoc)
*
* @see
* android.bluetooth.BluetoothGattCallback#onCharacteristicRead(android
* .bluetooth.BluetoothGatt,
* android.bluetooth.BluetoothGattCharacteristic, int)
*/
override fun onCharacteristicRead(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
super.onCharacteristicRead(gatt, characteristic, status)
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(
ACTION_DATA_AVAILABLE, characteristic, gatt
.device.address
)
} else {
}
}
override fun onDescriptorWrite(
gatt: BluetoothGatt,
descriptor: BluetoothGattDescriptor, status: Int
) {
super.onDescriptorWrite(gatt, descriptor, status)
if (status == BluetoothGatt.GATT_SUCCESS) {
nextQueue()
isConnected = true
broadcastUpdate(ACTION_GATT_onDescriptorWrite)
if (null != bleConnectionListener) {
bleConnectionListener!!.ConnectionSucceeded()
}
} else {
Log.i(TAG, "onDescriptorWrite: failed")
}
}
/*
* 特征值的变化 (non-Javadoc)
*
* @see
* android.bluetooth.BluetoothGattCallback#onCharacteristicChanged(android
* .bluetooth.BluetoothGatt,
* android.bluetooth.BluetoothGattCharacteristic)
*/
override fun onCharacteristicChanged(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic
) {
super.onCharacteristicChanged(gatt, characteristic)
if (mGatt == null) return
Log.i(TAG, "onCharacteristicChanged: " + byte2Hex(characteristic.value))
// SDUtil.saveBTLog("log", "Receiving: " + ResolveData.byte2Hex(characteristic.getValue()));
broadcastUpdate(
ACTION_DATA_AVAILABLE, characteristic, gatt
.device.address
)
// SendData.sendBus(ACTION_DATA_AVAILABLE, characteristic.getValue());
}
override fun onCharacteristicWrite(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic, status: Int
) {
super.onCharacteristicWrite(gatt, characteristic, status)
if (status == BluetoothGatt.GATT_SUCCESS) {
nextQueue()
} else {
// MyLog.i("status" + status);
}
}
}
fun refreshDeviceCache(gatt: BluetoothGatt?): Boolean {
try {
val localMethod = gatt!!.javaClass.getMethod(
"refresh", *arrayOfNulls(0)
)
if (localMethod != null) {
return localMethod.invoke(
gatt, *arrayOfNulls(0)
) as Boolean
}
} catch (localException: Exception) {
Log.e("s", "An exception occured while refreshing device")
}
return false
}
/**
* 广播
*
* @param action
*/
private fun broadcastUpdate(action: String?) {
val bleData = BleData()
bleData.action = action
instance.post(bleData)
//Intent intent = new Intent(action);
//sendBroadcast(intent);
}
/**
* 发�?带蓝牙信息的到广�? *
*
* @param action
* @param characteristic
*/
private fun broadcastUpdate(
action: String,
characteristic: BluetoothGattCharacteristic, mac: String
) {
// Intent intent = new Intent(action);
val data = characteristic.value
val bleData = BleData()
bleData.action = action
bleData.value = data
instance.post(bleData)
}
/**
* 读取设备数据
*
* @param
* @param characteristic
*/
fun readValue(characteristic: BluetoothGattCharacteristic?) {
if (mGatt == null) return
mGatt!!.readCharacteristic(characteristic)
}
/**
* 写入设备数据
*/
fun writeValue(value: ByteArray?) {
Handler(Looper.getMainLooper()).postDelayed(Runnable {
if (mGatt == null || value == null) return@Runnable
val service = mGatt!!.getService(SERVICE_DATA) ?: return@Runnable
val characteristic = service.getCharacteristic(DATA_Characteristic) ?: return@Runnable
if (value[0] == 0x47.toByte()) {
NeedReconnect = false
}
characteristic.value = value
Log.i(TAG, "writeValue: " + byte2Hex(value))
mGatt!!.writeCharacteristic(characteristic)
// SDUtil.saveBTLog("log", "writeValue: " + ResolveData.byte2Hex(value));
}, 500)
}
fun setCharacteristicNotification(enable: Boolean) {
if (mGatt == null) return
val service = mGatt!!.getService(SERVICE_DATA) ?: return
val characteristic = service.getCharacteristic(NOTIY_Characteristic) ?: return
mGatt!!.setCharacteristicNotification(characteristic, enable)
try {
Thread.sleep(20)
} catch (e: InterruptedException) {
e.printStackTrace()
}
val descriptor = characteristic.getDescriptor(NOTIY)
?: //MyLog.e("setCharacteristicNotification descriptor=null,所以不能发送使能数据");
return
descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
if (mGatt == null) return
mGatt!!.writeDescriptor(descriptor)
}
val supportedGattServices: List?
/**
* 获取services
*
* @return
*/
get() = if (mGatt == null) {
//MyLog.e("getServices, gatt is null ");
null
} else mGatt!!.services
/**
* 根据设备的Mac地址从已经连接的设备中匹配对应的BluetoothGatt对象
*
* @param device
* @return
*/
private fun getBluetoothGatt(device: BluetoothDevice): BluetoothGatt? {
return mGatt
}
/**
* //读取信号
*
* @param device
*/
fun readRssi(device: BluetoothDevice?) {
mGatt!!.readRemoteRssi()
}
override fun onDestroy() {
super.onDestroy()
}
var queues: Queue = LinkedList()
fun offerValue(value: ByteArray) {
queues.offer(value)
}
fun nextQueue() {
val requests = queues
val data = if (requests != null) requests.poll() else null
writeValue(data)
}
companion object {
private const val TAG = "BleService"
private val NOTIY = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")
private val SERVICE_DATA = UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb")
private val DATA_Characteristic = UUID.fromString("0000fff6-0000-1000-8000-00805f9b34fb")
private val NOTIY_Characteristic = UUID.fromString("0000fff7-0000-1000-8000-00805f9b34fb")
const val ACTION_GATT_onDescriptorWrite = "com.jstylelife.ble.service.onDescriptorWrite"
const val ACTION_GATT_CONNECTED = "com.jstylelife.ble.service.ACTION_GATT_CONNECTED"
const val ACTION_GATT_DISCONNECTED = "com.jstylelife.ble.service.ACTION_GATT_DISCONNECTED"
const val ACTION_DATA_AVAILABLE = "com.jstylelife.ble.service.ACTION_DATA_AVAILABLE"
private val arrayGatts = ArrayList() // 存放BluetoothGatt的集�?
var colorCharacteristic: BluetoothGattCharacteristic? = null
}
}
\ No newline at end of file
+package com.cloud.diplomaticquarterapp.smart_ring_2301
import android.annotation.SuppressLint
import android.app.Service
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCallback
import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothGattDescriptor
import android.bluetooth.BluetoothGattService
import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothProfile
import android.content.Context
import android.content.Intent
import android.os.Binder
import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.text.TextUtils
import android.util.Log
import com.cloud.diplomaticquarterapp.smart_ring_2301.Util.BleData
import com.cloud.diplomaticquarterapp.smart_ring_2301.Util.ResolveData.byte2Hex
import com.cloud.diplomaticquarterapp.smart_ring_2301.Util.ResolveData.decodeDeviceName
import com.cloud.diplomaticquarterapp.smart_ring_2301.Util.RxBus.Companion.instance
import com.jstyle.blesdk2301.callback.BleConnectionListener
import java.util.LinkedList
import java.util.Queue
import java.util.UUID
@SuppressLint("MissingPermission")
class BleService : Service() {
private var NeedReconnect = false
var fastconnect = false //是否连接成功过设备
var hasp = HashMap()
private val kBinder: IBinder = LocalBinder()
private val gattHash = HashMap()
private var bluetoothManager: BluetoothManager? = null
private var mBluetoothAdapter: BluetoothAdapter? = null
private var mGatt: BluetoothGatt? = null
var isConnected = false
private set
private val handler = Handler()
override fun onBind(intent: Intent): IBinder? {
initAdapter()
return kBinder
}
override fun onUnbind(intent: Intent): Boolean {
return super.onUnbind(intent)
}
/**
* 初始化BLE 如果已经连接就不用再次连
*
* @param bleDevice
* @return
*/
private var address: String? = null
private var mContext: Context? = null
protected var bleConnectionListener: BleConnectionListener? = null
fun initBluetoothDevice(address: String?, context: Context?, needReconnect: Boolean, bleConnectionListener1: BleConnectionListener?) {
if (null != bleConnectionListener1) {
bleConnectionListener = bleConnectionListener1
NeedReconnect = needReconnect
}
//MyLog.i("开始连接");
fastconnect = false
this.address = address
mContext = context
val device = mBluetoothAdapter!!.getRemoteDevice(address)
if (isConnected) return
if (null != mGatt) {
refreshDeviceCache(mGatt)
mGatt = null
}
mGatt = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
device.connectGatt(context, false, bleGattCallback, BluetoothDevice.TRANSPORT_LE)
} else {
device.connectGatt(context, false, bleGattCallback)
}
if (mGatt == null) {
println(device.address + "gatt is null")
}
if (null != bleConnectionListener) {
bleConnectionListener!!.Connecting()
}
// this.mContext=context;
// reconnect(true);
}
private var scanToConnect = true
private var isScaning = false
@SuppressLint("MissingPermission")
fun startScan(enable: Boolean) {
Log.i(TAG, "startScan: $enable")
if (!mBluetoothAdapter!!.isEnabled) {
return
}
if (scanToConnect) {
startScanDevice(true)
} else {
initBluetoothDevice(address, mContext, NeedReconnect, bleConnectionListener)
}
scanToConnect = !scanToConnect
}
@SuppressLint("MissingPermission")
private fun startScanDevice(enable: Boolean) {
if (enable) {
if (isScaning) return
handler.postDelayed({
mBluetoothAdapter!!.stopLeScan(mLeScanCallback)
isScaning = false
startScan(true)
}, 20000)
fastconnect = false
mBluetoothAdapter!!.startLeScan(mLeScanCallback)
} else {
if (isScaning) {
mBluetoothAdapter!!.stopLeScan(mLeScanCallback)
handler.removeCallbacksAndMessages(null)
}
}
isScaning = enable
}
private val mLeScanCallback = BluetoothAdapter.LeScanCallback { device, rssi, scanRecord ->
if (device.address == address) {
val name = decodeDeviceName(device, scanRecord)
if (!TextUtils.isEmpty(name) && name == "DfuTarg") return@LeScanCallback
if (mGatt != null) return@LeScanCallback
handler.post {
startScanDevice(false)
mGatt = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
device.connectGatt(mContext, false, bleGattCallback, BluetoothDevice.TRANSPORT_LE)
} else {
device.connectGatt(mContext, false, bleGattCallback)
}
if (mGatt == null) {
println("gatt is null ")
}
}
}
}
private fun initAdapter() {
if (bluetoothManager == null) {
bluetoothManager = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
if (bluetoothManager == null) {
return
}
}
mBluetoothAdapter = bluetoothManager!!.adapter
}
/**
* 断开连接
*/
fun disconnect() {
NeedReconnect = false
broadcastUpdate(ACTION_GATT_DISCONNECTED)
if (mGatt != null) {
mGatt = if (isConnected) {
mGatt!!.disconnect()
mGatt!!.close()
null
} else {
Log.i(TAG, "close: ")
mGatt!!.close()
null
}
}
isConnected = false
}
/**
* 根据设备的Mac地址断开连接
*
* @param address
*/
fun disconnect(address: String) {
val gatts = ArrayList()
for (gatt in arrayGatts) {
if (gatt != null && gatt.device.address == address) {
gatts.add(gatt)
// gatt.disconnect();
gatt.close()
// gatt = null;
}
}
arrayGatts.removeAll(gatts)
}
inner class LocalBinder : Binder() {
val service: BleService
get() = this@BleService
}
private var discoverCount = 0
private val ob = Any()
private val bleGattCallback: BluetoothGattCallback = object : BluetoothGattCallback() {
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
var gatt: BluetoothGatt? = gatt
if (status == 133 || newState == 0) {
if (null != bleConnectionListener) {
bleConnectionListener!!.BleStatus(status, newState)
}
if (mGatt != null) {
mGatt!!.disconnect()
mGatt!!.close()
refreshDeviceCache(mGatt)
mGatt = null
}
if (gatt != null) {
gatt.disconnect()
gatt.close()
refreshDeviceCache(gatt)
gatt = null
}
if (NeedReconnect) startScan(true)
return
}
var action: String? = null
Log.i(TAG, "onConnectionStateChange: status$status newstate $newState")
if (newState == BluetoothProfile.STATE_CONNECTED) {
try {
gatt!!.discoverServices()
} catch (e: Exception) {
e.printStackTrace()
}
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
if (null != bleConnectionListener) {
bleConnectionListener!!.ConnectionFailed()
}
isConnected = false
Log.i(TAG, "onConnectionStateChange: " + ACTION_GATT_DISCONNECTED)
if (mGatt != null) {
mGatt!!.close()
mGatt = null
}
queues.clear()
if (!NeedReconnect) {
action = ACTION_GATT_DISCONNECTED
broadcastUpdate(action)
}
if (!NeedReconnect) {
} else {
if (fastconnect) {
fastconnect = false
Log.e(TAG, "发送异常断开")
}
if (status == 133) {
refreshDeviceCache(gatt)
}
if (null != bleConnectionListener) {
bleConnectionListener!!.OnReconnect()
}
startScan(true)
}
} else {
Log.e("MainActivity", "onConnectionStateChange: status$status newstate $newState")
if (0 == status && 0 == newState) {
if (null != bleConnectionListener) {
bleConnectionListener!!.BluetoothSwitchIsTurnedOff()
}
} else {
if (null != bleConnectionListener) {
bleConnectionListener!!.BleStatus(status, newState)
}
}
}
}
/*
* 搜索device中的services (non-Javadoc)
*
* @see
* android.bluetooth.BluetoothGattCallback#onServicesDiscovered(android
* .bluetooth.BluetoothGatt, int)
*/
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
super.onServicesDiscovered(gatt, status)
// if (mGatt == null)
// return;
if (status == BluetoothGatt.GATT_SUCCESS) {
val address = gatt.device.address
val name = mBluetoothAdapter!!.getRemoteDevice(address)
.name
setCharacteristicNotification(true)
/* if (gatt != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
gatt.requestMtu(512);
}else{
setCharacteristicNotification(true);
}*/discoverCount = 0
} else {
// mGatt = null;
Log.w(
"servieDiscovered", "onServicesDiscovered received: "
+ status
)
}
}
override fun onMtuChanged(gatt: BluetoothGatt, mtu: Int, status: Int) {
super.onMtuChanged(gatt, mtu, status)
if (BluetoothGatt.GATT_SUCCESS == status) {
setCharacteristicNotification(true)
} else {
gatt.requestMtu(153)
}
}
/*
* 读取特征�?(non-Javadoc)
*
* @see
* android.bluetooth.BluetoothGattCallback#onCharacteristicRead(android
* .bluetooth.BluetoothGatt,
* android.bluetooth.BluetoothGattCharacteristic, int)
*/
override fun onCharacteristicRead(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
super.onCharacteristicRead(gatt, characteristic, status)
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(
ACTION_DATA_AVAILABLE, characteristic, gatt
.device.address
)
} else {
}
}
override fun onDescriptorWrite(
gatt: BluetoothGatt,
descriptor: BluetoothGattDescriptor, status: Int
) {
super.onDescriptorWrite(gatt, descriptor, status)
if (status == BluetoothGatt.GATT_SUCCESS) {
nextQueue()
isConnected = true
broadcastUpdate(ACTION_GATT_onDescriptorWrite)
if (null != bleConnectionListener) {
bleConnectionListener!!.ConnectionSucceeded()
}
} else {
Log.i(TAG, "onDescriptorWrite: failed")
}
}
/*
* 特征值的变化 (non-Javadoc)
*
* @see
* android.bluetooth.BluetoothGattCallback#onCharacteristicChanged(android
* .bluetooth.BluetoothGatt,
* android.bluetooth.BluetoothGattCharacteristic)
*/
override fun onCharacteristicChanged(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic
) {
super.onCharacteristicChanged(gatt, characteristic)
if (mGatt == null) return
Log.i(TAG, "onCharacteristicChanged: " + byte2Hex(characteristic.value))
// SDUtil.saveBTLog("log", "Receiving: " + ResolveData.byte2Hex(characteristic.getValue()));
broadcastUpdate(
ACTION_DATA_AVAILABLE, characteristic, gatt
.device.address
)
// SendData.sendBus(ACTION_DATA_AVAILABLE, characteristic.getValue());
}
override fun onCharacteristicWrite(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic, status: Int
) {
super.onCharacteristicWrite(gatt, characteristic, status)
if (status == BluetoothGatt.GATT_SUCCESS) {
nextQueue()
} else {
// MyLog.i("status" + status);
}
}
}
fun refreshDeviceCache(gatt: BluetoothGatt?): Boolean {
try {
val localMethod = gatt!!.javaClass.getMethod(
"refresh", *arrayOfNulls(0)
)
if (localMethod != null) {
return localMethod.invoke(
gatt, *arrayOfNulls(0)
) as Boolean
}
} catch (localException: Exception) {
Log.e("s", "An exception occured while refreshing device")
}
return false
}
/**
* 广播
*
* @param action
*/
private fun broadcastUpdate(action: String?) {
val bleData = BleData()
bleData.action = action
instance.post(bleData)
//Intent intent = new Intent(action);
//sendBroadcast(intent);
}
/**
* 发�?带蓝牙信息的到广�? *
*
* @param action
* @param characteristic
*/
private fun broadcastUpdate(
action: String,
characteristic: BluetoothGattCharacteristic, mac: String
) {
// Intent intent = new Intent(action);
val data = characteristic.value
val bleData = BleData()
bleData.action = action
bleData.value = data
instance.post(bleData)
}
/**
* 读取设备数据
*
* @param
* @param characteristic
*/
fun readValue(characteristic: BluetoothGattCharacteristic?) {
if (mGatt == null) return
mGatt!!.readCharacteristic(characteristic)
}
/**
* 写入设备数据
*/
fun writeValue(value: ByteArray?) {
Handler(Looper.getMainLooper()).postDelayed(Runnable {
if (mGatt == null || value == null) return@Runnable
val service = mGatt!!.getService(SERVICE_DATA) ?: return@Runnable
val characteristic = service.getCharacteristic(DATA_Characteristic) ?: return@Runnable
if (value[0] == 0x47.toByte()) {
NeedReconnect = false
}
characteristic.value = value
Log.i(TAG, "writeValue: " + byte2Hex(value))
mGatt!!.writeCharacteristic(characteristic)
// SDUtil.saveBTLog("log", "writeValue: " + ResolveData.byte2Hex(value));
}, 500)
}
fun setCharacteristicNotification(enable: Boolean) {
if (mGatt == null) return
val service = mGatt!!.getService(SERVICE_DATA) ?: return
val characteristic = service.getCharacteristic(NOTIY_Characteristic) ?: return
mGatt!!.setCharacteristicNotification(characteristic, enable)
try {
Thread.sleep(20)
} catch (e: InterruptedException) {
e.printStackTrace()
}
val descriptor = characteristic.getDescriptor(NOTIY)
?: //MyLog.e("setCharacteristicNotification descriptor=null,所以不能发送使能数据");
return
descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
if (mGatt == null) return
mGatt!!.writeDescriptor(descriptor)
}
val supportedGattServices: List?
/**
* 获取services
*
* @return
*/
get() = if (mGatt == null) {
//MyLog.e("getServices, gatt is null ");
null
} else mGatt!!.services
/**
* 根据设备的Mac地址从已经连接的设备中匹配对应的BluetoothGatt对象
*
* @param device
* @return
*/
private fun getBluetoothGatt(device: BluetoothDevice): BluetoothGatt? {
return mGatt
}
/**
* //读取信号
*
* @param device
*/
fun readRssi(device: BluetoothDevice?) {
mGatt!!.readRemoteRssi()
}
override fun onDestroy() {
super.onDestroy()
}
var queues: Queue = LinkedList()
fun offerValue(value: ByteArray) {
queues.offer(value)
}
fun nextQueue() {
val requests = queues
val data = if (requests != null) requests.poll() else null
writeValue(data)
}
companion object {
private const val TAG = "BleService"
private val NOTIY = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")
private val SERVICE_DATA = UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb")
private val DATA_Characteristic = UUID.fromString("0000fff6-0000-1000-8000-00805f9b34fb")
private val NOTIY_Characteristic = UUID.fromString("0000fff7-0000-1000-8000-00805f9b34fb")
const val ACTION_GATT_onDescriptorWrite = "com.jstylelife.ble.service.onDescriptorWrite"
const val ACTION_GATT_CONNECTED = "com.jstylelife.ble.service.ACTION_GATT_CONNECTED"
const val ACTION_GATT_DISCONNECTED = "com.jstylelife.ble.service.ACTION_GATT_DISCONNECTED"
const val ACTION_DATA_AVAILABLE = "com.jstylelife.ble.service.ACTION_DATA_AVAILABLE"
private val arrayGatts = ArrayList() // 存放BluetoothGatt的集�?
var colorCharacteristic: BluetoothGattCharacteristic? = null
private var bleServiceInstance: BleService? = null
fun getInstance(): BleService? {
return bleServiceInstance
}
}
}
\ No newline at end of file
diff --git a/lib/pages/medical/my_trackers/ble_device_type_screens/ble_devices_screen.dart b/lib/pages/medical/my_trackers/ble_device_type_screens/ble_devices_screen.dart
index 7f801a77..07bd5419 100644
--- a/lib/pages/medical/my_trackers/ble_device_type_screens/ble_devices_screen.dart
+++ b/lib/pages/medical/my_trackers/ble_device_type_screens/ble_devices_screen.dart
@@ -30,6 +30,7 @@ class _BleDevicesScreenState extends State {
@override
void dispose() {
FlutterBluePlus.stopScan();
+ myTrackersVm.stopNativeScan();
myTrackersVm.resetList();
super.dispose();
}
diff --git a/lib/pages/medical/my_trackers/ble_device_type_screens/checkme_all_in-one_connect_screen.dart b/lib/pages/medical/my_trackers/ble_device_type_screens/checkme_all_in-one_connect_screen.dart
index a079c2da..56b32ada 100644
--- a/lib/pages/medical/my_trackers/ble_device_type_screens/checkme_all_in-one_connect_screen.dart
+++ b/lib/pages/medical/my_trackers/ble_device_type_screens/checkme_all_in-one_connect_screen.dart
@@ -85,6 +85,7 @@ class _CheckMeAllInOneConnectScreenState extends State onTrackerTypePressed(TrackerTypeEnum trackerTypeEnum, MyTrackersViewModel myTrackersViewModel) async {
- switch (trackerTypeEnum) {
- case TrackerTypeEnum.BloodPressureTracker:
- case TrackerTypeEnum.BloodSugarTracker:
+ Future onTrackerTypePressed(SmartRingOperationsEnum smartRingOperationsEnum, MyTrackersViewModel myTrackersViewModel) async {
+ switch (smartRingOperationsEnum) {
+ case SmartRingOperationsEnum.Temperature:
+ myTrackersViewModel.getTemperatureSmartRing();
+ Navigator.of(context).push(FadePage(page: SmartRingInfoScreen(smartRingOperationsEnum)));
break;
- case TrackerTypeEnum.OxymeterTracker:
+ case SmartRingOperationsEnum.HeartRateStatic:
+ myTrackersViewModel.getStaticHeartRateSmartRing();
+ Navigator.of(context).push(FadePage(page: SmartRingInfoScreen(smartRingOperationsEnum)));
break;
- case TrackerTypeEnum.ECGTracker:
- myTrackersViewModel.getBatteryLevelSmartRing();
+ case SmartRingOperationsEnum.HeartRateDynamic:
+ myTrackersViewModel.getDynamicHeartRateSmartRing();
+ Navigator.of(context).push(FadePage(page: SmartRingInfoScreen(smartRingOperationsEnum)));
+ break;
+ case SmartRingOperationsEnum.HRV:
+ myTrackersViewModel.getHRVSmartRing();
+ Navigator.of(context).push(FadePage(page: SmartRingInfoScreen(smartRingOperationsEnum)));
break;
- case TrackerTypeEnum.Temperature:
+ case SmartRingOperationsEnum.BloodOxygen:
+ myTrackersViewModel.getBloodOxygenSmartRing();
+ // Navigator.of(context).push(FadePage(page: SmartRingInfoScreen(smartRingOperationsEnum)));
+ break;
+ case SmartRingOperationsEnum.BatteryLevel:
+ myTrackersViewModel.getBatteryLevelSmartRing();
+ Navigator.of(context).push(FadePage(page: SmartRingInfoScreen(smartRingOperationsEnum)));
break;
- case TrackerTypeEnum.Spirometer:
- case TrackerTypeEnum.WeightScale:
- case TrackerTypeEnum.SmartRing:
- case TrackerTypeEnum.AllInOneTracker:
+ default:
break;
}
}
@@ -87,7 +91,7 @@ class _SmartRingAllInOneConnectScreenState extends State SizedBox(height: 14),
+ shrinkWrap: true,
+ reverse: false,
+ itemBuilder: (context, index) {
+ SmartRingGenericModel smartRingTemp = myTrackersVm.smartRingTemperatureHistory[index];
+ return InkWell(
+ onTap: () => Navigator.pop(context),
+ child: Container(
+ decoration: cardRadius(12),
+ padding: EdgeInsets.all(12.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text("Temperature: ${smartRingTemp.value}"),
+ mHeight(4.0),
+ Text("Date: ${smartRingTemp.date}"),
+ ],
+ ),
+ ),
+ );
+ },
+ ),
+ );
+ } else {
+ return getNoDataWidget(context);
+ }
+ }
+
+ Widget buildHeartRateDynamicWidget(MyTrackersViewModel myTrackersVm, BuildContext context) {
+ if (myTrackersVm.filesLoader) {
+ return Center(child: CircularProgressIndicator());
+ } else if (myTrackersVm.smartRingHeartRateDynamicHistory != null && myTrackersVm.smartRingHeartRateDynamicHistory.isNotEmpty) {
+ return Expanded(
+ child: ListView.separated(
+ itemCount: myTrackersVm.smartRingHeartRateDynamicHistory.length,
+ separatorBuilder: (context, index) => SizedBox(height: 14),
+ shrinkWrap: true,
+ reverse: false,
+ itemBuilder: (context, index) {
+ SmartRingGenericModel smartRingHr = myTrackersVm.smartRingHeartRateDynamicHistory[index];
+ return InkWell(
+ onTap: () => Navigator.pop(context),
+ child: Container(
+ decoration: cardRadius(12),
+ padding: EdgeInsets.all(12.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text("arrayDynamicHR: ${smartRingHr.value}"),
+ mHeight(4.0),
+ Text("Date: ${smartRingHr.date}"),
+ ],
+ ),
+ ),
+ );
+ },
+ ),
+ );
+ } else {
+ return getNoDataWidget(context);
+ }
+ }
+
+ Widget buildHeartRateStaticWidget(MyTrackersViewModel myTrackersVm, BuildContext context) {
+ if (myTrackersVm.filesLoader) {
+ return Center(child: CircularProgressIndicator());
+ } else if (myTrackersVm.smartRingHeartRateStaticHistory != null && myTrackersVm.smartRingHeartRateStaticHistory.isNotEmpty) {
+ return Expanded(
+ child: ListView.separated(
+ itemCount: myTrackersVm.smartRingHeartRateStaticHistory.length,
+ separatorBuilder: (context, index) => SizedBox(height: 14),
+ shrinkWrap: true,
+ reverse: false,
+ itemBuilder: (context, index) {
+ SmartRingGenericModel smartRingHr = myTrackersVm.smartRingHeartRateStaticHistory[index];
+ return InkWell(
+ onTap: () => Navigator.pop(context),
+ child: Container(
+ decoration: cardRadius(12),
+ padding: EdgeInsets.all(12.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text("onceHeartValue: ${smartRingHr.value}"),
+ mHeight(4.0),
+ Text("Date: ${smartRingHr.date}"),
+ ],
+ ),
+ ),
+ );
+ },
+ ),
+ );
+ } else {
+ return getNoDataWidget(context);
+ }
+ }
+
+ Widget buildHrvWidget(MyTrackersViewModel myTrackersVm, BuildContext context) {
+ if (myTrackersVm.filesLoader) {
+ return Center(child: CircularProgressIndicator());
+ } else if (myTrackersVm.smartRingHrvHistory != null && myTrackersVm.smartRingHrvHistory.isNotEmpty) {
+ return Expanded(
+ child: ListView.separated(
+ itemCount: myTrackersVm.smartRingHrvHistory.length,
+ separatorBuilder: (context, index) => SizedBox(height: 14),
+ shrinkWrap: true,
+ reverse: false,
+ itemBuilder: (context, index) {
+ SmartRingHrvModel smartRingHrvModel = myTrackersVm.smartRingHrvHistory[index];
+ return InkWell(
+ onTap: () => Navigator.pop(context),
+ child: Container(
+ decoration: cardRadius(12),
+ padding: EdgeInsets.all(12.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text("highBP: ${smartRingHrvModel.highBP}"),
+ mHeight(4.0),
+ Text("lowBP: ${smartRingHrvModel.lowBP}"),
+ mHeight(4.0),
+ Text("stress: ${smartRingHrvModel.stress}"),
+ mHeight(4.0),
+ Text("heartRate: ${smartRingHrvModel.heartRate}"),
+ mHeight(4.0),
+ Text("hrv: ${smartRingHrvModel.hrv}"),
+ mHeight(4.0),
+ Text("vascularAging: ${smartRingHrvModel.vascularAging}"),
+ ],
+ ),
+ ),
+ );
+ },
+ ),
+ );
+ } else {
+ return getNoDataWidget(context);
+ }
+ }
+
+ Widget buildBatteryLevelWidget(MyTrackersViewModel myTrackersVm, BuildContext context) {
+ if (myTrackersVm.filesLoader) {
+ return Center(child: CircularProgressIndicator());
+ } else if (myTrackersVm.smartRingBatteryLevel != null && myTrackersVm.smartRingBatteryLevel.isNotEmpty) {
+ return Center(
+ child: Text("Battery Level: ${myTrackersVm.smartRingBatteryLevel}"),
+ );
+ } else {
+ return getNoDataWidget(context);
+ }
+ }
+
+ Widget buildECGWidget(MyTrackersViewModel myTrackersVm, BuildContext context) {
+ return Column(
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ if (myTrackersVm.filesLoader) ...[
+ Center(child: CircularProgressIndicator())
+ ] else if (myTrackersVm.checkMeEcg != null && myTrackersVm.checkMeEcg.isNotEmpty) ...[
+ Material(
+ child: ListView.separated(
+ itemCount: myTrackersVm.checkMeEcg.length,
+ separatorBuilder: (context, index) => SizedBox(height: 14),
+ shrinkWrap: true,
+ reverse: false,
+ itemBuilder: (context, index) {
+ CheckMeECGModel checkMeECGModel = myTrackersVm.checkMeEcg[index];
+ return InkWell(
+ onTap: () {
+ myTrackersVm.getEcgWaveDataFromCheckMePro(checkMeECGModel.timeString);
+ // Navigator.push(context, MaterialPageRoute(builder: (context) => CheckMeECGInfoScreen(SmartRingOperationsEnum.ECGTracker)));
+ },
+ child: Container(
+ decoration: cardRadius(12),
+ padding: EdgeInsets.all(12.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text("Date: ${checkMeECGModel.date}"),
+ mHeight(8),
+ Text("TimeString: ${checkMeECGModel.timeString}"),
+ ],
+ ),
+ ),
+ );
+ },
+ ),
+ )
+ ] else ...[
+ getNoDataWidget(context),
+ ]
+ ],
+ );
+ }
+
+ Widget buildOxiWidget(MyTrackersViewModel myTrackersVm, BuildContext context) {
+ return Column(
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ if (myTrackersVm.filesLoader) ...[
+ Center(child: CircularProgressIndicator())
+ ] else if (myTrackersVm.checkMeOxi != null && myTrackersVm.checkMeOxi.isNotEmpty) ...[
+ Material(
+ child: ListView.separated(
+ itemCount: myTrackersVm.checkMeOxi.length,
+ separatorBuilder: (context, index) => SizedBox(height: 14),
+ shrinkWrap: true,
+ reverse: false,
+ itemBuilder: (context, index) {
+ CheckMeOxiModel checkMeOxiModel = myTrackersVm.checkMeOxi[index];
+ return InkWell(
+ onTap: () => Navigator.pop(context),
+ child: Container(
+ decoration: cardRadius(12),
+ padding: EdgeInsets.all(12.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text("PR: ${checkMeOxiModel.pr} PI: ${checkMeOxiModel.pi}"),
+ mHeight(4.0),
+ Text("Oxi: ${checkMeOxiModel.oxy}"),
+ mHeight(4.0),
+ Text("Date: ${checkMeOxiModel.date}"),
+ ],
+ ),
+ ),
+ );
+ },
+ ),
+ )
+ ] else ...[
+ getNoDataWidget(context),
+ ]
+ ],
+ );
+ }
+
+ Widget buildBPWidget(MyTrackersViewModel myTrackersVm, BuildContext context) {
+ return Column(
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ if (myTrackersVm.filesLoader) ...[
+ Center(child: CircularProgressIndicator())
+ ] else if (myTrackersVm.checkMeBP != null && myTrackersVm.checkMeBP.isNotEmpty) ...[
+ Material(
+ child: ListView.separated(
+ itemCount: myTrackersVm.checkMeBP.length,
+ separatorBuilder: (context, index) => SizedBox(height: 14),
+ shrinkWrap: true,
+ reverse: false,
+ itemBuilder: (context, index) {
+ CheckMeBPModel checkMeBPModel = myTrackersVm.checkMeBP[index];
+ return InkWell(
+ onTap: () => Navigator.pop(context),
+ child: Container(
+ decoration: cardRadius(12),
+ padding: EdgeInsets.all(12.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text("DIA: ${checkMeBPModel.dia} SYS: ${checkMeBPModel.sys}"),
+ mHeight(4.0),
+ Text("PR: ${checkMeBPModel.pr}"),
+ mHeight(4.0),
+ Text("Date: ${checkMeBPModel.date}"),
+ ],
+ ),
+ ),
+ );
+ },
+ ),
+ )
+ ] else ...[
+ getNoDataWidget(context),
+ ]
+ ],
+ );
+ }
+
+ Widget buildGlucoseWidget(MyTrackersViewModel myTrackersVm, BuildContext context) {
+ return Column(
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ if (myTrackersVm.filesLoader) ...[
+ Center(child: CircularProgressIndicator())
+ ] else if (myTrackersVm.checkMeGlucose != null && myTrackersVm.checkMeGlucose.isNotEmpty) ...[
+ Material(
+ child: ListView.separated(
+ itemCount: myTrackersVm.checkMeGlucose.length,
+ separatorBuilder: (context, index) => SizedBox(height: 14),
+ shrinkWrap: true,
+ reverse: false,
+ itemBuilder: (context, index) {
+ CheckMeGlucoseModel checkMeGlucoseModel = myTrackersVm.checkMeGlucose[index];
+ return InkWell(
+ onTap: () => null,
+ child: Container(
+ decoration: cardRadius(12),
+ padding: EdgeInsets.all(12.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text("Glucose: ${checkMeGlucoseModel.glu}"),
+ mHeight(4.0),
+ Text("Date: ${checkMeGlucoseModel.date}"),
+ ],
+ ),
+ ),
+ );
+ },
+ ),
+ )
+ ] else ...[
+ getNoDataWidget(context),
+ ]
+ ],
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return AppScaffold(
+ appBarTitle: "${getTrackerNameByEnum(smartRingOperationsEnum)}",
+ showNewAppBar: true,
+ isShowDecPage: false,
+ showNewAppBarTitle: true,
+ backgroundColor: Color(0xffF8F8F8),
+ body: Padding(
+ padding: const EdgeInsets.all(24.0),
+ child: Column(
+ children: [
+ Consumer(
+ builder: (BuildContext context, MyTrackersViewModel myTrackersVm, Widget child) {
+ return getAllInOneOperationWidgets(myTrackersVm, smartRingOperationsEnum, context);
+ },
+ ),
+ ],
+ )),
+ );
+ }
+}
diff --git a/lib/pages/medical/my_trackers/ble_helpers/ble_connect_helper.dart b/lib/pages/medical/my_trackers/ble_helpers/ble_connect_helper.dart
index b0a7ad87..261a0c7a 100644
--- a/lib/pages/medical/my_trackers/ble_helpers/ble_connect_helper.dart
+++ b/lib/pages/medical/my_trackers/ble_helpers/ble_connect_helper.dart
@@ -18,7 +18,7 @@ class BleChannel {
result = await platform.invokeMethod('scanForCheckMePro');
print("----------Flutter scanCheckMeProNative Result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -33,7 +33,7 @@ class BleChannel {
result = await platform.invokeMethod('scanDevices', deviceType);
print("----------Flutter Result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -49,7 +49,7 @@ class BleChannel {
result = await platform.invokeMethod('stopScanCheckMe');
print("----------Flutter Result stopNativeScan -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -64,7 +64,7 @@ class BleChannel {
result = await platform.invokeMethod('connectDevice', device);
print("----------Flutter Result connectDevice -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -79,7 +79,7 @@ class BleChannel {
result = await platform.invokeMethod('connectDeviceCheckMe', device);
print("----------Flutter Result connectDeviceCheckMe -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -91,7 +91,7 @@ class BleChannel {
print("----------Flutter getECGFilesList -------");
final String result = await platform.invokeMethod('ecgFilesList', device);
print("----------Flutter Result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -103,7 +103,7 @@ class BleChannel {
print("----------Flutter duoEkFactoryReset -------");
final String result = await platform.invokeMethod('factoryResetECG', device);
print("----------Flutter Result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -115,7 +115,7 @@ class BleChannel {
print("----------Flutter getBP2FilesList -------");
final String result = await platform.invokeMethod('bp2FilesList', deviceType);
print("----------Flutter Result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -128,7 +128,7 @@ class BleChannel {
final String result = await platform.invokeMethod('disconnectDevice');
final String result2 = await platform.invokeMethod('disconnectCheckMe');
print("----------Flutter Result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -140,7 +140,7 @@ class BleChannel {
print("----------Flutter getDeviceInfoCheckMePro -------");
final String result = await platform.invokeMethod('getDeviceInfoCheckMePro');
print("----------Flutter getDeviceInfoCheckMePro result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -152,7 +152,7 @@ class BleChannel {
print("----------Flutter getDeviceInfoCheckMePro -------");
final String result = await platform.invokeMethod('getGlucoseDataFromCheckMePro', userId);
print("----------Flutter getDeviceInfoCheckMePro result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -164,7 +164,7 @@ class BleChannel {
print("----------Flutter getBPDataFromCheckMePro -------");
final String result = await platform.invokeMethod('getBPDataFromCheckMePro', userId);
print("----------Flutter getBPDataFromCheckMePro result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -176,7 +176,7 @@ class BleChannel {
print("----------Flutter getOxiDataFromCheckMePro -------");
final String result = await platform.invokeMethod('getOxiDataFromCheckMePro');
print("----------Flutter getOxiDataFromCheckMePro result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -188,7 +188,7 @@ class BleChannel {
print("----------Flutter getTempDataFromCheckMePro -------");
final String result = await platform.invokeMethod('getTempDataFromCheckMePro');
print("----------Flutter getTempDataFromCheckMePro result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -200,7 +200,7 @@ class BleChannel {
print("----------Flutter getEcgDataFromCheckMePro -------");
final String result = await platform.invokeMethod('getEcgDataFromCheckMePro');
print("----------Flutter getEcgDataFromCheckMePro result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -212,7 +212,7 @@ class BleChannel {
print("----------Flutter getEcgWaveFromCheckMePro -------");
final String result = await platform.invokeMethod('getEcgWaveFromCheckMePro', timeString);
print("----------Flutter getEcgWaveFromCheckMePro result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -229,7 +229,7 @@ class BleChannel {
result = await platform.invokeMethod('scanForSmartRing');
print("----------Flutter scanForSmartRing Result -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -244,7 +244,7 @@ class BleChannel {
result = await platform.invokeMethod('connectDeviceSmartRing', deviceAddress);
print("----------Flutter Result connectDeviceSmartRing -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -259,7 +259,7 @@ class BleChannel {
result = await platform.invokeMethod('disConnectDeviceSmartRing');
print("----------Flutter Result disConnectDeviceSmartRing -------");
- print(result);
+
return result;
} catch (e) {
return "Error: $e";
@@ -271,10 +271,72 @@ class BleChannel {
print("----------Flutter getBatteryLevelSmartRing -------");
final String result = await platform.invokeMethod('getBatteryLevelSmartRing');
print("----------Flutter getBatteryLevelSmartRing result -------");
- print(result);
+
+ return result;
+ } catch (e) {
+ return "Error: $e";
+ }
+ }
+
+ static Future getTemperatureSmartRing() async {
+ try {
+ print("----------Flutter getTemperatureSmartRing -------");
+ final String result = await platform.invokeMethod('getTemperatureSmartRing');
+ print("----------Flutter getTemperatureSmartRing result -------");
+
+ return result;
+ } catch (e) {
+ return "Error: $e";
+ }
+ }
+
+ static Future getDynamicHeartRateSmartRing() async {
+ try {
+ print("----------Flutter getDynamicHeartRateSmartRing -------");
+ final String result = await platform.invokeMethod('getDynamicHeartRateSmartRing');
+ print("----------Flutter getDynamicHeartRateSmartRing result -------");
+
+ return result;
+ } catch (e) {
+ return "Error: $e";
+ }
+ }
+
+ static Future getStaticHeartRateSmartRing() async {
+ try {
+ print("----------Flutter getStaticHeartRateSmartRing -------");
+ final String result = await platform.invokeMethod('getStaticHeartRateSmartRing');
+ print("----------Flutter getStaticHeartRateSmartRing result -------");
+
return result;
} catch (e) {
return "Error: $e";
}
}
+
+ static Future getHRVSmartRing() async {
+ try {
+ print("----------Flutter getHRVSmartRing -------");
+ final String result = await platform.invokeMethod('getHRVSmartRing');
+ print("----------Flutter getHRVSmartRing result -------");
+
+ return result;
+ } catch (e) {
+ return "Error: $e";
+ }
+ }
+
+ static Future getBloodOxygenSmartRing() async {
+ try {
+ print("----------Flutter getBloodOxygenSmartRing -------");
+ final String result = await platform.invokeMethod('getBloodOxygenSmartRing');
+ print("----------Flutter getBloodOxygenSmartRing result -------");
+
+ return result;
+ } catch (e) {
+ return "Error: $e";
+ }
+ }
+
+
}
diff --git a/lib/pages/medical/my_trackers/ble_models/ble_devices_model.dart b/lib/pages/medical/my_trackers/ble_models/ble_devices_model.dart
index 11f528a3..86e403a9 100644
--- a/lib/pages/medical/my_trackers/ble_models/ble_devices_model.dart
+++ b/lib/pages/medical/my_trackers/ble_models/ble_devices_model.dart
@@ -11,12 +11,12 @@ class BleDeviceModel {
BleDeviceModel({this.macAddr, this.model, this.name, this.rssi, this.andesfitBluetoothDevice});
- BleDeviceModel.fromJson(Map json) {
+ BleDeviceModel.fromJson(Map json, TrackerTypeEnum trackerType) {
macAddr = json['macAddr'];
model = json['model'];
name = json['name'];
rssi = json['rssi'];
- deviceType = TrackerTypeEnum.AllInOneTracker;
+ deviceType = trackerType;
andesfitBluetoothDevice = null;
}
diff --git a/lib/pages/medical/my_trackers/ble_models/smart_ring_models.dart b/lib/pages/medical/my_trackers/ble_models/smart_ring_models.dart
new file mode 100644
index 00000000..491a4c69
--- /dev/null
+++ b/lib/pages/medical/my_trackers/ble_models/smart_ring_models.dart
@@ -0,0 +1,76 @@
+//TEMPERATURE
+
+import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart';
+
+String getValueKeyBySmartRingOperation(SmartRingOperationsEnum smartRingOperationsEnum) {
+ switch (smartRingOperationsEnum) {
+ case SmartRingOperationsEnum.Temperature:
+ return "temperature";
+ case SmartRingOperationsEnum.HeartRateStatic:
+ return "onceHeartValue";
+ case SmartRingOperationsEnum.HeartRateDynamic:
+ return "arrayDynamicHR";
+ case SmartRingOperationsEnum.HRV:
+ // TODO: Handle this case.
+ break;
+ case SmartRingOperationsEnum.BloodOxygen:
+ // TODO: Handle this case.
+ break;
+ case SmartRingOperationsEnum.BatteryLevel:
+ return "batteryLevel";
+ }
+ return "batteryLevel";
+}
+
+class SmartRingGenericModel {
+ DateTime date;
+ String value;
+
+ SmartRingGenericModel({this.date, this.value});
+
+ SmartRingGenericModel.fromJson(Map json, SmartRingOperationsEnum smartRingOperationsEnum) {
+ date = json['date'] != null ? DateTime.parse(((json["date"] as String).replaceAll(".", "-"))) : DateTime.now();
+ value = json['${getValueKeyBySmartRingOperation(smartRingOperationsEnum)}'];
+ }
+
+ Map toJson(SmartRingOperationsEnum smartRingOperationsEnum) {
+ final Map data = new Map();
+ data['date'] = this.date;
+ data['arrayDynamicHR'] = getValueKeyBySmartRingOperation(smartRingOperationsEnum);
+ return data;
+ }
+}
+
+class SmartRingHrvModel {
+ String date;
+ String highBP;
+ String stress;
+ String lowBP;
+ String heartRate;
+ String hrv;
+ String vascularAging;
+
+ SmartRingHrvModel({this.date, this.highBP, this.stress, this.lowBP, this.heartRate, this.hrv, this.vascularAging});
+
+ SmartRingHrvModel.fromJson(Map json) {
+ date = json['date'];
+ highBP = json['highBP'];
+ stress = json['stress'];
+ lowBP = json['lowBP'];
+ heartRate = json['heartRate'];
+ hrv = json['hrv'];
+ vascularAging = json['vascularAging'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['date'] = this.date;
+ data['highBP'] = this.highBP;
+ data['stress'] = this.stress;
+ data['lowBP'] = this.lowBP;
+ data['heartRate'] = this.heartRate;
+ data['hrv'] = this.hrv;
+ data['vascularAging'] = this.vascularAging;
+ return data;
+ }
+}
diff --git a/lib/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart b/lib/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart
index ae4e4f79..f708d27f 100644
--- a/lib/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart
+++ b/lib/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart
@@ -14,6 +14,7 @@ import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkm
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_oxi_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_temperature_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/checkmepro_all_in_one_models/checkme_user_model.dart';
+import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/smart_ring_models.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/viatom_devices/bp_rt_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/viatom_devices/ecg_file_detail_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/viatom_devices/ecg_rt_model.dart';
@@ -25,7 +26,6 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
import 'package:flutter/services.dart';
-import 'package:flutter/cupertino.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_helpers/ble_connect_helper.dart';
@@ -34,6 +34,8 @@ import 'package:provider/provider.dart';
enum TrackerTypeEnum { OxymeterTracker, BloodPressureTracker, BloodSugarTracker, ECGTracker, WeightScale, Temperature, Spirometer, SmartRing, AllInOneTracker }
+enum SmartRingOperationsEnum { Temperature, HeartRateStatic, HeartRateDynamic, HRV, BloodOxygen, BatteryLevel }
+
//NativeEventNames
String kRealTimeDataBPMeasuring = "RealTimeDataBPMeasuring";
@@ -55,6 +57,11 @@ String kBPCheckMePro = "BPCheckMePro";
String kDevicesListSmartRing = "DevicesListSmartRing";
String kBatteryLevelSmartRing = "BatteryLevelSmartRing";
+String kTemperatureSmartRing = "TemperatureSmartRing";
+String kDynamicHeartRateSmartRing = "DynamicHeartRateSmartRing";
+String kStaticHeartRateSmartRing = "StaticHeartRateSmartRing";
+String kHrvSmartRing = "HrvSmartRing";
+String kBloodOxygenSmartRing = "BloodOxygenSmartRing";
class MyTrackersViewModel extends ChangeNotifier {
EventChannel eventChannel = EventChannel('BLE-Platform-Bridge-Event');
@@ -90,7 +97,7 @@ class MyTrackersViewModel extends ChangeNotifier {
{"model": "BLE-MSA"},
],
"SmartRing": [
- {"model": ""},
+ {"model": "2301A"},
],
"AllInOneTracker": [
{"model": "Checkme 1316"},
@@ -120,7 +127,7 @@ class MyTrackersViewModel extends ChangeNotifier {
{"model": "BLE-MSA"},
],
"SmartRing": [
- {"model": "2301A"},
+ {"model": ""},
],
"AllInOneTracker": [
{"model": "Checkme 1316"},
@@ -136,11 +143,13 @@ class MyTrackersViewModel extends ChangeNotifier {
TrackerTypeEnum.BloodSugarTracker,
TrackerTypeEnum.ECGTracker,
];
- List smartRingTrackers = [
- TrackerTypeEnum.Temperature,
- TrackerTypeEnum.OxymeterTracker,
- TrackerTypeEnum.BloodSugarTracker,
- TrackerTypeEnum.ECGTracker,
+ List smartRingTrackers = [
+ SmartRingOperationsEnum.Temperature,
+ SmartRingOperationsEnum.HeartRateStatic,
+ SmartRingOperationsEnum.HeartRateDynamic,
+ SmartRingOperationsEnum.HRV,
+ SmartRingOperationsEnum.BloodOxygen,
+ SmartRingOperationsEnum.BatteryLevel,
];
List andesFitDevices = [
@@ -358,7 +367,7 @@ class MyTrackersViewModel extends ChangeNotifier {
// if(Platform.isIOS) {
// parsesDevicesList(json.decode(event['data']));
// } else if(Platform.isAndroid) {
- parsesDevicesList(json.decode(event['data']) as List);
+ parsesDevicesList(json.decode(event['data']) as List, currentSelectedTrackerType);
// }
}
@@ -406,8 +415,8 @@ class MyTrackersViewModel extends ChangeNotifier {
await scanDevicesNative(currentSelectedTrackerType);
}
- void parsesDevicesList(List returnData) {
- var devicesList = List.generate(returnData.length, (index) => BleDeviceModel.fromJson(returnData[index]));
+ void parsesDevicesList(List returnData, TrackerTypeEnum trackerType) {
+ var devicesList = List.generate(returnData.length, (index) => BleDeviceModel.fromJson(returnData[index], trackerType));
log("devicesList: ${devicesList.toString()}");
filterOutTheSearchedDevicesNative(devicesList);
}
@@ -433,7 +442,7 @@ class MyTrackersViewModel extends ChangeNotifier {
if (currentSelectedTrackerType == TrackerTypeEnum.AllInOneTracker) {
await BleChannel.connectDeviceCheckMe([device.name, device.model.toString(), currentSelectedTrackerType.name]);
} else if (currentSelectedTrackerType == TrackerTypeEnum.SmartRing) {
- await BleChannel.connectDeviceSmartRing("CA:59:D9:7E:3E:D6"); //TODO: NEED TO VERIFY IF IT KEEPS CHANGING OR NO
+ await BleChannel.connectDeviceSmartRing(device.macAddr);
} else {
await BleChannel.connectDevice([device.name, device.model.toString(), currentSelectedTrackerType.name]);
}
@@ -1125,9 +1134,9 @@ class MyTrackersViewModel extends ChangeNotifier {
if (event['type'] == kDevicesListCheckMe) {
if (Platform.isAndroid) {
List list = [json.decode(event['data'])];
- parsesDevicesList(list);
+ parsesDevicesList(list, currentSelectedTrackerType);
} else {
- parsesDevicesList(json.decode(event['data']));
+ parsesDevicesList(json.decode(event['data']), currentSelectedTrackerType);
}
}
if (event['type'] == kCheckMeUsersList) {
@@ -1372,12 +1381,36 @@ class MyTrackersViewModel extends ChangeNotifier {
if (event['type'] == kDevicesListSmartRing) {
if (Platform.isAndroid) {
List list = [json.decode(event['data'])];
- parsesDevicesList(list);
+ parsesDevicesList(list, currentSelectedTrackerType);
} else {}
}
if (event['type'] == kBatteryLevelSmartRing) {
- updateCheckMeTemperatureInfoModel(json.decode(event['data']));
+ updateSmartRingBatteryLevelModel(json.decode(event['data']));
+ }
+
+ if (event['type'] == kTemperatureSmartRing) {
+ logger.i(event['data']);
+ updateSmartRingTemperatureHistory(json.decode(event['data']));
+ }
+
+ if (event['type'] == kBloodOxygenSmartRing) {
+ logger.i(event['data']);
+ }
+
+ if (event['type'] == kHrvSmartRing) {
+ logger.i(event['data']);
+ updateSmartRingHrvHistory(json.decode(event['data']));
+ }
+
+ if (event['type'] == kStaticHeartRateSmartRing) {
+ logger.i(event['data']);
+ updateSmartRingHeartRateStaticHistory(json.decode(event['data']));
+ }
+
+ if (event['type'] == kDynamicHeartRateSmartRing) {
+ logger.i(event['data']);
+ updateSmartRingHeartRateDynamicHistory(json.decode(event['data']));
}
});
@@ -1420,8 +1453,115 @@ class MyTrackersViewModel extends ChangeNotifier {
await device.connect(timeout: Duration(seconds: 35));
}
+ Future getTemperatureSmartRing() async {
+ if (smartRingTemperatureHistory != null) {
+ smartRingTemperatureHistory.clear();
+ smartRingTemperatureHistory = null;
+ }
+ String data = await BleChannel.getTemperatureSmartRing();
+ logger.i(jsonEncode(data.toString()));
+ }
+
Future getBatteryLevelSmartRing() async {
String data = await BleChannel.getBatteryLevelSmartRing();
logger.i(jsonEncode(data.toString()));
}
+
+ Future getDynamicHeartRateSmartRing() async {
+ String data = await BleChannel.getDynamicHeartRateSmartRing();
+ logger.i(jsonEncode(data.toString()));
+ }
+
+ Future getStaticHeartRateSmartRing() async {
+ String data = await BleChannel.getStaticHeartRateSmartRing();
+ logger.i(jsonEncode(data.toString()));
+ }
+
+ Future getHRVSmartRing() async {
+ String data = await BleChannel.getHRVSmartRing();
+ logger.i(jsonEncode(data.toString()));
+ }
+
+ Future getBloodOxygenSmartRing() async {
+ String data = await BleChannel.getBloodOxygenSmartRing();
+ logger.i(jsonEncode(data.toString()));
+ }
+
+ String smartRingBatteryLevel;
+
+ void updateSmartRingBatteryLevelModel(dynamic returnData) {
+ if (smartRingBatteryLevel != null) {
+ return;
+ }
+ Map data = returnData;
+ smartRingBatteryLevel = (data["dicData"]["batteryLevel"]).toString();
+ notifyListeners();
+ }
+
+ //TEMPERATURE
+
+ List smartRingTemperatureHistory;
+
+ void updateSmartRingTemperatureHistory(dynamic returnData) {
+ Map data = returnData;
+ List response = (data["dicData"]) as List;
+
+ List list = List.generate(response.length, (index) => SmartRingGenericModel.fromJson(response[index], SmartRingOperationsEnum.Temperature));
+ if (smartRingTemperatureHistory == null) {
+ smartRingTemperatureHistory = list;
+ } else {
+ smartRingTemperatureHistory.addAll(list);
+ }
+ notifyListeners();
+ }
+
+ //HEART RATE DYNAMIC
+
+ List smartRingHeartRateDynamicHistory;
+
+ void updateSmartRingHeartRateDynamicHistory(dynamic returnData) {
+ Map data = returnData;
+ List response = (data["dicData"]) as List;
+
+ List list = List.generate(response.length, (index) => SmartRingGenericModel.fromJson(response[index], SmartRingOperationsEnum.HeartRateDynamic));
+ if (smartRingHeartRateDynamicHistory == null) {
+ smartRingHeartRateDynamicHistory = list;
+ } else {
+ smartRingHeartRateDynamicHistory.addAll(list);
+ }
+ log("smartRingHeartRateDynamicHistory: ${smartRingHeartRateDynamicHistory.length}");
+ notifyListeners();
+ }
+
+ List smartRingHeartRateStaticHistory;
+
+ void updateSmartRingHeartRateStaticHistory(dynamic returnData) {
+ Map data = returnData;
+ List response = (data["dicData"]) as List;
+
+ List list = List.generate(response.length, (index) => SmartRingGenericModel.fromJson(response[index], SmartRingOperationsEnum.HeartRateStatic));
+ if (smartRingHeartRateStaticHistory == null) {
+ smartRingHeartRateStaticHistory = list;
+ } else {
+ smartRingHeartRateStaticHistory.addAll(list);
+ }
+ log("smartRingHeartRateStaticHistory: ${smartRingHeartRateStaticHistory.length}");
+ notifyListeners();
+ }
+
+ List smartRingHrvHistory;
+
+ void updateSmartRingHrvHistory(dynamic returnData) {
+ Map data = returnData;
+ List response = (data["dicData"]) as List;
+
+ List list = List.generate(response.length, (index) => SmartRingHrvModel.fromJson(response[index]));
+ if (smartRingHrvHistory == null) {
+ smartRingHrvHistory = list;
+ } else {
+ smartRingHrvHistory.addAll(list);
+ }
+ log("smartRingHrvHistory: ${smartRingHrvHistory.length}");
+ notifyListeners();
+ }
}