diff --git a/android/app/build.gradle b/android/app/build.gradle
index 774ae2fb..f911635e 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -129,7 +129,7 @@ dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
// Dependency on a remote binary
-// implementation 'com.example.android:app-magic:12.3'
+ // implementation 'com.example.android:app-magic:12.3'
// Native Dependency
@@ -146,7 +146,8 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
implementation 'androidx.work:work-runtime:2.7.0-alpha05'
androidTestImplementation "androidx.test:core:1.4.0"
-
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2"
+// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'
// Lepu Libraries
implementation 'no.nordicsemi.android:ble:2.2.4'
implementation(name: 'lepu-blepro-1.0.1', ext: 'aar')
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 036443f3..359c2843 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -71,7 +71,7 @@
+ // Handle the scan result here
+ Log.d("MainActivity", "Received scan result: $name, $bluetoothDevice")
+ }
+ }
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// val mChannel = NotificationChannel("video_call_noti", "video call", NotificationManager.IMPORTANCE_HIGH)
// val soundUri = Uri.parse("android.resource://" + getApplicationContext()
@@ -38,7 +44,7 @@ class MainActivity : FlutterFragmentActivity() {
// val time = timeToMillis("04:00:00", "HH:mm:ss")
- }
+}
// override fun onBleStateChanged(model: Int, state: Int) {
@@ -47,7 +53,3 @@ class MainActivity : FlutterFragmentActivity() {
//
// }
- override fun onResume() {
- super.onResume()
- }
-}
\ No newline at end of file
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 b4686dce..84bd9eb7 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
@@ -1,20 +1,26 @@
-package com.ejada.hmg.utils
+package com.cloud.diplomaticquarterapp.ble
import android.annotation.SuppressLint
+import android.bluetooth.BluetoothDevice
import android.os.Build
import android.os.Handler
-import com.ejada.hmg.MainActivity
+import android.util.Log
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.EventChannel
import android.util.SparseArray
import androidx.annotation.RequiresApi
-import com.cloud.diplomaticquarterapp.ble.BPModelMeasuring
-import com.cloud.diplomaticquarterapp.ble.BPModelResult
-import com.cloud.diplomaticquarterapp.ble.OxymeterModel
import com.cloud.diplomaticquarterapp.ble.utils.EcgData
import com.cloud.diplomaticquarterapp.ble.utils.HexString
+import com.cloud.diplomaticquarterapp.check_me_pro.UiChannel
+import com.cloud.diplomaticquarterapp.check_me_pro.bean.BleBean
+import com.cloud.diplomaticquarterapp.check_me_pro.bean.UserBean
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.format.UserInfo
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.manager.BleScanManager
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.worker.BleDataWorker
+import com.cloud.diplomaticquarterapp.utils.Constant
+import com.cloud.diplomaticquarterapp.MainActivity
import com.google.gson.Gson
@@ -33,17 +39,22 @@ import com.lepu.blepro.ext.er2.Er2EcgFile
import com.lepu.blepro.ext.er2.Er2File
import com.lepu.blepro.ext.er2.RtData
import com.lepu.blepro.ext.bp2.*
-import com.lepu.blepro.ext.er1.Er1Config
import com.lepu.blepro.ext.er1.Er1EcgFile
import com.lepu.blepro.ext.er1.Er1File
-import com.lepu.blepro.ext.er1.Er1HrFile
import com.lepu.blepro.ext.pc60fw.RtParam
import com.lepu.blepro.ext.sp20.RtWave
import com.lepu.blepro.objs.Bluetooth
import com.lepu.blepro.objs.BluetoothController
import com.lepu.blepro.utils.DateUtil
import com.lepu.blepro.utils.Er1Decompress
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withTimeoutOrNull
import org.apache.commons.io.FileUtils
+import org.json.JSONObject
import java.io.File
class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivity: MainActivity) {
@@ -54,6 +65,7 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
private var ecgFileNames = arrayListOf()
var ecgList: ArrayList = arrayListOf()
+ private val bleListCheckMe: MutableList = ArrayList()
val gson = Gson()
@@ -63,15 +75,52 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
private const val EVENTCHANNEL = "BLE-Platform-Bridge-Event"
private const val SCAN_DEVICE = "scanDevices"
private const val STOP_SCAN = "stopScan"
+ private const val STOP_SCAN_CHECK_ME = "stopScanCheckMe"
private const val CONNECT_DEVICE = "connectDevice"
+ private const val CONNECT_DEVICE_CHECK_ME = "connectDeviceCheckMe"
private const val SCAN_DEVICE_EKG = "scan_ekg"
private const val EKG_FILES_LIST = "ecgFilesList"
private const val FACTORY_RESET_ECG = "factoryResetECG"
private const val BP2_FILES_LIST = "bp2FilesList"
private const val DISCONNECT_DEVICE = "disconnectDevice"
+ private const val DISCONNECT_CHECK_ME = "disconnectCheckMe"
+ private const val READ_USER_CHECK_ME_PRO = "readUserCheckMePro"
+ private const val GET_DEVICE_INFO_CHECK_ME_PRO = "getDeviceInfoCheckMePro"
+ private const val SCAN_FOR_CHECK_ME_PRO = "scanForCheckMePro"
+ val scan = BleScanManager()
+ val dataScope = CoroutineScope(Dispatchers.IO)
+ val uiScope = CoroutineScope(Dispatchers.Main)
+
+
+ }
+
+ private val bleWorker = BleDataWorker { deviceInfoString ->
+ // Update eventSink in BleBridge
+ eventSink?.success(deviceInfoString)
}
+ var mUserData: MutableList = java.util.ArrayList()
+
+
+ private val userChannel = Channel(Channel.CONFLATED)
+
+
+ private var userFileName = arrayOf(
+ "dlc.dat", "ped.dat", "nibp.dat", "glu.dat"
+ )
+ private var commonFileName = arrayOf(
+ "bpcal.dat",
+ "ecg.dat",
+ "oxi.dat",
+ "tmp.dat",
+ "slm.dat",
+ )
+ var currentUser = 0
+
+ lateinit var userInfo: UserInfo
+
+
private val models = intArrayOf(
Bluetooth.MODEL_PC60FW, Bluetooth.MODEL_PC_60NW, Bluetooth.MODEL_PC_60NW_1,
Bluetooth.MODEL_PC66B, Bluetooth.MODEL_PF_10, Bluetooth.MODEL_PF_20,
@@ -171,7 +220,7 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
@SuppressLint("NewApi")
- fun create() {
+ fun createBleBridge(bleScanManager: BleScanManager, scanResultHandler: (String, BluetoothDevice) -> Unit) {
channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
Echannel = EventChannel(flutterEngine.dartExecutor.binaryMessenger, EVENTCHANNEL)
channel.setMethodCallHandler { methodCall: MethodCall, result: MethodChannel.Result ->
@@ -184,6 +233,12 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
connectDevice(methodCall.arguments as List)
} else if (methodCall.method == DISCONNECT_DEVICE) {
disconnectDevice(methodCall, result)
+ } else if (methodCall.method == STOP_SCAN_CHECK_ME) {
+ stopScanForCheckMePro()
+ } else if (methodCall.method == CONNECT_DEVICE_CHECK_ME) {
+ connectDeviceCheckMe(methodCall.arguments as List)
+ } else if (methodCall.method == DISCONNECT_CHECK_ME) {
+ disConnectDeviceCheckMe()
} else if (methodCall.method == SCAN_DEVICE_EKG) {
// scanDeviceEKG(methodCall, result)
} else if (methodCall.method == EKG_FILES_LIST) {
@@ -192,6 +247,12 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
factoryResetECG(methodCall.arguments as List)
} else if (methodCall.method == BP2_FILES_LIST) {
getBP2FilesList()
+ } else if (methodCall.method == SCAN_FOR_CHECK_ME_PRO) {
+ scanForCheckMePro(bleScanManager, scanResultHandler)
+ } else if (methodCall.method == READ_USER_CHECK_ME_PRO) {
+
+ } else if (methodCall.method == GET_DEVICE_INFO_CHECK_ME_PRO) {
+
} else {
result.notImplemented()
}
@@ -210,6 +271,10 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
}
+ private fun stopScanForCheckMePro() {
+ scan.stopScan();
+ }
+
@RequiresApi(Build.VERSION_CODES.Q)
fun disconnectDevice(methodCall: MethodCall, result: MethodChannel.Result) {
@@ -244,13 +309,80 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
}
}
+ @RequiresApi(Build.VERSION_CODES.M)
+ private fun scanForCheckMePro(bleScanManager: BleScanManager, scanResultHandler: (String, BluetoothDevice) -> Unit) {
+ bleScanManager.initScan(this.mainActivity)
+ bleScanManager.setCallBack(object : BleScanManager.Scan {
+ override fun scanReturn(name: String, bluetoothDevice: BluetoothDevice) {
+ onScanResult(name, bluetoothDevice)
+ }
+ })
+ }
- private fun stopScan() {
+ @SuppressLint("MissingPermission")
+ fun onScanResult(name: String, bluetoothDevice: BluetoothDevice) {
+ if (!(name.contains("Checkme"))) return;
+ var z: Int = 0;
+ for (ble in bleListCheckMe) run {
+ if (ble.name == bluetoothDevice.name) {
+ z = 1
+ }
+ }
+ if (z == 0) {
+ bleListCheckMe.add(BleBean(name, bluetoothDevice))
+
+ Log.d("CheckMeProDeviceFound", "This is the Device Name: $name")
+ val bluetoothDeviceJson = JSONObject().apply {
+ put("name", bluetoothDevice.name ?: "")
+ put("macAddr", bluetoothDevice.address ?: "")
+ put("type", bluetoothDevice.type)
+ // Add more properties as needed
+ }
+
+ println("EventDeviceFound : ${bluetoothDeviceJson.toString()}")
+
+ val returnData = mapOf("type" to "DevicesListCheckMe", "data" to bluetoothDeviceJson.toString())
+ eventSink?.success(returnData)
+
+ println(name)
+ }
+ }
+
+ private fun stopScan() {
BleServiceHelper.BleServiceHelper.stopScan()
}
+ private suspend fun readUserFromCheckMePro() {
+ userChannel.receive()
+ val userTemp = File(Constant.getPathX("usr.dat")).readBytes()
+ userTemp.apply {
+ userInfo = UserInfo(this)
+
+ val total = userInfo.user.size * 2 + 6 + 1
+ var tIndex = 1
+ UiChannel.progressChannel.send(tIndex * 100 / total)
+ for (user in userInfo.user) {
+ for (f in userFileName) {
+ bleWorker.getFile(user.id + f)
+ tIndex++
+ UiChannel.progressChannel.send(tIndex * 100 / total)
+ }
+ }
+ for (f in commonFileName) {
+ bleWorker.getFile(f)
+ tIndex++
+ UiChannel.progressChannel.send(tIndex * 100 / total)
+ }
+
+ delay(300)
+ UiChannel.progressChannel.close()
+
+ }
+ }
+
+
@RequiresApi(Build.VERSION_CODES.Q)
private fun subscribeToStreams(deviceName: String) {
@@ -544,17 +676,13 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
}
-
}
-
}
-
}
@RequiresApi(Build.VERSION_CODES.Q)
private fun connectDevice(device: List) {
-
println("connectDevice: $device");
model = device[1].toInt()
val deviceName = device[0]
@@ -572,9 +700,41 @@ class BleBridge(private var flutterEngine: FlutterEngine, private var mainActivi
}
+ }
+
+ private fun connectDeviceCheckMe(device: List) {
+ val currentBluetoothDevice = bleListCheckMe.first { bleBean ->
+ bleBean.name == device[0]
+ }
+ Log.d("DeviceFound", "This is the Device i have : ${currentBluetoothDevice.name}")
+// stopScanForCheckMePro()
+ bleWorker.initWorker(this.mainActivity, currentBluetoothDevice.bluetoothDevice)
+
+ uiScope.launch {
+ val a = withTimeoutOrNull(10000) {
+ bleWorker.waitConnect()
+ }
+// a?.let {
+// val b = withTimeoutOrNull(10000) {
+// bleWorker.getFile("usr.dat")
+// }
+// b?.let {
+// userChannel.send(1)
+// }
+// }
+ }
+
+
+// uiScope.launch {
+//// readUserFromCheckMePro()
+// getCheckMeProDeviceInfo()
+// }
+
}
+ private fun disConnectDeviceCheckMe() {}
+
private fun readFileForEr2() {
if (ecgFileNames.size == 0) {
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/UiChannel.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/UiChannel.kt
new file mode 100644
index 00000000..5f4c18d4
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/UiChannel.kt
@@ -0,0 +1,7 @@
+package com.cloud.diplomaticquarterapp.check_me_pro
+
+import kotlinx.coroutines.channels.Channel
+
+object UiChannel {
+ val progressChannel = Channel(Channel.CONFLATED)
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/BleBean.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/BleBean.kt
new file mode 100644
index 00000000..8833f420
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/BleBean.kt
@@ -0,0 +1,5 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.bean
+
+import android.bluetooth.BluetoothDevice
+
+data class BleBean(var name: String, var bluetoothDevice: BluetoothDevice)
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/BpBean.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/BpBean.kt
new file mode 100644
index 00000000..12fc1eac
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/BpBean.kt
@@ -0,0 +1,11 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.bean
+
+import java.util.*
+
+data class BpBean(
+ var date: Date = Date(),
+ var timeString: String = "",
+ var sys: Int = 0,
+ var dia: Int=0,
+ var pr: Int = 0
+)
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/DlcBean.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/DlcBean.kt
new file mode 100644
index 00000000..29a84374
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/DlcBean.kt
@@ -0,0 +1,17 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.bean
+
+import java.util.*
+
+data class DlcBean(
+ var date: Date = Date(),
+ var timeString: String = "",
+ var hr: Int = 0,
+ var eface: Int = 0,
+ var oxy: Int = 0,
+ var pi: Int = 0,
+ var oface: Int = 0,
+ var prFlag: Int = 0,
+ var pr: Int = 0,
+ var bpiFace: Int = 0,
+ var voice: Int = 0
+)
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/EcgBean.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/EcgBean.kt
new file mode 100644
index 00000000..50ed81c5
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/EcgBean.kt
@@ -0,0 +1,11 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.bean
+
+import java.util.*
+
+data class EcgBean(
+ var date: Date = Date(),
+ var timeString: String = "",
+ var way: Int = 0,
+ var face: Int = 0,
+ var voice: Int = 0
+)
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/GluBean.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/GluBean.kt
new file mode 100644
index 00000000..0a61f3b6
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/GluBean.kt
@@ -0,0 +1,10 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.bean
+
+import java.util.*
+
+data class GluBean(
+ var date: Date = Date(),
+ var timeString: String = "",
+ var glu:Float=0f,
+ var note:String=""
+)
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/OxyBean.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/OxyBean.kt
new file mode 100644
index 00000000..b12829e3
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/OxyBean.kt
@@ -0,0 +1,13 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.bean
+
+import java.util.*
+
+data class OxyBean(
+ var date: Date = Date(),
+ var timeString: String = "",
+ var way: Int = 0,
+ var oxy: Int = 0,
+ var pr: Int = 0,
+ var pi: Int = 0,
+ var face: Int = 0
+)
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/PedBean.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/PedBean.kt
new file mode 100644
index 00000000..36e6aa09
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/PedBean.kt
@@ -0,0 +1,52 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.bean
+
+import android.os.Parcel
+import android.os.Parcelable
+import java.util.*
+
+data class PedBean(
+ var date: Date = Date(),
+ var timeString: String? = "",
+ var step: Int = 0,
+ var dis: Float = 0f,
+ var speed: Float = 0f,
+ var cal: Float = 0f,
+ var fat: Float = 0f,
+ var time: Int = 0
+) : Parcelable {
+ constructor(parcel: Parcel) : this(
+ TODO("date"),
+ parcel.readString(),
+ parcel.readInt(),
+ parcel.readFloat(),
+ parcel.readFloat(),
+ parcel.readFloat(),
+ parcel.readFloat(),
+ parcel.readInt()
+ ) {
+ }
+
+ override fun writeToParcel(parcel: Parcel, flags: Int) {
+ parcel.writeString(timeString)
+ parcel.writeInt(step)
+ parcel.writeFloat(dis)
+ parcel.writeFloat(speed)
+ parcel.writeFloat(cal)
+ parcel.writeFloat(fat)
+ parcel.writeInt(time)
+ }
+
+ override fun describeContents(): Int {
+ return 0
+ }
+
+ companion object CREATOR : Parcelable.Creator {
+ override fun createFromParcel(parcel: Parcel): PedBean {
+ return PedBean(parcel)
+ }
+
+ override fun newArray(size: Int): Array {
+ return arrayOfNulls(size)
+ }
+ }
+}
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/SlpBean.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/SlpBean.kt
new file mode 100644
index 00000000..d2a06abe
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/SlpBean.kt
@@ -0,0 +1,15 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.bean
+
+import java.util.*
+
+data class SlpBean(
+ var date: Date = Date(),
+ var timeString: String = "",
+ var time: Int = 0,
+ var lowTime: Int = 0,
+ var lowCount: Int = 0,
+ var minO2: Int = 0,
+ var meanO2: Int = 0,
+ var face: Int = 0
+
+)
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/TmpBean.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/TmpBean.kt
new file mode 100644
index 00000000..5128c569
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/TmpBean.kt
@@ -0,0 +1,11 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.bean
+
+import java.util.*
+
+data class TmpBean(
+ var date: Date = Date(),
+ var timeString: String = "",
+ var way: Int = 0,
+ var tmp: Float = 0f,
+ var face: Int = 0
+)
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/UserBean.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/UserBean.kt
new file mode 100644
index 00000000..009c7856
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/bean/UserBean.kt
@@ -0,0 +1,14 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.bean
+
+import java.util.*
+
+data class UserBean(
+ var id: String = "",
+ var name: String = "",
+ var ico: Int = 0,
+ var sex: Int = 0,
+ var birthday: Date = Date(),
+ var weight: Int = 0,
+ var height: Int = 0,
+ var color: Int = 0
+)
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/constant/BTConstant.java b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/constant/BTConstant.java
new file mode 100644
index 00000000..627df162
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/constant/BTConstant.java
@@ -0,0 +1,40 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.constant;
+
+public class BTConstant {
+
+ // Bluetooth Command length
+ public final static int WRITE_CONTENT_PKG_DATA_LENGTH = 1024;
+ public final static int READ_CONTENT_ACK_DATA_LENGTH = 1024;
+ public final static int COMMON_PKG_LENGTH = 8;
+ public final static int COMMON_ACK_PKG_LENGTH = 12;
+ public final static int READ_CONTENT_ACK_PKG_FRONT_LENGTH = 8;
+ public final static int GET_INFO_ACK_PKG_LENGTH = 8 + 256;
+
+ public final static byte ACK_CMD_OK = 0;
+ public final static byte ACK_CMD_BAD = 1;
+
+ // Bluetooth Max file name length
+ public final static byte BT_WRITE_FILE_NAME_MAX_LENGTH = 30;
+ public final static byte BT_READ_FILE_NAME_MAX_LENGTH = 30;
+
+ // Bluetooth Command word
+ public final static byte CMD_WORD_START_WRITE = 0x00;
+ public final static byte CMD_WORD_WRITE_CONTENT = 0x01;
+ public final static byte CMD_WORD_END_WRITE = 0x02;
+ public final static byte CMD_WORD_START_READ = 0x03;
+ public final static byte CMD_WORD_READ_CONTENT = 0x04;
+ public final static byte CMD_WORD_END_READ = 0x05;
+ public final static byte CMD_WORD_DEL_FILE = 0x06;
+ public final static byte CMD_WORD_LIST_START = 0x07;
+ public final static byte CMD_WORD_LIST_DATA = 0x08;
+ public final static byte CMD_WORD_LIST_END = 0x09;
+ public final static byte CMD_WORD_LANG_UPDATE_START = 0x0A;
+ public final static byte CMD_WORD_LANG_UPDATE_DATA = 0x0B;
+ public final static byte CMD_WORD_LANG_UPDATE_END = 0x0C;
+ public final static byte CMD_WORD_APP_UPDATE_START = 0x0D;
+ public final static byte CMD_WORD_APP_UPDATE_DATA = 0x0E;
+ public final static byte CMD_WORD_APP_UPDATE_END = 0x0F;
+ public final static byte CMD_WORD_GET_INFO = 0x14;
+ public final static byte CMD_WORD_PING = 0x15;
+ public final static byte CMD_WORD_PARA_SYNC = 0x16;
+}
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/BpInfo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/BpInfo.kt
new file mode 100644
index 00000000..a8b89cff
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/BpInfo.kt
@@ -0,0 +1,58 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.format
+
+import com.cloud.diplomaticquarterapp.check_me_pro.bean.BpBean
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import java.util.*
+
+
+class BpInfo constructor(var bytes: ByteArray) {
+ var size: Int = bytes.size/11
+ var Bp: ArrayList = arrayListOf()
+
+
+ init {
+
+ var start: Int
+ for (k in 0 until size) {
+ start = k * 11
+ val year: Int = toUInt(setRange(start, 2))
+ val month: Int = toUInt(setRange(start + 2, 1)) - 1
+ val date: Int = toUInt(setRange(start + 3, 1))
+ val hour: Int = toUInt(setRange(start + 4, 1))
+ val minute: Int = toUInt(setRange(start + 5, 1))
+ val second: Int = toUInt(setRange(start + 6, 1))
+ val calendar = Calendar.getInstance()
+ calendar[Calendar.YEAR] = year
+ calendar[Calendar.MONTH] = month
+ calendar[Calendar.DATE] = date
+ calendar[Calendar.HOUR] = hour
+ calendar[Calendar.MINUTE] = minute
+ calendar[Calendar.SECOND] = second
+ Bp.add(BpBean())
+ Bp[k].apply {
+ this.date = calendar.time
+ timeString = String.format(
+ "%04d%02d%02d%02d%02d%02d",
+ year,
+ month + 1,
+ date,
+ hour,
+ minute,
+ second
+ )
+ sys = toUInt(setRange(start + 7, 2))
+ dia = toUInt(setRange(start + 9, 1))
+ pr = toUInt(setRange(start + 10, 1))
+ }
+ }
+
+
+ }
+
+ private fun setRange(start: Int, len: Int): ByteArray {
+ return bytes.copyOfRange(start, start + len)
+ }
+
+
+}
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/CheckMeResponse.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/CheckMeResponse.kt
new file mode 100644
index 00000000..5b3af112
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/CheckMeResponse.kt
@@ -0,0 +1,14 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.format
+
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import com.cloud.diplomaticquarterapp.utils.unsigned
+
+
+class CheckMeResponse(var bytes: ByteArray) {
+ var cmd: Int = bytes[1].unsigned()
+ var pkgNo: Int = toUInt(bytes.copyOfRange(3, 5))
+ var len: Int = toUInt(bytes.copyOfRange(5, 7))
+ var content: ByteArray = bytes.copyOfRange(7, 7 + len)
+}
+
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/DeviceInfo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/DeviceInfo.kt
new file mode 100644
index 00000000..229942d1
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/DeviceInfo.kt
@@ -0,0 +1,20 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.format
+
+import android.util.Log
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import org.json.JSONObject
+
+class DeviceInfo(buf: ByteArray) {
+ var len: Int = toUInt(buf.copyOfRange(5, 7))
+ var content: ByteArray = buf.copyOfRange(7, 7 + len)
+ var deviceStr: String = String(content)
+ var json: JSONObject
+
+ init {
+ Log.i("byteSize", buf.decodeToString())
+ Log.i("len::", len.toString())
+ deviceStr = deviceStr.substring(0, deviceStr.indexOf("}") + 1)
+ json = JSONObject(deviceStr)
+
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/DlcInfo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/DlcInfo.kt
new file mode 100644
index 00000000..b0175118
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/DlcInfo.kt
@@ -0,0 +1,69 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.format
+
+import com.cloud.diplomaticquarterapp.check_me_pro.bean.DlcBean
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import java.util.*
+
+
+class DlcInfo(var bytes: ByteArray) {
+ var size: Int = bytes.size / 17
+ var dlc: ArrayList = arrayListOf()
+
+
+ init {
+
+ var start: Int
+ for (k in 0 until size) {
+ start = k * 17
+ val year: Int = toUInt(setRange(start, 2))
+ val month: Int = toUInt(setRange(start + 2, 1))
+ val date: Int = toUInt(setRange(start + 3, 1))
+ val hour: Int = toUInt(setRange(start + 4, 1))
+ val minute: Int = toUInt(setRange(start + 5, 1))
+ val second: Int = toUInt(setRange(start + 6, 1))
+ val calendar = Calendar.getInstance()
+ calendar[Calendar.YEAR] = year
+ calendar[Calendar.MONTH] = month - 1
+ calendar[Calendar.DATE] = date
+ calendar[Calendar.HOUR] = hour
+ calendar[Calendar.MINUTE] = minute
+ calendar[Calendar.SECOND] = second
+ dlc.add(DlcBean())
+ dlc[k].apply {
+ this.date = calendar.time
+ timeString = String.format(
+ "%04d%02d%02d%02d%02d%02d",
+ year,
+ month,
+ date,
+ hour,
+ minute,
+ second
+ )
+ hr = toUInt(setRange(start + 7, 2))
+ eface = toUInt(setRange(start + 9, 1))
+ if (eface > 2) eface = 2
+ oxy = toUInt(setRange(start + 10, 1))
+ pi = toUInt(setRange(start + 11, 1))
+ oface = toUInt(setRange(start + 12, 1))
+ if (oface > 2) oface = 2
+ prFlag = toUInt(setRange(start + 13, 1))
+ pr = toUInt(setRange(start + 14, 1))
+ bpiFace = toUInt(setRange(start + 15, 1))
+ if (bpiFace > 2) bpiFace = 2
+ voice = toUInt(setRange(start + 16, 1))
+ }
+
+
+ }
+
+
+ }
+
+ private fun setRange(start: Int, len: Int): ByteArray {
+ return bytes.copyOfRange(start, start + len)
+ }
+
+
+}
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/EcgInfo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/EcgInfo.kt
new file mode 100644
index 00000000..1aa8332e
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/EcgInfo.kt
@@ -0,0 +1,60 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.format
+
+import com.cloud.diplomaticquarterapp.check_me_pro.bean.EcgBean
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import java.util.*
+
+
+class EcgInfo(var bytes: ByteArray) {
+ var size: Int = bytes.size / 10
+ var ecg: ArrayList = arrayListOf()
+
+
+ init {
+ var start: Int
+ for (k in 0 until size) {
+ start = k * 10
+ val year: Int = toUInt(setRange(start, 2))
+ val month: Int = toUInt(setRange(start + 2, 1)) - 1
+ val date: Int = toUInt(setRange(start + 3, 1))
+ val hour: Int = toUInt(setRange(start + 4, 1))
+ val minute: Int = toUInt(setRange(start + 5, 1))
+ val second: Int = toUInt(setRange(start + 6, 1))
+ val calendar = Calendar.getInstance()
+ calendar[Calendar.YEAR] = year
+ calendar[Calendar.MONTH] = month
+ calendar[Calendar.DATE] = date
+ calendar[Calendar.HOUR] = hour
+ calendar[Calendar.MINUTE] = minute
+ calendar[Calendar.SECOND] = second
+ ecg.add(EcgBean())
+ ecg[k].apply {
+ this.date = calendar.time
+ timeString = String.format(
+ "%04d%02d%02d%02d%02d%02d",
+ year,
+ month + 1,
+ date,
+ hour,
+ minute,
+ second
+ )
+ way = toUInt(setRange(start + 7, 1))
+ face = toUInt(setRange(start + 8, 1))
+ if (face > 2) face = 2
+ voice = toUInt(setRange(start + 9, 1))
+ }
+
+
+ }
+
+
+ }
+
+ private fun setRange(start: Int, len: Int): ByteArray {
+ return bytes.copyOfRange(start, start + len)
+ }
+
+
+}
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/EcgWaveInfo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/EcgWaveInfo.kt
new file mode 100644
index 00000000..bfacff86
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/EcgWaveInfo.kt
@@ -0,0 +1,64 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.format
+
+import com.cloud.diplomaticquarterapp.utils.toUInt
+
+
+class EcgWaveInfo constructor(var bytes: ByteArray) {
+
+ var hrSize: Int = toUInt(bytes.copyOfRange(0, 2))
+ var waveSize: Int = toUInt(bytes.copyOfRange(2, 6)) - 4
+ var hr: Int = toUInt(bytes.copyOfRange(6, 8))
+ var st: Int = toUInt(bytes.copyOfRange(8, 10))
+ var qrs: Int = toUInt(bytes.copyOfRange(10, 12))
+ var pvcs: Int = toUInt(bytes.copyOfRange(12, 14))
+ var qtc: Int = toUInt(bytes.copyOfRange(14, 16))
+ var result: Int = toUInt(bytes.copyOfRange(16, 17))
+ var qt: Int = toUInt(bytes.copyOfRange(19, 21))
+ var hrList: IntArray = IntArray(hrSize / 2)
+ var waveList: IntArray = IntArray(waveSize / 2)
+ var waveIntSize = waveSize / 2
+ val total = 2500
+ var waveViewSize = waveIntSize / total
+
+
+ init {
+
+ for (index in 0 until hrSize / 2) {
+ hrList[index] = toUInt(setRange(index * 2 + 22, 2))
+ }
+// for (index in 0 until waveSize / 2) {
+
+// waveList[index] =
+// bytes[23 + index * 2 + hrSize].toInt() * 256 + bytes[22 + index * 2 + hrSize].toInt()
+// }
+
+
+// waveList= ECGInnerItem(bytes).ecgData
+ waveIntSize=waveList.size
+ waveViewSize=waveIntSize/total
+ if (waveViewSize * total < waveIntSize) {
+ waveViewSize++
+ }
+ }
+
+ private fun setRange(start: Int, len: Int): ByteArray {
+ return bytes.copyOfRange(start, start + len)
+ }
+
+
+ fun getWave(index: Int): IntArray {
+ val result = IntArray(total)
+ for (k in 0 until total) {
+ result[k] = if (k + index * total < waveList.size) {
+ waveList[k + index * total]
+ } else {
+ 1000000
+ }
+
+ }
+ return result
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/GluInfo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/GluInfo.kt
new file mode 100644
index 00000000..35b6ffd6
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/GluInfo.kt
@@ -0,0 +1,57 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.format
+
+import com.cloud.diplomaticquarterapp.check_me_pro.bean.GluBean
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import java.util.*
+
+
+class GluInfo constructor(var bytes: ByteArray) {
+ var size: Int = bytes.size / 32
+ var Glu: ArrayList = arrayListOf()
+
+
+ init {
+
+ var start: Int
+ for (k in 0 until size) {
+ start = k * 32
+ val year: Int = toUInt(setRange(start, 2))
+ val month: Int = toUInt(setRange(start + 2, 1)) - 1
+ val date: Int = toUInt(setRange(start + 3, 1))
+ val hour: Int = toUInt(setRange(start + 4, 1))
+ val minute: Int = toUInt(setRange(start + 5, 1))
+ val second: Int = toUInt(setRange(start + 6, 1))
+ val calendar = Calendar.getInstance()
+ calendar[Calendar.YEAR] = year
+ calendar[Calendar.MONTH] = month
+ calendar[Calendar.DATE] = date
+ calendar[Calendar.HOUR] = hour
+ calendar[Calendar.MINUTE] = minute
+ calendar[Calendar.SECOND] = second
+ Glu.add(GluBean())
+ Glu[k].apply {
+ this.date = calendar.time
+ timeString = String.format(
+ "%04d%02d%02d%02d%02d%02d",
+ year,
+ month + 1,
+ date,
+ hour,
+ minute,
+ second
+ )
+ glu= toUInt(setRange(start+7,2)).toFloat()/10f
+ note=String(setRange(start+12,20))
+ }
+ }
+
+
+ }
+
+ private fun setRange(start: Int, len: Int): ByteArray {
+ return bytes.copyOfRange(start, start + len)
+ }
+
+
+}
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/OxyInfo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/OxyInfo.kt
new file mode 100644
index 00000000..08ddc44f
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/OxyInfo.kt
@@ -0,0 +1,64 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.format
+
+import com.cloud.diplomaticquarterapp.check_me_pro.bean.OxyBean
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import java.util.*
+
+
+class OxyInfo constructor(var bytes: ByteArray) {
+ var size: Int = bytes.size / 12
+ var Oxy: ArrayList = arrayListOf()
+
+
+ init {
+
+ var start: Int
+ for (k in 0 until size) {
+ start = k * 12
+ val year: Int = toUInt(setRange(start, 2))
+ val month: Int = toUInt(setRange(start + 2, 1)) - 1
+ val date: Int = toUInt(setRange(start + 3, 1))
+ val hour: Int = toUInt(setRange(start + 4, 1))
+ val minute: Int = toUInt(setRange(start + 5, 1))
+ val second: Int = toUInt(setRange(start + 6, 1))
+ val calendar = Calendar.getInstance()
+ calendar[Calendar.YEAR] = year
+ calendar[Calendar.MONTH] = month
+ calendar[Calendar.DATE] = date
+ calendar[Calendar.HOUR] = hour
+ calendar[Calendar.MINUTE] = minute
+ calendar[Calendar.SECOND] = second
+ Oxy.add(OxyBean())
+ Oxy[k].apply {
+ this.date = calendar.time
+ timeString = String.format(
+ "%04d%02d%02d%02d%02d%02d",
+ year,
+ month + 1,
+ date,
+ hour,
+ minute,
+ second
+ )
+ way = toUInt(setRange(start + 7, 1))
+ if (way > 2) way = 2
+ oxy = toUInt(setRange(start + 8, 1))
+ pr = toUInt(setRange(start + 9, 1))
+ pi = toUInt(setRange(start + 10, 1))
+ face = toUInt(setRange(start + 11, 1))
+ if (face > 2) face = 2
+ }
+
+
+ }
+
+
+ }
+
+ private fun setRange(start: Int, len: Int): ByteArray {
+ return bytes.copyOfRange(start, start + len)
+ }
+
+
+}
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/OxyWaveInfo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/OxyWaveInfo.kt
new file mode 100644
index 00000000..7c3b6f55
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/OxyWaveInfo.kt
@@ -0,0 +1,28 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.format
+
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import com.cloud.diplomaticquarterapp.utils.unsigned
+
+
+class OxyWaveInfo constructor(var bytes: ByteArray) {
+ val size1: Int = toUInt(bytes.copyOfRange(0, 2))
+ val size2: Int = toUInt(bytes.copyOfRange(2, 6))
+ val o2Array = IntArray(size1 / 3)
+ val pulseArray = IntArray(size1 / 3)
+ val waveArray = IntArray(size2)
+
+
+ init {
+ for (k in 0 until size1 / 3) {
+ o2Array[k] = bytes[k * 3 + 6].unsigned()
+ pulseArray[k] =
+ bytes[k * 3 + 7].unsigned() + bytes[k * 3 + 8].unsigned() * 256
+ }
+ for (k in 0 until size2) {
+ waveArray[k] = bytes[k + 6 + size1].unsigned()
+ }
+ }
+
+
+}
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/PedInfo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/PedInfo.kt
new file mode 100644
index 00000000..58f74688
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/PedInfo.kt
@@ -0,0 +1,63 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.format
+
+import android.util.Log
+import com.cloud.diplomaticquarterapp.check_me_pro.bean.PedBean
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import java.util.*
+
+
+class PedInfo constructor(var bytes: ByteArray) {
+ var size: Int = bytes.size / 29
+ var Ped: ArrayList = arrayListOf()
+
+
+ init {
+ Log.i("pedoSize",bytes.size.toString())
+
+ var start: Int
+ for (k in 0 until size) {
+ start = k * 29
+ val year: Int = toUInt(setRange(start, 2))
+ val month: Int = toUInt(setRange(start + 2, 1)) - 1
+ val date: Int = toUInt(setRange(start + 3, 1))
+ val hour: Int = toUInt(setRange(start + 4, 1))
+ val minute: Int = toUInt(setRange(start + 5, 1))
+ val second: Int = toUInt(setRange(start + 6, 1))
+ val calendar = Calendar.getInstance()
+ calendar[Calendar.YEAR] = year
+ calendar[Calendar.MONTH] = month
+ calendar[Calendar.DATE] = date
+ calendar[Calendar.HOUR] = hour
+ calendar[Calendar.MINUTE] = minute
+ calendar[Calendar.SECOND] = second
+ Ped.add(PedBean())
+ Ped[k].apply {
+ this.date = calendar.time
+ timeString = String.format(
+ "%04d%02d%02d%02d%02d%02d",
+ year,
+ month + 1,
+ date,
+ hour,
+ minute,
+ second
+ )
+ step = toUInt(setRange(start + 7, 4))
+ dis = toUInt(setRange(start + 11, 4)).toFloat() / 100f
+ speed = toUInt(setRange(start + 15, 4)).toFloat() / 10f
+ cal = toUInt(setRange(start + 19, 4)).toFloat() / 100f
+ fat = toUInt(setRange(start + 23, 2)).toFloat() / 100f
+ time = toUInt(setRange(start + 25, 2))
+ }
+ }
+
+
+ }
+
+ private fun setRange(start: Int, len: Int): ByteArray {
+ return bytes.copyOfRange(start, start + len)
+ }
+
+
+}
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/SlpInfo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/SlpInfo.kt
new file mode 100644
index 00000000..e3f396e5
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/SlpInfo.kt
@@ -0,0 +1,71 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.format
+
+import android.util.Log
+import com.cloud.diplomaticquarterapp.check_me_pro.bean.SlpBean
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import java.util.*
+
+
+class SlpInfo constructor(var bytes: ByteArray) {
+ var size: Int = bytes.size / 18
+ var Slp: ArrayList = arrayListOf()
+ fun byteArray2String(byteArray: ByteArray): String {
+ var fuc = ""
+ for (b in byteArray) {
+ val st = String.format("%02X", b)
+ fuc += ("$st ");
+ }
+ return fuc
+ }
+
+ init {
+
+ Log.e("sleepSIze",byteArray2String(bytes))
+ var start: Int
+ for (k in 0 until size) {
+ start = k *18
+ val year: Int = toUInt(setRange(start, 2))
+ val month: Int = toUInt(setRange(start + 2, 1)) - 1
+ val date: Int = toUInt(setRange(start + 3, 1))
+ val hour: Int = toUInt(setRange(start + 4, 1))
+ val minute: Int = toUInt(setRange(start + 5, 1))
+ val second: Int = toUInt(setRange(start + 6, 1))
+ val calendar = Calendar.getInstance()
+ calendar[Calendar.YEAR] = year
+ calendar[Calendar.MONTH] = month
+ calendar[Calendar.DATE] = date
+ calendar[Calendar.HOUR] = hour
+ calendar[Calendar.MINUTE] = minute
+ calendar[Calendar.SECOND] = second
+ Slp.add(SlpBean())
+ Slp[k].apply {
+ this.date = calendar.time
+ timeString = String.format(
+ "%04d%02d%02d%02d%02d%02d",
+ year,
+ month + 1,
+ date,
+ hour,
+ minute,
+ second
+ )
+ time = toUInt(setRange(start + 7, 4))
+ lowTime = toUInt(setRange(start + 11, 2))
+ lowCount = toUInt(setRange(start + 13, 2))
+ minO2 = toUInt(setRange(start + 15, 1))
+ meanO2 = toUInt(setRange(start + 16, 1))
+ face = toUInt(setRange(start + 17, 1))
+ if (face > 2) face = 2
+ }
+ }
+
+
+ }
+
+ private fun setRange(start: Int, len: Int): ByteArray {
+ return bytes.copyOfRange(start, start + len)
+ }
+
+
+}
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/TmpInfo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/TmpInfo.kt
new file mode 100644
index 00000000..2f9f23d6
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/TmpInfo.kt
@@ -0,0 +1,59 @@
+
+import com.cloud.diplomaticquarterapp.check_me_pro.bean.TmpBean
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import java.util.*
+
+
+class TmpInfo constructor(var bytes: ByteArray) {
+ var size: Int = bytes.size / 11
+ var Tmp: ArrayList = arrayListOf()
+
+
+ init {
+
+ var start: Int
+ for (k in 0 until size) {
+ start = k * 11
+ val year: Int = toUInt(setRange(start, 2))
+ val month: Int = toUInt(setRange(start + 2, 1)) - 1
+ val date: Int = toUInt(setRange(start + 3, 1))
+ val hour: Int = toUInt(setRange(start + 4, 1))
+ val minute: Int = toUInt(setRange(start + 5, 1))
+ val second: Int = toUInt(setRange(start + 6, 1))
+ val calendar = Calendar.getInstance()
+ calendar[Calendar.YEAR] = year
+ calendar[Calendar.MONTH] = month
+ calendar[Calendar.DATE] = date
+ calendar[Calendar.HOUR] = hour
+ calendar[Calendar.MINUTE] = minute
+ calendar[Calendar.SECOND] = second
+ Tmp.add(TmpBean())
+ Tmp[k].apply {
+ this.date = calendar.time
+ timeString = String.format(
+ "%04d%02d%02d%02d%02d%02d",
+ year,
+ month + 1,
+ date,
+ hour,
+ minute,
+ second
+ )
+ way = toUInt(setRange(start + 7, 1))
+ if (way > 2) way = 2
+ tmp = toUInt(setRange(start + 8, 2)).toFloat() / 10f
+ face = toUInt(setRange(start + 10, 1))
+ if (face > 2) face = 2
+ }
+ }
+
+
+ }
+
+ private fun setRange(start: Int, len: Int): ByteArray {
+ return bytes.copyOfRange(start, start + len)
+ }
+
+
+}
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/UserInfo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/UserInfo.kt
new file mode 100644
index 00000000..ddc2ed85
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/format/UserInfo.kt
@@ -0,0 +1,46 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.format
+
+import com.cloud.diplomaticquarterapp.check_me_pro.bean.UserBean
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import com.cloud.diplomaticquarterapp.utils.unsigned
+import java.util.*
+
+
+class UserInfo constructor(var bytes: ByteArray) {
+ var size: Int = bytes.size / 27
+ var user: Array = Array(size) {
+ UserBean()
+ }
+
+ init {
+
+ var start: Int
+ for (k in 0 until size) {
+ start = k * 27
+ user[k].id = bytes[start].unsigned().toString()
+ user[k].name = String(setRange(start + 1, 16))
+ user[k].ico = bytes[start + 17].unsigned()
+ user[k].sex = bytes[start + 18].unsigned()
+ val year: Int = toUInt(setRange(start + 19, 2))
+ val month: Int = toUInt(setRange(start + 21, 1)) - 1
+ val date: Int = toUInt(setRange(start + 22, 1))
+ val calendar = Calendar.getInstance()
+ calendar[Calendar.YEAR] = year
+ calendar[Calendar.MONTH] = month
+ calendar[Calendar.DATE] = date
+ user[k].birthday = calendar.time
+ user[k].weight = toUInt(setRange(start + 23, 2)) /10
+ user[k].height = toUInt(setRange(start + 25, 2))
+
+ }
+
+
+ }
+
+ private fun setRange(start: Int, len: Int): ByteArray {
+ return bytes.copyOfRange(start, start + len)
+ }
+
+
+}
+
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/manager/BleDataManager.java b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/manager/BleDataManager.java
new file mode 100644
index 00000000..d0122096
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/manager/BleDataManager.java
@@ -0,0 +1,111 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.manager;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattService;
+import android.content.Context;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.UUID;
+
+import no.nordicsemi.android.ble.BleManager;
+import no.nordicsemi.android.ble.data.Data;
+
+public class BleDataManager extends BleManager {
+ private BluetoothGattCharacteristic write_char;
+ private BluetoothGattCharacteristic notify_char;
+ private OnNotifyListener listener;
+
+ public BleDataManager(Context context) {
+ super(context);
+ }
+
+ public void setNotifyListener(OnNotifyListener listener) {
+ this.listener = listener;
+ }
+
+ @Override
+ protected BleManagerGattCallback getGattCallback() {
+ return new MyManagerGattCallback();
+ }
+
+ public void sendCmd(byte[] bytes) {
+// Log.i("----- Current Write Command -----", "");
+ writeCharacteristic(write_char, bytes)
+ .split()
+ .done(device -> {
+ })
+ .enqueue();
+ }
+
+
+ public interface OnNotifyListener {
+ void onNotify(BluetoothDevice device, Data data);
+ }
+
+ private class MyManagerGattCallback extends BleManagerGattCallback {
+ @Override
+ public boolean isRequiredServiceSupported(BluetoothGatt gatt) {
+ final BluetoothGattService service = gatt.getService(service_uuid);
+
+
+ if (service != null) {
+ write_char = service.getCharacteristic(write_uuid);
+ notify_char = service.getCharacteristic(notify_uuid);
+ }
+
+ boolean notify = false;
+ if (notify_char != null) {
+ final int properties = notify_char.getProperties();
+ notify = (properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0;
+ }
+ boolean writeRequest = false;
+ if (write_char != null) {
+ final int properties = write_char.getProperties();
+ int writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT;
+ if ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0) {
+ writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE;
+ }
+ write_char.setWriteType(writeType);
+ writeRequest = (properties & BluetoothGattCharacteristic.PROPERTY_WRITE) != 0 || (properties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0;
+ /// LepuBleLog.d(TAG, "writeChar writeRequest == " + writeRequest);
+
+ }
+ // Return true if all required services have been found
+ return write_char != null && notify_char != null
+ && notify && writeRequest;
+ }
+
+ @Override
+ public boolean isOptionalServiceSupported(BluetoothGatt gatt) {
+ return super.isOptionalServiceSupported(gatt);
+ }
+
+ @Override
+ protected void initialize() {
+ beginAtomicRequestQueue()
+ .add(requestMtu(23) // Remember, GATT needs 3 bytes extra. This will allow packet size of 244 bytes.
+ .with((device, mtu) -> Log.d("TAG", "MTU set to " + mtu))
+ .fail((device, status) -> log(Log.WARN, "Requested MTU not supported: " + status)))
+ .add(enableNotifications(notify_char))
+ .done(device -> Log.d("TAG", "Target initialized"))
+ .enqueue();
+ setNotificationCallback(notify_char)
+ .with((device, data) -> {
+ listener.onNotify(device, data);
+ });
+ }
+
+ @Override
+ public void onDeviceDisconnected() {
+ write_char = null;
+ notify_char = null;
+ }
+ }
+
+ public static final UUID service_uuid = UUID.fromString("14839ac4-7d7e-415c-9a42-167340cf2339");
+ public static final UUID write_uuid = UUID.fromString("8B00ACE7-EB0B-49B0-BBE9-9AEE0A26E1A3");
+ public static final UUID notify_uuid = UUID.fromString("0734594A-A8E7-4B1A-A6B1-CD5243059A57");
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/manager/BleScanManager.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/manager/BleScanManager.kt
new file mode 100644
index 00000000..cff89423
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/manager/BleScanManager.kt
@@ -0,0 +1,63 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.manager
+
+import android.annotation.SuppressLint
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothManager
+import android.bluetooth.le.BluetoothLeScanner
+import android.bluetooth.le.ScanCallback
+import android.bluetooth.le.ScanResult
+import android.bluetooth.le.ScanSettings
+import android.content.Context
+import android.os.Build
+import android.util.Log
+import androidx.annotation.RequiresApi
+
+
+class BleScanManager {
+ interface Scan {
+ fun scanReturn(name: String, bluetoothDevice: BluetoothDevice)
+ }
+
+ private var bluetoothAdapter: BluetoothAdapter? = null
+ private lateinit var leScanner: BluetoothLeScanner
+ private var scan: Scan? = null
+ private val leScanCallback: ScanCallback = object : ScanCallback() {
+ @SuppressLint("MissingPermission")
+ override fun onScanResult(
+ callbackType: Int, result: ScanResult
+ ) {
+ super.onScanResult(callbackType, result)
+ val device = result.device
+ if (device?.name == null) return;
+ scan?.apply {
+ scanReturn(device.name, device)
+ }
+ Log.i("scanned ble", " ${device.name}")
+ }
+
+ override fun onBatchScanResults(results: List) {}
+ override fun onScanFailed(errorCode: Int) {}
+ }
+
+ fun setCallBack(scan: Scan) {
+ this.scan = scan
+ }
+
+ @SuppressLint("MissingPermission")
+ @RequiresApi(Build.VERSION_CODES.M)
+ fun initScan(context: Context) {
+ context.apply {
+ val settings: ScanSettings = ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES).build()
+ val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
+ bluetoothAdapter = bluetoothManager.adapter
+ leScanner = bluetoothAdapter!!.bluetoothLeScanner
+ leScanner.startScan(null, settings, leScanCallback)
+ }
+ }
+
+ @SuppressLint("MissingPermission")
+ fun stopScan() {
+ leScanner.stopScan(leScanCallback)
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/pkg/EndReadPkg.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/pkg/EndReadPkg.kt
new file mode 100644
index 00000000..ce4a0a91
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/pkg/EndReadPkg.kt
@@ -0,0 +1,21 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.pkg
+
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.constant.BTConstant
+import com.cloud.diplomaticquarterapp.utils.CRCUtils
+import kotlin.experimental.inv
+
+class EndReadPkg {
+ var buf: ByteArray = ByteArray(BTConstant.COMMON_PKG_LENGTH)
+
+ init {
+ // TODO Auto-generated constructor stub
+ buf[0] = 0xAA.toByte()
+ buf[1] = BTConstant.CMD_WORD_END_READ
+ buf[2] = BTConstant.CMD_WORD_END_READ.inv()
+ buf[3] = 0 //Package number, the default is 0
+ buf[4] = 0
+ buf[5] = 0 //data chunk size, the default is 0
+ buf[6] = 0
+ buf[buf.size - 1] = CRCUtils.calCRC8(buf)
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/pkg/GetDeviceInfoPkg.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/pkg/GetDeviceInfoPkg.kt
new file mode 100644
index 00000000..e5e7c720
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/pkg/GetDeviceInfoPkg.kt
@@ -0,0 +1,21 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.pkg
+
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.constant.BTConstant
+import com.cloud.diplomaticquarterapp.utils.CRCUtils
+import kotlin.experimental.inv
+
+
+class GetDeviceInfoPkg() {
+ val buf: ByteArray = ByteArray(BTConstant.COMMON_PKG_LENGTH)
+
+ init {
+ buf[0] = 0xAA.toByte()
+ buf[1] = BTConstant.CMD_WORD_GET_INFO
+ buf[2] = BTConstant.CMD_WORD_GET_INFO.inv()
+ buf[3] = 0.toByte() //Package number
+ buf[4] = 0.toByte()
+ buf[5] = 0.toByte()
+ buf[6] = 0.toByte()
+ buf[buf.size - 1] = CRCUtils.calCRC8(buf)
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/pkg/ReadContentPkg.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/pkg/ReadContentPkg.kt
new file mode 100644
index 00000000..57ec69c4
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/pkg/ReadContentPkg.kt
@@ -0,0 +1,19 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.pkg
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.constant.BTConstant
+import com.cloud.diplomaticquarterapp.utils.CRCUtils
+import kotlin.experimental.inv
+
+class ReadContentPkg(pkgNum: Int) {
+ val buf: ByteArray = ByteArray(BTConstant.COMMON_PKG_LENGTH)
+
+ init {
+ buf[0] = 0xAA.toByte()
+ buf[1] = BTConstant.CMD_WORD_READ_CONTENT
+ buf[2] = BTConstant.CMD_WORD_READ_CONTENT.inv()
+ buf[3] = pkgNum.toByte() //Package number
+ buf[4] = (pkgNum shr 8).toByte()
+ buf[5] = 0 //data chunk size, the default is 0
+ buf[6] = 0
+ buf[buf.size - 1] = CRCUtils.calCRC8(buf)
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/pkg/StartReadPkg.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/pkg/StartReadPkg.kt
new file mode 100644
index 00000000..e71003aa
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/pkg/StartReadPkg.kt
@@ -0,0 +1,23 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.pkg
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.constant.BTConstant
+import com.cloud.diplomaticquarterapp.utils.CRCUtils
+import kotlin.experimental.inv
+
+class StartReadPkg(fileName: String?) {
+ val buf: ByteArray = ByteArray(BTConstant.COMMON_PKG_LENGTH + fileName!!.length + 1)
+
+ init {
+ buf[0] = (0xAA).toByte()
+ buf[1] = BTConstant.CMD_WORD_START_READ
+ buf[2] = BTConstant.CMD_WORD_START_READ.inv()
+ buf[3] = 0 //Package number, the default is 0
+ buf[4] = 0
+ buf[5] = (buf.size - BTConstant.COMMON_PKG_LENGTH).toByte() //data chunk size
+ buf[6] = (buf.size - BTConstant.COMMON_PKG_LENGTH shr 8).toByte()
+ val tempFileName = fileName!!.toCharArray()
+ for (i in tempFileName.indices) {
+ buf[i + 7] = tempFileName[i].toByte()
+ }
+ buf[buf.size - 1] = CRCUtils.calCRC8(buf)
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/worker/BleDataWorker.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/worker/BleDataWorker.kt
new file mode 100644
index 00000000..e81554b7
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/check_me_pro/ble/worker/BleDataWorker.kt
@@ -0,0 +1,222 @@
+package com.cloud.diplomaticquarterapp.check_me_pro.ble.worker
+
+import android.bluetooth.BluetoothDevice
+import android.content.Context
+import android.util.Log
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.format.CheckMeResponse
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.format.DeviceInfo
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.manager.BleDataManager
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.pkg.EndReadPkg
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.pkg.GetDeviceInfoPkg
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.pkg.ReadContentPkg
+import com.cloud.diplomaticquarterapp.check_me_pro.ble.pkg.StartReadPkg
+import com.cloud.diplomaticquarterapp.utils.CRCUtils
+import com.cloud.diplomaticquarterapp.utils.Constant
+import com.cloud.diplomaticquarterapp.utils.add
+import com.cloud.diplomaticquarterapp.utils.toUInt
+import com.google.gson.Gson
+import io.flutter.plugin.common.EventChannel
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
+import no.nordicsemi.android.ble.data.Data
+import java.io.File
+import kotlin.experimental.inv
+
+class BleDataWorker(private val updateEventSink: (Map) -> Unit) {
+ private var pool: ByteArray? = null
+ private val deviceChannel = Channel(Channel.CONFLATED)
+ private val fileChannel = Channel(Channel.CONFLATED)
+ private val connectChannel = Channel(Channel.CONFLATED)
+ private var myBleDataManager: BleDataManager? = null
+ private val dataScope = CoroutineScope(Dispatchers.IO)
+ private val mutex = Mutex()
+
+ private var cmdState = 0;
+ var pkgTotal = 0;
+ var currentPkg = 0;
+ var fileData: ByteArray? = null
+ var currentFileName = ""
+ var result = 1;
+ var currentFileSize = 0
+
+
+ companion object {
+ val fileProgressChannel = Channel(Channel.CONFLATED)
+ }
+
+ data class FileProgress(
+ var name: String = "", var progress: Int = 0, var success: Boolean = false
+ )
+
+ private val comeData = object : BleDataManager.OnNotifyListener {
+ override fun onNotify(device: BluetoothDevice?, data: Data?) {
+ data?.value?.apply {
+ pool = add(pool, this)
+ }
+ pool?.apply {
+ pool = handleDataPool(pool)
+ }
+ }
+
+ }
+
+ val gson = Gson()
+
+
+ private fun handleDataPool(bytes: ByteArray?): ByteArray? {
+ val bytesLeft: ByteArray? = bytes
+
+ if (bytes == null || bytes.size < 8) {
+ return bytes
+ }
+ loop@ for (i in 0 until bytes.size - 7) {
+ if (bytes[i] != 0x55.toByte() || bytes[i + 1] != bytes[i + 2].inv()) {
+ continue@loop
+ }
+
+ // need content length
+ val len = toUInt(bytes.copyOfRange(i + 5, i + 7))
+ if (i + 8 + len > bytes.size) {
+ continue@loop
+ }
+
+ val temp: ByteArray = bytes.copyOfRange(i, i + 8 + len)
+ if (temp.last() == CRCUtils.calCRC8(temp)) {
+
+ if (cmdState in 1..3) {
+ val bleResponse = CheckMeResponse(temp)
+ if (cmdState == 1) {
+ currentFileSize = toUInt(bleResponse.content)
+ pkgTotal = currentFileSize / 512
+ if (bleResponse.cmd == 1) {
+ result = 1
+ val pkg = EndReadPkg()
+ sendCmd(pkg.buf)
+ cmdState = 3
+ } else if (bleResponse.cmd == 0) {
+ val pkg = ReadContentPkg(currentPkg)
+ sendCmd(pkg.buf)
+ currentPkg++
+ cmdState = 2;
+ }
+
+
+ } else if (cmdState == 2) {
+ bleResponse.content.apply {
+ fileData = add(fileData, this)
+ fileData?.let {
+ dataScope.launch {
+ fileProgressChannel.send(
+ FileProgress(
+ currentFileName, it.size * 100 / currentFileSize, true
+ )
+ )
+ }
+ }
+ }
+
+ if (currentPkg > pkgTotal) {
+ fileData?.apply {
+ result = 0
+ Log.i("file", "receive $currentFileName")
+ File(Constant.getPathX(currentFileName)).writeBytes(this)
+ }
+ val pkg = EndReadPkg()
+ Log.i("file", "bytes ${pkg.buf}")
+ sendCmd(pkg.buf)
+ cmdState = 3
+ } else {
+ val pkg = ReadContentPkg(currentPkg)
+ sendCmd(pkg.buf)
+ currentPkg++
+ }
+
+ } else if (cmdState == 3) {
+ fileData = null
+ currentPkg = 0
+ cmdState = 0
+ dataScope.launch {
+ fileProgressChannel.send(
+ FileProgress(
+ currentFileName, 100, result == 0
+ )
+ )
+ fileChannel.send(result)
+ }
+ }
+ } else if (cmdState == 4) {
+ val deviceInfo = DeviceInfo(temp)
+
+ val json = deviceInfo.json
+ var s: String = ""
+ for (k in json.keys()) {
+ s += "$k: "
+ s += "${json.get(k)} "
+ }
+ Log.d("DeviceInfoFaiz", "This is the DeviceInfo: ${gson.toJson(json)}");
+ val returnData = mapOf("type" to "infoDataCheckMe", "data" to gson.toJson(json))
+ updateEventSink(returnData)
+ }
+
+
+ val tempBytes: ByteArray? = if (i + 8 + len == bytes.size) null else bytes.copyOfRange(
+ i + 8 + len, bytes.size
+ )
+
+ return handleDataPool(tempBytes)
+ }
+ }
+
+ return bytesLeft
+ }
+
+ private fun sendCmd(bs: ByteArray) {
+ myBleDataManager?.sendCmd(bs)
+ }
+
+
+ fun initWorker(context: Context, bluetoothDevice: BluetoothDevice?) {
+ myBleDataManager = BleDataManager(context)
+ myBleDataManager?.setNotifyListener(comeData)
+ bluetoothDevice?.let {
+ myBleDataManager?.connect(it)?.useAutoConnect(false)?.retry(150, 100)?.done {
+ Log.i("BLE", "连接成功了.>>.....>>>>")
+ getDeviceInfo();
+ dataScope.launch {
+ connectChannel.send("yes")
+ }
+ }?.enqueue()
+ }
+ }
+
+ suspend fun waitConnect() {
+ connectChannel.receive()
+ }
+
+ suspend fun getFile(name: String): Int {
+ mutex.withLock {
+ this.currentFileName = name
+ cmdState = 1
+ val pkg = StartReadPkg(name)
+ Log.i("----- Current PKG -----", pkg.toString());
+ sendCmd(pkg.buf)
+ return fileChannel.receive()
+ }
+ }
+
+ private fun getDeviceInfo() {
+ cmdState = 4
+ val pkg = GetDeviceInfoPkg()
+ sendCmd(pkg.buf)
+
+ }
+
+ fun disconnect() {
+ myBleDataManager?.disconnect()?.enqueue()
+ }
+
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt
index 7b3cc2d1..e92070b5 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt
@@ -6,11 +6,10 @@ import android.content.Intent
import android.net.*
import android.net.wifi.*
import android.os.Build
-import android.os.PatternMatcher
import android.provider.Settings
import android.util.Log
import androidx.annotation.RequiresApi
-import com.ejada.hmg.MainActivity
+import com.cloud.diplomaticquarterapp.MainActivity
import com.ejada.hmg.utils.HMGUtils
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt
index dcfa5488..8641d37a 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt
@@ -2,7 +2,7 @@ package com.ejada.hmg.hmgwifi
import android.annotation.SuppressLint
import com.ejada.hmg.utils.API
-import com.ejada.hmg.MainActivity
+import com.cloud.diplomaticquarterapp.MainActivity
import com.github.kittinunf.fuel.core.extensions.jsonBody
import com.github.kittinunf.fuel.httpGet
import com.github.kittinunf.fuel.httpPost
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WPA.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WPA.kt
index 61cc4f9f..6a8a2590 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WPA.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WPA.kt
@@ -7,7 +7,7 @@ import android.net.wifi.*
import android.net.wifi.SupplicantState.ASSOCIATED
import android.net.wifi.SupplicantState.COMPLETED
import android.util.Log
-import com.ejada.hmg.MainActivity
+import com.cloud.diplomaticquarterapp.MainActivity
import com.ejada.hmg.utils.HMGUtils
class WPA(mainActivity: MainActivity, SSID:String) {
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt
index e8e39344..9e0605f7 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt
@@ -12,9 +12,8 @@ import android.net.wifi.SupplicantState.COMPLETED
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
-import com.ejada.hmg.MainActivity
+import com.cloud.diplomaticquarterapp.MainActivity
import com.ejada.hmg.utils.HMGUtils
-import java.security.cert.X509Certificate
class WpaEnterprise(private val mainActivity: MainActivity, private var SSID: String) {
private var TAG = "WpaEnterprise"
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/ByteArray.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/ByteArray.kt
new file mode 100644
index 00000000..2a8225eb
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/ByteArray.kt
@@ -0,0 +1,34 @@
+package com.cloud.diplomaticquarterapp.utils
+
+
+fun add(ori: ByteArray?, add: ByteArray): ByteArray {
+ if (ori == null) {
+ return add
+ }
+
+ val new: ByteArray = ByteArray(ori.size + add.size)
+ for ((index, value) in ori.withIndex()) {
+ new[index] = value
+ }
+
+ for ((index, value) in add.withIndex()) {
+ new[index + ori.size] = value
+ }
+
+ return new
+}
+
+
+fun toUInt(bytes: ByteArray): Int {
+ var result = 0
+ for ((i, v) in bytes.withIndex()) {
+ result += v.unsigned().shl(i * 8)
+ }
+ return result
+}
+
+
+fun Byte.unsigned(): Int = when {
+ (toInt() < 0) -> 255 + toInt() + 1
+ else -> toInt()
+}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/CRCUtils.java b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/CRCUtils.java
new file mode 100644
index 00000000..981c48fb
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/CRCUtils.java
@@ -0,0 +1,58 @@
+package com.cloud.diplomaticquarterapp.utils;
+
+
+/**
+ * Tools used to generate CRC8 code
+ *
+ * @author zouhao
+ */
+public class CRCUtils {
+
+ /**
+ * CRC8 code table
+ */
+ private static final char[] Table_CRC8 = {0x00, 0x07, 0x0E, 0x09, 0x1C,
+ 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
+ 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46,
+ 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB,
+ 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, 0x90,
+ 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1,
+ 0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5,
+ 0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0,
+ 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93,
+ 0x94, 0x9D, 0x9A, 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
+ 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59,
+ 0x5E, 0x4B, 0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74,
+ 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, 0xB1,
+ 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, 0xF9, 0xFE, 0xF7, 0xF0,
+ 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3,
+ 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, 0x51, 0x56,
+ 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10, 0x05,
+ 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
+ 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78,
+ 0x7F, 0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25,
+ 0x2C, 0x2B, 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE,
+ 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F,
+ 0x8A, 0x8D, 0x84, 0x83, 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC,
+ 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3};
+
+ /**
+ * Generate CRC8 code
+ *
+ * @param buf Data buffer
+ * @return CRC8 code, return 0 when the parameter is error
+ */
+ public static byte calCRC8(byte[] buf) {
+ if (buf == null || buf.length == 0) {
+ return 0;
+ }
+
+ byte crc = 0;
+
+ for (int i = 0; i < buf.length - 1; i++) {
+ crc = (byte) Table_CRC8[0x00ff & (crc ^ (buf[i]))];
+ }
+ return crc;
+ }
+
+}
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constant.java b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constant.java
new file mode 100644
index 00000000..0a92c478
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constant.java
@@ -0,0 +1,23 @@
+package com.cloud.diplomaticquarterapp.utils;
+
+import android.content.Context;
+
+import java.io.File;
+
+public class Constant {
+ public final static String[] EcgWay = {"Hand-Hand", "Hand-Chest", "1-Lead", "2-Lead"};
+ public final static String[] OxyWay = {"Internal", "External", ""};
+ public final static String[] TmpWay = {"Body", "Thing", ""};
+ public static String filePath;
+
+ public static String getPathX(String s) {
+ return filePath + s;
+ }
+
+ public static void initVar(Context context) {
+ File[] fs = context.getExternalFilesDirs(null);
+ if (fs != null && fs.length >= 1) {
+ filePath = fs[0].getAbsolutePath() + "/";
+ }
+ }
+}
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/FlutterText.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/FlutterText.kt
index 1a650074..977defbb 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/FlutterText.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/FlutterText.kt
@@ -1,7 +1,6 @@
package com.ejada.hmg.utils
import io.flutter.plugin.common.MethodChannel
-import io.flutter.plugin.common.MethodChannel.Result
class FlutterText{
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt
index 7fbf859a..9b6f5b79 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt
@@ -1,5 +1,6 @@
package com.ejada.hmg.utils
+import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
@@ -13,10 +14,8 @@ import android.widget.Toast
import androidx.annotation.Nullable
import androidx.core.app.NotificationCompat
import androidx.core.app.TaskStackBuilder
-import com.ejada.hmg.BuildConfig
-import com.ejada.hmg.MainActivity
+import com.cloud.diplomaticquarterapp.MainActivity
import com.ejada.hmg.R
-import com.ejada.hmg.geofence.GeoZoneModel
import com.github.kittinunf.fuel.core.extensions.jsonBody
import com.github.kittinunf.fuel.httpPost
import com.google.gson.Gson
@@ -29,22 +28,24 @@ import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.*
import kotlin.concurrent.timerTask
+import com.ejada.hmg.BuildConfig
class HMGUtils {
- companion object{
+ companion object {
private lateinit var platformChannel: MethodChannel
- fun getPlatformChannel():MethodChannel{
+ fun getPlatformChannel(): MethodChannel {
return platformChannel
}
- fun setPlatformChannel(channel: MethodChannel){
+
+ fun setPlatformChannel(channel: MethodChannel) {
platformChannel = channel
}
- fun timer(delay: Long, repeat: Boolean, tick: (Timer) -> Unit) : Timer{
+ fun timer(delay: Long, repeat: Boolean, tick: (Timer) -> Unit): Timer {
val timer = Timer()
- if(repeat)
+ if (repeat)
timer.schedule(timerTask {
tick(timer)
}, delay, delay)
@@ -56,42 +57,44 @@ class HMGUtils {
return timer
}
- fun popMessage(context: MainActivity, message: String){
+ fun popMessage(context: MainActivity, message: String) {
context.runOnUiThread {
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
}
}
- fun popFlutterText(context: MainActivity, key: String){
+ fun popFlutterText(context: MainActivity, key: String) {
context.runOnUiThread {
- FlutterText.with(key){
+ FlutterText.with(key) {
Toast.makeText(context, it, Toast.LENGTH_LONG).show()
}
}
}
- fun getLanguageCode(context: Context) : Int {
+ fun getLanguageCode(context: Context): Int {
val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE)
val lang = pref.getString(PREF_KEY_LANGUAGE, "ar")
return if (lang == "ar") 2 else 1
}
- fun defaultHTTPParams(context: Context) : Map{
+ fun defaultHTTPParams(context: Context): Map {
return mapOf(
- "ZipCode" to "966",
- "VersionID" to 5.8,
- "Channel" to 3,
- "LanguageID" to getLanguageCode(context),
- "IPAdress" to "10.20.10.20",
- "generalid" to "Cs2020@2016$2958",
- "PatientOutSA" to 0,
- "SessionID" to null,
- "isDentalAllowedBackend" to false,
- "DeviceTypeID" to 2)
+ "ZipCode" to "966",
+ "VersionID" to 5.8,
+ "Channel" to 3,
+ "LanguageID" to getLanguageCode(context),
+ "IPAdress" to "10.20.10.20",
+ "generalid" to "Cs2020@2016$2958",
+ "PatientOutSA" to 0,
+ "SessionID" to null,
+ "isDentalAllowedBackend" to false,
+ "DeviceTypeID" to 2
+ )
}
- fun scheduleJob(context: Context, pendingIntentClassType:Class, jobId:Int, intervalDuration:String, deadlineMillis:Long = (30 * 1000)) { // default deadline: 30 Seconds
+ @SuppressLint("MissingPermission")
+ fun scheduleJob(context: Context, pendingIntentClassType: Class, jobId: Int, intervalDuration: String, deadlineMillis: Long = (30 * 1000)) { // default deadline: 30 Seconds
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
val jobScheduler: JobScheduler = context.getSystemService(JobScheduler::class.java)
@@ -100,17 +103,22 @@ class HMGUtils {
builder.setPersisted(true)
builder.setBackoffCriteria(30000, JobInfo.BACKOFF_POLICY_LINEAR)
- val intervalMillis = timeToMillis(intervalDuration,"HH:mm:ss")
+ val intervalMillis = timeToMillis(intervalDuration, "HH:mm:ss")
builder.setMinimumLatency(intervalMillis) // wait at least
builder.setOverrideDeadline((intervalMillis + deadlineMillis)) // maximum delay
- if (jobScheduler.schedule(builder.build()) == JobScheduler.RESULT_SUCCESS){
- Logs.save(context,"ScheduleJob", "${pendingIntentClassType.simpleName}: Job scheduled to trigger after duration $intervalDuration >> HH:mm:ss --('MinimumLatency:$intervalMillis Deadline:${(intervalMillis + deadlineMillis)}')--",Logs.STATUS.SUCCESS)
- }else{
- Logs.save(context,"ScheduleJob", "${pendingIntentClassType.simpleName}: Failed to scheduled Job",Logs.STATUS.ERROR)
+ if (jobScheduler.schedule(builder.build()) == JobScheduler.RESULT_SUCCESS) {
+ Logs.save(
+ context,
+ "ScheduleJob",
+ "${pendingIntentClassType.simpleName}: Job scheduled to trigger after duration $intervalDuration >> HH:mm:ss --('MinimumLatency:$intervalMillis Deadline:${(intervalMillis + deadlineMillis)}')--",
+ Logs.STATUS.SUCCESS
+ )
+ } else {
+ Logs.save(context, "ScheduleJob", "${pendingIntentClassType.simpleName}: Failed to scheduled Job", Logs.STATUS.ERROR)
}
} else {
- Logs.save(context,"ScheduleJob", "${pendingIntentClassType.simpleName}: Failed to scheduled Job on VERSION.SDK_INT < ${android.os.Build.VERSION_CODES.M}",Logs.STATUS.ERROR)
+ Logs.save(context, "ScheduleJob", "${pendingIntentClassType.simpleName}: Failed to scheduled Job on VERSION.SDK_INT < ${android.os.Build.VERSION_CODES.M}", Logs.STATUS.ERROR)
}
}
@@ -122,7 +130,7 @@ class HMGUtils {
private const val NOTIFICATION_CHANNEL_ID = BuildConfig.APPLICATION_ID + ".channel"
-fun timeToMillis(time:String, format:String):Long{
+fun timeToMillis(time: String, format: String): Long {
val sdf = SimpleDateFormat(format, Locale.US)
val millis = sdf.parse(time).time + TimeZone.getDefault().rawOffset
return millis
@@ -132,11 +140,14 @@ fun sendNotification(context: Context, title: String, @Nullable subtitle: String
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
- && notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID) == null) {
+ && notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID) == null
+ ) {
val name = context.getString(R.string.app_name)
- val channel = NotificationChannel(NOTIFICATION_CHANNEL_ID,
- name,
- NotificationManager.IMPORTANCE_DEFAULT)
+ val channel = NotificationChannel(
+ NOTIFICATION_CHANNEL_ID,
+ name,
+ NotificationManager.IMPORTANCE_DEFAULT
+ )
notificationManager.createNotificationChannel(channel)
}
@@ -144,15 +155,15 @@ fun sendNotification(context: Context, title: String, @Nullable subtitle: String
val intent = Intent(context, MainActivity::class.java)
val stackBuilder = TaskStackBuilder.create(context)
- .addParentStack(MainActivity::class.java)
- .addNextIntent(intent)
+ .addParentStack(MainActivity::class.java)
+ .addNextIntent(intent)
val notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT)
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
- .setSmallIcon(R.mipmap.ic_launcher)
- .setContentIntent(notificationPendingIntent)
- .setAutoCancel(true)
- .setContentTitle(title)
+ .setSmallIcon(R.mipmap.ic_launcher)
+ .setContentIntent(notificationPendingIntent)
+ .setAutoCancel(true)
+ .setContentTitle(title)
subtitle.let { notification.setContentText(it) }
message.let { notification.setSubText(it) }
@@ -167,59 +178,63 @@ fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt())
object DateUtils {
@JvmStatic
- fun dateTimeNow() : String {
+ fun dateTimeNow(): String {
val format = SimpleDateFormat("dd-MMM-yyy hh:mm:ss")
return format.format(Date())
}
}
fun isJSONValid(jsonString: String?): Boolean {
- try { JSONObject(jsonString) } catch (ex: JSONException) {
- try { JSONArray(jsonString) } catch (ex1: JSONException) {
+ try {
+ JSONObject(jsonString)
+ } catch (ex: JSONException) {
+ try {
+ JSONArray(jsonString)
+ } catch (ex1: JSONException) {
return false
}
}
return true
}
-fun saveLog(context: Context, tag: String, message: String){
+fun saveLog(context: Context, tag: String, message: String) {
val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE)
var logs = pref.getString("LOGS", "")
logs += "$tag -> $message \n"
pref.edit().putString("LOGS", logs).apply();
}
-fun getLogs(context: Context) : String?{
+fun getLogs(context: Context): String? {
val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE)
return pref.getString("LOGS", "")
}
-class HTTPResponse(data: T){
- final var data:T = data
+class HTTPResponse(data: T) {
+ final var data: T = data
}
-fun httpPost(url: String, body: Map, onSuccess: (response: HTTPResponse) -> Unit, onError: (error: Exception) -> Unit){
+fun httpPost(url: String, body: Map, onSuccess: (response: HTTPResponse) -> Unit, onError: (error: Exception) -> Unit) {
val gson = Gson()
- val type = object : TypeToken() {}.type
+ val type = object : TypeToken() {}.type
val jsonBody = gson.toJson(body)
url.httpPost()
- .jsonBody(jsonBody, Charsets.UTF_8)
- .timeout(10000)
- .header("Content-Type", "application/json")
- .header("Allow", "*/*")
- .response { request, response, result ->
- result.doAsyncResult { }
- result.fold({ data ->
- val dataString = String(data)
- if (isJSONValid(dataString)) {
- val responseData = gson.fromJson(dataString, type)
- onSuccess(HTTPResponse(responseData))
- } else {
- onError(Exception("Invalid response from server (Not a valid JSON)"))
- }
- }, {
- onError(it)
- })
+ .jsonBody(jsonBody, Charsets.UTF_8)
+ .timeout(10000)
+ .header("Content-Type", "application/json")
+ .header("Allow", "*/*")
+ .response { request, response, result ->
+ result.doAsyncResult { }
+ result.fold({ data ->
+ val dataString = String(data)
+ if (isJSONValid(dataString)) {
+ val responseData = gson.fromJson(dataString, type)
+ onSuccess(HTTPResponse(responseData))
+ } else {
+ onError(Exception("Invalid response from server (Not a valid JSON)"))
+ }
+ }, {
+ onError(it)
+ })
- }
+ }
}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt
index d9dc209e..db4f911a 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt
@@ -2,128 +2,128 @@ package com.ejada.hmg.utils
import android.content.Context
import android.content.SharedPreferences
-import android.os.Build
import com.ejada.hmg.BuildConfig
import com.google.gson.Gson
class Logs {
- enum class STATUS{
+ enum class STATUS {
SUCCESS,
ERROR;
}
- class GeofenceEvent{
- companion object{
- fun save(context: Context, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){
- Logs.Common.save(context,"GeofenceEvent", tag, message, status)
+
+ class GeofenceEvent {
+ companion object {
+ fun save(context: Context, tag: String, message: String, status: Logs.STATUS = STATUS.SUCCESS) {
+ Logs.Common.save(context, "GeofenceEvent", tag, message, status)
}
- fun list(context: Context, tag:String? = null, status:Logs.STATUS? = null):List{
- return Logs.Common.list(context,"GeofenceEvent", tag, status)
+ fun list(context: Context, tag: String? = null, status: Logs.STATUS? = null): List {
+ return Logs.Common.list(context, "GeofenceEvent", tag, status)
}
- fun raw(context: Context):String{
- return Logs.Common.raw(context,"GeofenceEvent")
+ fun raw(context: Context): String {
+ return Logs.Common.raw(context, "GeofenceEvent")
}
}
}
- class RegisterGeofence{
- companion object{
- fun save(context: Context, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){
- Logs.Common.save(context,"RegisterGeofence", tag, message, status)
+ class RegisterGeofence {
+ companion object {
+ fun save(context: Context, tag: String, message: String, status: Logs.STATUS = STATUS.SUCCESS) {
+ Logs.Common.save(context, "RegisterGeofence", tag, message, status)
}
- fun list(context: Context, tag:String? = null, status:Logs.STATUS? = null):List{
- return Logs.Common.list(context,"RegisterGeofence", tag, status)
+ fun list(context: Context, tag: String? = null, status: Logs.STATUS? = null): List {
+ return Logs.Common.list(context, "RegisterGeofence", tag, status)
}
- fun raw(context: Context):String{
- return Logs.Common.raw(context,"RegisterGeofence");
+ fun raw(context: Context): String {
+ return Logs.Common.raw(context, "RegisterGeofence");
}
}
}
- companion object{
- private var pref:SharedPreferences? = null
- fun save(context: Context, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){
- Logs.Common.save(context,"Logs", tag, message, status)
+ companion object {
+ private var pref: SharedPreferences? = null
+ fun save(context: Context, tag: String, message: String, status: Logs.STATUS = STATUS.SUCCESS) {
+ Logs.Common.save(context, "Logs", tag, message, status)
}
- fun list(context: Context, tag:String? = null, status:Logs.STATUS? = null):List{
- return Logs.Common.list(context,"Logs", tag, status)
+ fun list(context: Context, tag: String? = null, status: Logs.STATUS? = null): List {
+ return Logs.Common.list(context, "Logs", tag, status)
}
- fun raw(context: Context):String{
- return Logs.Common.raw(context,"Logs");
+ fun raw(context: Context): String {
+ return Logs.Common.raw(context, "Logs");
}
- private fun storage(context: Context):SharedPreferences{
- if(pref == null) {
+ private fun storage(context: Context): SharedPreferences {
+ if (pref == null) {
pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE)
}
return pref!!
}
}
- private class Common{
- companion object{
+ private class Common {
+ companion object {
private val gson = Gson()
- fun save(context: Context, key:String, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){
- if(!BuildConfig.DEBUG)
+ fun save(context: Context, key: String, tag: String, message: String, status: Logs.STATUS = STATUS.SUCCESS) {
+ if (!BuildConfig.DEBUG)
return
-
+
val pref = Logs.storage(context)
- val string = pref.getString(key,"{}")
- val json = gson.fromJson(string,LogsContainerModel::class.java)
+ val string = pref.getString(key, "{}")
+ val json = gson.fromJson(string, LogsContainerModel::class.java)
json.add(
- LogModel().apply {
- this.TAG = tag
- this.MESSAGE = message
- this.STATUS = status.name
- this.DATE = DateUtils.dateTimeNow()
- }
+ LogModel().apply {
+ this.TAG = tag
+ this.MESSAGE = message
+ this.STATUS = status.name
+ this.DATE = DateUtils.dateTimeNow()
+ }
)
- pref.edit().putString(key,gson.toJson(json)).apply()
+ pref.edit().putString(key, gson.toJson(json)).apply()
}
- fun list(context: Context, key:String, tag:String? = null, status:Logs.STATUS? = null):List{
+ fun list(context: Context, key: String, tag: String? = null, status: Logs.STATUS? = null): List {
val pref = Logs.storage(context)
- val string = pref.getString(key,"{}")
- val json = gson.fromJson(string,LogsContainerModel::class.java)
- if(tag == null && status == null) {
+ val string = pref.getString(key, "{}")
+ val json = gson.fromJson(string, LogsContainerModel::class.java)
+ if (tag == null && status == null) {
return json.LOGS
- }else if(tag != null && status != null){
+ } else if (tag != null && status != null) {
return json.LOGS.filter { (it.TAG == tag && it.STATUS == status.name) }
- }else if(tag != null){
+ } else if (tag != null) {
return json.LOGS.filter { (it.TAG == tag) }
- }else if(status != null){
+ } else if (status != null) {
return json.LOGS.filter { (it.STATUS == status.name) }
}
return listOf()
}
- fun raw(context: Context, key:String):String{
+ fun raw(context: Context, key: String): String {
val pref = Logs.storage(context)
- val string = pref.getString(key,"{}")
+ val string = pref.getString(key, "{}")
return string!!
}
}
}
- class LogModel{
- lateinit var TAG:String
- lateinit var MESSAGE:String
- lateinit var STATUS:String
- lateinit var DATE:String
+ class LogModel {
+ lateinit var TAG: String
+ lateinit var MESSAGE: String
+ lateinit var STATUS: String
+ lateinit var DATE: String
- companion object{
- fun with(tag:String, message:String, status:String):LogModel{
+ companion object {
+ fun with(tag: String, message: String, status: String): LogModel {
return LogModel().apply {
this.TAG = tag
this.MESSAGE = message
@@ -134,9 +134,9 @@ class Logs {
}
}
- class LogsContainerModel{
+ class LogsContainerModel {
var LOGS = mutableListOf()
- fun add(log:LogModel){
+ fun add(log: LogModel) {
LOGS.add(log)
}
}
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt
index ebb04456..84e27e29 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt
@@ -1,6 +1,6 @@
package com.ejada.hmg.utils
-import com.ejada.hmg.MainActivity
+import com.cloud.diplomaticquarterapp.MainActivity
import com.ejada.hmg.opentok.OpenTok
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt
index 9a66f4b3..c6b2476d 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt
@@ -11,7 +11,7 @@ import android.widget.Toast
import androidx.core.app.ActivityCompat.startActivityForResult
import android.net.wifi.WifiManager
import android.util.Log
-import com.ejada.hmg.MainActivity
+import com.cloud.diplomaticquarterapp.MainActivity
import com.ejada.hmg.hmgwifi.HMG_Guest
import com.ejada.hmg.geofence.GeoZoneModel
import com.ejada.hmg.geofence.HMG_Geofence
diff --git a/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_all_in-one_connect_screen.dart b/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_all_in-one_connect_screen.dart
index 8b0ca498..02f3c0ad 100644
--- a/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_all_in-one_connect_screen.dart
+++ b/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_all_in-one_connect_screen.dart
@@ -1,5 +1,4 @@
-import 'package:diplomaticquarterapp/extensions/string_extensions.dart';
-import 'package:flutter_blue_plus/flutter_blue_plus.dart';
+import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/ble_devices_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart';
@@ -8,7 +7,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class AndesAllInOneConnectScreen extends StatefulWidget {
- final BluetoothDevice deviceModel;
+ final BleDeviceModel deviceModel;
const AndesAllInOneConnectScreen({this.deviceModel});
@@ -22,13 +21,13 @@ class _AndesAllInOneConnectScreenState extends State
@override
void initState() {
myTrackersVm = context.read();
- myTrackersVm.connectAndesfitAllInOneDevice(widget.deviceModel);
+ myTrackersVm.connectDevice(widget.deviceModel);
super.initState();
}
@override
void dispose() {
- myTrackersVm.disConnectAndesfitDevice(widget.deviceModel);
+ myTrackersVm.disConnectDevice();
super.dispose();
}
@@ -36,32 +35,27 @@ class _AndesAllInOneConnectScreenState extends State
return Expanded(
child: ListView(
children: [
- if (myTrackersViewModel.andesfitWeightScaleData == null && (myTrackersViewModel.isAndesfitDeviceConnected != null && myTrackersViewModel.isAndesfitDeviceConnected)) ...[
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- mHeight(24.0),
- Column(
- children: [
- Text("Please Wait", style: TextStyle(fontSize: 20)),
- ],
+ if (myTrackersViewModel.checkMeInfo == null) ...[
+ Padding(
+ padding: const EdgeInsets.all(24.0),
+ child: Center(
+ child: Text(
+ "Some animation with the instruction",
+ style: TextStyle(fontSize: 9.0),
),
- mHeight(24.0),
- ],
- ),
- ] else if (false) ...[
- // Add the UI here for All In One Monitor
+ ),
+ )
] else ...[
Padding(
padding: const EdgeInsets.all(24.0),
child: Center(
child: Text(
- "Some animation with the instruction",
+ "${myTrackersViewModel.checkMeInfo.toString()}",
style: TextStyle(fontSize: 9.0),
),
),
)
- ],
+ ]
],
),
);
@@ -70,7 +64,7 @@ class _AndesAllInOneConnectScreenState extends State
@override
Widget build(BuildContext context) {
return AppScaffold(
- appBarTitle: "${widget.deviceModel.localName}",
+ appBarTitle: "${widget.deviceModel.name}",
showNewAppBar: true,
isShowDecPage: false,
showNewAppBarTitle: true,
@@ -89,9 +83,9 @@ class _AndesAllInOneConnectScreenState extends State
children: [
Expanded(
child: DefaultButton(
- "Disconnect with ${widget.deviceModel.localName}",
+ "Disconnect with ${widget.deviceModel.name}",
() async {
- myTrackersVm.disConnectAndesfitDevice(widget.deviceModel);
+ myTrackersVm.disConnectDevice();
Navigator.pop(context);
},
textColor: Colors.white,
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 88993f14..da3470a9 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
@@ -36,8 +36,12 @@ class _BleDevicesScreenState extends State {
@override
void initState() {
myTrackersVm = context.read();
- myTrackersVm.startSearchingForTracker();
- myTrackersVm.startTimerForNativeScan();
+ if (myTrackersVm.currentSelectedTrackerType == TrackerTypeEnum.AllInOneTracker) {
+ myTrackersVm.startSearchingForCheckMePro();
+ } else {
+ myTrackersVm.startSearchingForTracker();
+ myTrackersVm.startTimerForNativeScan();
+ }
super.initState();
}
@@ -48,7 +52,7 @@ class _BleDevicesScreenState extends State {
void onDeviceTapped(BleDeviceModel device) {
myTrackersVm.isDeviceSelected = true;
- log("isDeviceSelected from Screen:${myTrackersVm.isDeviceSelected}");
+ log("isDeviceSelected from Screen: ${myTrackersVm.isDeviceSelected}");
FlutterBluePlus.stopScan();
switch (device.deviceType) {
case TrackerTypeEnum.OxymeterTracker:
@@ -112,10 +116,9 @@ class _BleDevicesScreenState extends State {
break;
case TrackerTypeEnum.AllInOneTracker:
if (myTrackersVm.isDeviceFromAndesFit(device.name)) {
- Navigator.pushReplacement(context, FadePage(page: AndesAllInOneConnectScreen(deviceModel: device.andesfitBluetoothDevice)));
return;
}
- // TODO: Handle this case.
+ Navigator.pushReplacement(context, FadePage(page: AndesAllInOneConnectScreen(deviceModel: device)));
break;
}
}
diff --git a/lib/pages/medical/my_trackers/ble_device_type_screens/select_tracker_type.dart b/lib/pages/medical/my_trackers/ble_device_type_screens/select_tracker_type.dart
index 05fb6694..471090d0 100644
--- a/lib/pages/medical/my_trackers/ble_device_type_screens/select_tracker_type.dart
+++ b/lib/pages/medical/my_trackers/ble_device_type_screens/select_tracker_type.dart
@@ -1,11 +1,5 @@
-import 'dart:convert';
-import 'dart:developer';
-import 'dart:typed_data';
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_all_in-one_connect_screen.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_device_type_screens/ble_devices_screen.dart';
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_response.dart';
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/device_info.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart';
import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
@@ -16,9 +10,6 @@ import 'package:provider/provider.dart';
class SelectTrackerType extends StatelessWidget {
const SelectTrackerType();
- Uint8List convertIntArrayToByteArray(List intArray) {
- return Uint8List.fromList(intArray);
- }
List myTrackersTypeList({BuildContext context}) {
List medical = [];
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 9d5d7f46..1e92c67f 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
@@ -10,6 +10,21 @@ class BleChannel {
// static const platform_ios_ekg = MethodChannel('BLE-Platform-Bridge-IOS-EKG');
//BLE-Platform-Bridge
+ static Future scanCheckMeProNative() async {
+ try {
+ String result;
+ print("----------Flutter scanCheckMeProNative -------");
+
+ result = await platform.invokeMethod('scanForCheckMePro');
+
+ print("----------Flutter scanCheckMeProNative Result -------");
+ print(result);
+ return result;
+ } catch (e) {
+ return "Error: $e";
+ }
+ }
+
static Future scanResultsNative(List deviceType) async {
try {
String result;
@@ -31,6 +46,7 @@ class BleChannel {
print("----------Flutter stopNativeScan -------");
result = await platform.invokeMethod('stopScan');
+ result = await platform.invokeMethod('stopScanCheckMe');
print("----------Flutter Result stopNativeScan -------");
print(result);
@@ -55,6 +71,21 @@ class BleChannel {
}
}
+ static Future connectDeviceCheckMe(List device) async {
+ try {
+ String result;
+ print("----------Flutter init connectDeviceCheckMe -------");
+
+ result = await platform.invokeMethod('connectDeviceCheckMe', device);
+
+ print("----------Flutter Result connectDeviceCheckMe -------");
+ print(result);
+ return result;
+ } catch (e) {
+ return "Error: $e";
+ }
+ }
+
static Future getECGFilesList(List device) async {
try {
print("----------Flutter getECGFilesList -------");
@@ -95,6 +126,7 @@ class BleChannel {
try {
print("----------Flutter disconnect -------");
final String result = await platform.invokeMethod('disconnectDevice');
+ final String result2 = await platform.invokeMethod('disconnectCheckMe');
print("----------Flutter Result -------");
print(result);
return result;
@@ -102,4 +134,16 @@ class BleChannel {
return "Error: $e";
}
}
+
+ static Future getDeviceInfoCheckMePro() async {
+ try {
+ print("----------Flutter getDeviceInfoCheckMePro -------");
+ final String result = await platform.invokeMethod('getDeviceInfoCheckMePro');
+ print("----------Flutter getDeviceInfoCheckMePro result -------");
+ print(result);
+ return result;
+ } catch (e) {
+ return "Error: $e";
+ }
+ }
}
diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_info_model.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_info_model.dart
new file mode 100644
index 00000000..6d625ff1
--- /dev/null
+++ b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_info_model.dart
@@ -0,0 +1,61 @@
+class CheckMeInfoModel {
+ String region;
+ String model;
+ String hardwareVer;
+ String softwareVer;
+ String languageVer;
+ String curLanguage;
+ String fileVer;
+ String sPCPVer;
+ String application;
+ String sN;
+ String branchCode;
+
+ CheckMeInfoModel(
+ {this.region,
+ this.model,
+ this.hardwareVer,
+ this.softwareVer,
+ this.languageVer,
+ this.curLanguage,
+ this.fileVer,
+ this.sPCPVer,
+ this.application,
+ this.sN,
+ this.branchCode});
+
+ @override
+ String toString() {
+ return 'CheckMeInfoModel{region: $region, model: $model, hardwareVer: $hardwareVer, softwareVer: $softwareVer, languageVer: $languageVer, curLanguage: $curLanguage, fileVer: $fileVer, sPCPVer: $sPCPVer, application: $application, sN: $sN, branchCode: $branchCode}';
+ }
+
+ CheckMeInfoModel.fromJson(Map json) {
+ region = json['Region'];
+ model = json['Model'];
+ hardwareVer = json['HardwareVer'];
+ softwareVer = json['SoftwareVer'];
+ languageVer = json['LanguageVer'];
+ curLanguage = json['CurLanguage'];
+ fileVer = json['FileVer'];
+ sPCPVer = json['SPCPVer'];
+ application = json['Application'];
+ sN = json['SN'];
+ branchCode = json['BranchCode'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['Region'] = this.region;
+ data['Model'] = this.model;
+ data['HardwareVer'] = this.hardwareVer;
+ data['SoftwareVer'] = this.softwareVer;
+ data['LanguageVer'] = this.languageVer;
+ data['CurLanguage'] = this.curLanguage;
+ data['FileVer'] = this.fileVer;
+ data['SPCPVer'] = this.sPCPVer;
+ data['Application'] = this.application;
+ data['SN'] = this.sN;
+ data['BranchCode'] = this.branchCode;
+ return data;
+ }
+}
diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_response.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_response.dart
deleted file mode 100644
index 6ab90fc0..00000000
--- a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_response.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-import 'dart:typed_data';
-
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart';
-
-class CheckMeResponse {
- List bytes;
- int cmd;
- int pkgNo;
- int len;
- List content;
-
- CheckMeResponse(List bytes) {
- this.bytes = bytes;
- this.cmd = bytes[1];
- this.pkgNo = bytes.sublist(3, 5).toUInt();
- this.len = bytes.sublist(5, 7).toUInt();
- this.content = bytes.sublist(7, 7 + len);
- }
-
- @override
- String toString() {
- return 'CheckMeResponse{bytes: $bytes, cmd: $cmd, pkgNo: $pkgNo, len: $len, content: $content}';
- }
-}
diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/device_info.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/device_info.dart
deleted file mode 100644
index 971114ac..00000000
--- a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/device_info.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-import 'dart:convert';
-
-class DeviceInfo {
- int len;
- List content;
- String deviceStr;
- Map json;
-
- DeviceInfo(List buf) {
- len = _toUInt(buf.sublist(5, 7));
- content = buf.sublist(7, 7 + len);
- deviceStr = utf8.decode(content);
- deviceStr = deviceStr.substring(0, deviceStr.indexOf("}") + 1);
- json = jsonDecode(deviceStr);
- }
-
- int _toUInt(List bytes) {
- var result = 0;
- for (var i = 0; i < bytes.length; i++) {
- result += bytes[i].toUnsigned(8) << (i * 8);
- }
- return result;
- }
-}
\ No newline at end of file
diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/end_read_pkg.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/end_read_pkg.dart
deleted file mode 100644
index 9fae7334..00000000
--- a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/end_read_pkg.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/bt_constants.dart';
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart';
-import 'package:flutter/services.dart';
-
-class EndReadPkg {
- Uint8List buf;
-
- EndReadPkg() {
- int commonPkgLength = BTConstants.COMMON_PKG_LENGTH; // Assuming BTConstant.COMMON_PKG_LENGTH is 7
- buf = Uint8List(commonPkgLength);
-
- buf[0] = 0xAA;
- buf[1] = BTConstants.CMD_WORD_END_READ; // Assuming BTConstant.CMD_WORD_END_READ is defined elsewhere
- buf[2] = ~BTConstants.CMD_WORD_END_READ; // Assuming BTConstant.CMD_WORD_END_READ is defined elsewhere
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = 0;
- buf[6] = 0;
-
- buf[buf.length - 1] = buf.calCRC8();
- }
-}
diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/read_content_pkg.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/read_content_pkg.dart
deleted file mode 100644
index cb49f55b..00000000
--- a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/read_content_pkg.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-import 'dart:typed_data';
-
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/bt_constants.dart';
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart';
-
-class ReadContentPkg {
- List buf;
-
- ReadContentPkg(int pkgNum) {
- buf = List.filled(7, 0);
- buf[0] = 0xAA.toByte();
- buf[1] = BTConstants.CMD_WORD_READ_CONTENT; // Assuming CMD_WORD_READ_CONTENT is defined elsewhere
- buf[2] = (BTConstants.CMD_WORD_READ_CONTENT.inv()).toByte(); // Assuming CMD_WORD_READ_CONTENT is defined elsewhere
- buf[3] = pkgNum.toByte(); // Package number
- buf[4] = (pkgNum >> 8).toByte();
- buf[5] = 0; // Data chunk size, default is 0
- buf[6] = 0;
- buf[buf.length - 1] = buf.calCRC8();
- }
-}
diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/start_read_pkg.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/start_read_pkg.dart
deleted file mode 100644
index 980f972d..00000000
--- a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/start_read_pkg.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-import 'dart:developer';
-
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/bt_constants.dart';
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart';
-import 'package:flutter/services.dart';
-
-class StartReadPkg {
- //[u, s, r, ., d, a, t]
-
- //[-86, 3, -4, 0, 0, 8, 0, 117, 115, 114, 46, 100, 97, 116, 0, 0]
-
- List buf;
-
- StartReadPkg(String fileName) {
- int commonPkgLength = BTConstants.COMMON_PKG_LENGTH;
-
- int bufLength = commonPkgLength + fileName.length + 1;
- buf = List.filled(bufLength, 0);
-
- buf[0] = (0xAA).toByte();
- buf[1] = BTConstants.CMD_WORD_START_READ;
- buf[2] = ((BTConstants.CMD_WORD_START_READ).inv()).toByte();
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = (bufLength - commonPkgLength).toByte();
- buf[6] = ((bufLength - commonPkgLength) >> 8).toByte();
-
- if (fileName != null) {
- List tempFile = fileName.codeUnits;
-
- for (int i = 0; i < tempFile.length; i++) {
- buf[i + 7] = tempFile[i].toByte();
- }
- }
-
- buf[bufLength - 1] = buf.calCRC8();
-
- // [-86, 3, -4, 0, 0, 8, 0, 117, 115, 114, 46, 100, 97, 116, 0, 124] --> KOTLIN
- // [-86, 3, -4, 0, 0, 8, 0, 117, 115, 114, 46, 100, 97, 116, 0, 124] --> DART
- }
-}
diff --git a/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/temperature_info.dart b/lib/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/temperature_info.dart
deleted file mode 100644
index e69de29b..00000000
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 69569e73..5f6cd5cf 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
@@ -1,11 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_response.dart';
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/device_info.dart';
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/end_read_pkg.dart';
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/read_content_pkg.dart';
-import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/start_read_pkg.dart';
+import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/all_in_one_monitor/check_me_info_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/bt_constants.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/andesfit_devices/weight_data_model.dart';
import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_models/ble_devices_model.dart';
@@ -34,6 +30,8 @@ String kRealTimeDataBPMeasuring = "RealTimeDataBPMeasuring";
String kRealTimeDataBPResult = "RealTimeDataBPResult";
String kOxyRtParam = "OxyRtParam";
String kDevicesList = "DevicesList";
+String kDevicesListCheckMe = "DevicesListCheckMe";
+String kInfoDataCheckMe = "infoDataCheckMe";
String kRealTimeDataECGMeasuring = "RealTimeDataECGMeasuring"; // This is for the device that measures BP and ECG also Like BP2 0567
String kRealTimeDataECGResult = "RealTimeDataECGResult";
String kRealTimeDataECG = "RealTimeDataECG";
@@ -105,7 +103,14 @@ class MyTrackersViewModel extends ChangeNotifier {
};
List ecgEnabledDevices = ["BP2 0567", "DuoEK", "ER1", "PM101897"];
- List andesFitDevices = ["BPM", "PM101897", "SDIC", "TEMP", "Samico GL", "BLE-MSA", "Checkme 1316"];
+ List andesFitDevices = [
+ "BPM",
+ "PM101897",
+ "SDIC",
+ "TEMP",
+ "Samico GL",
+ "BLE-MSA",
+ ];
StreamSubscription bleDevicesStream;
@@ -206,6 +211,13 @@ class MyTrackersViewModel extends ChangeNotifier {
notifyListeners();
}
+ String checkMeInfo;
+
+ void updateCheckMeInfoModel(String mapData) {
+ checkMeInfo = mapData;
+ notifyListeners();
+ }
+
Widget getFilesListWidget(List filesList, BuildContext context) {
return Material(
child: SizedBox(
@@ -300,6 +312,25 @@ class MyTrackersViewModel extends ChangeNotifier {
});
}
+ Future startSearchingForCheckMePro() async {
+ log("selectedTracker in startSearchingForCheckMePro: ${currentSelectedTrackerType.name}");
+ await checkBLEPermissions();
+ eventChannel.receiveBroadcastStream().listen((event) {
+ print('Received event---: $event');
+ print(event['type']);
+ if (event['type'] == kDevicesListCheckMe) {
+ List list = [json.decode(event['data'])];
+ parsesDevicesList(list);
+ }
+
+ if (event['type'] == kInfoDataCheckMe) {
+ updateCheckMeInfoModel(event['data'].toString());
+ }
+ });
+
+ await scanForCheckMe();
+ }
+
Future startSearchingForTracker() async {
log("selectedTracker: ${currentSelectedTrackerType.name}");
@@ -369,7 +400,9 @@ class MyTrackersViewModel extends ChangeNotifier {
void resetList() {
devicesList.clear();
- bleDevicesStream.cancel();
+ if (bleDevicesStream != null) {
+ bleDevicesStream.cancel();
+ }
FlutterBluePlus.stopScan();
secondsToWaitForNativeScan = 5;
}
@@ -383,7 +416,11 @@ class MyTrackersViewModel extends ChangeNotifier {
}
Future connectDevice(BleDeviceModel device) async {
- await BleChannel.connectDevice([device.name, device.model.toString(), currentSelectedTrackerType.name]);
+ if (currentSelectedTrackerType == TrackerTypeEnum.AllInOneTracker) {
+ await BleChannel.connectDeviceCheckMe([device.name, device.model.toString(), currentSelectedTrackerType.name]);
+ } else {
+ await BleChannel.connectDevice([device.name, device.model.toString(), currentSelectedTrackerType.name]);
+ }
}
Future disConnectDevice() async {
@@ -395,6 +432,10 @@ class MyTrackersViewModel extends ChangeNotifier {
await BleChannel.scanResultsNative([currentSelectedTrackerType.name]);
}
+ Future scanForCheckMe() async {
+ await BleChannel.scanCheckMeProNative();
+ }
+
Future stopNativeScan() async {
await BleChannel.stopNativeScan();
}
@@ -1061,233 +1102,7 @@ class MyTrackersViewModel extends ChangeNotifier {
int result = 0;
int currentPkg = 0;
- BluetoothCharacteristic allInOneWriteCharacteristics;
-
- sendCommand(List bytes) {
- log("trying to write on $allInOneWriteCharacteristics");
- allInOneWriteCharacteristics.write(bytes, withoutResponse: true);
- }
-
Future connectAndesfitAllInOneDevice(BluetoothDevice device) async {
log("deviceToConnect: ${device.toString()}");
-
- device.connectionState.listen((BluetoothConnectionState state) async {
- if (state == BluetoothConnectionState.disconnected) {
- isAndesfitDeviceConnected = false;
- notifyListeners();
- }
- if (state == BluetoothConnectionState.connected) {
- isAndesfitDeviceConnected = true;
- notifyListeners();
- bleDevicesStream.cancel();
-
- List services = await device.discoverServices();
- services.forEach((service) {
- if (service.serviceUuid.toString().toLowerCase() == BLEUtils.ALL_IN_ONE_SERVICE.toLowerCase()) {
- service.characteristics.forEach((characteristic) async {
- log("characteristics : ${characteristic.characteristicUuid}");
- if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.ALL_IN_ONE_READ_CHARACTERISTIC.toLowerCase()) {
- characteristic.onValueReceived.listen((event) {
- log("onValueReceived 9A57 Stream");
- log(event.toString());
- handleDataPool(event);
- });
-
- await Future.delayed(Duration(milliseconds: 1000)).then((value) async {
- log("-----Delayed 9A57 notify true done-----");
- if (!characteristic.isNotifying) await characteristic.setNotifyValue(true).catchError((err) {});
- });
- } else if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.ALL_IN_ONE_WRITE_CHARACTERISTIC.toLowerCase()) {
- print(characteristic.characteristicUuid);
- print(characteristic.properties.toString());
-
- allInOneWriteCharacteristics = characteristic;
-
- await Future.delayed(Duration(milliseconds: 3000)).then((value) => getFile("usr.dat"));
- // await Future.delayed(Duration(milliseconds: 3000)).then((value) async {
- // characteristic.write([-86, 3, -4, 0, 0, 8, 0, 117, 115, 114, 46, 100, 97, 116, 0, 124], withoutResponse: true).then((value) {
- // print("----E1A3 get User Info command data written----");
- // });
- // });
- }
- });
- }
- });
- }
- });
-
- await device.connect(timeout: Duration(seconds: 35));
- }
-
- getFile(String fileName) async {
- log("writing command: $fileName");
- log("on characteristic: $allInOneWriteCharacteristics");
- cmdState = 1;
- var pkg = StartReadPkg(fileName);
- log("----- Current PKG ----- ${pkg.buf.toString()}");
- sendCommand(pkg.buf);
- }
-
- List handleDataPool(List bytes) {
- log("bytes I got in dataPool: $bytes");
- var bytesLeft = bytes;
- if (bytes == null || bytes.length < 8) {
- return bytes;
- }
-
- for (int i = 0; i < bytes.length - 7; i++) {
- if (bytes[i] != 0x55.toByte() || bytes[i + 1] != (bytes[i + 2].inv()).toByte()) {
- continue;
- }
-
- // need content length
- var len = bytes.sublist(i + 5, i + 7).toUInt();
- if (i + 8 + len > bytes.length) {
- continue;
- }
-
- var temp = bytes.sublist(i, i + 8 + len);
- if (temp.last == temp.calCRC8()) {
- if (cmdState >= 1 && cmdState <= 3) {
- var bleResponse = CheckMeResponse(temp);
-
- log("bleResponse: $bleResponse");
- if (cmdState == 1) {
- currentFileSize = bleResponse.content.toUInt();
- pkgTotal = currentFileSize ~/ 512;
- if (bleResponse.cmd == 1) {
- result = 1;
- var pkg = EndReadPkg();
- sendCommand(pkg.buf);
- cmdState = 3;
- } else if (bleResponse.cmd == 0) {
- var pkg = ReadContentPkg(currentPkg);
-
- log("ReadContentPkg pkg before: ${pkg.buf}");
-
- if (pkg.buf.last == 204) {
- pkg.buf.last = 106;
- }
-
- log("ReadContentPkg pkg: ${pkg.buf}");
-
- //[-86, 4, -5, 0, 0, 0, 204] --> DART
- //[-86, 4, -5, 0, 0, 0, 106] --> KOTLIN
- sendCommand(pkg.buf);
- currentPkg++;
- cmdState = 2;
- }
- } else if (cmdState == 2) {
- // bleResponse.content.apply {
- // fileData = add(fileData, this)
- // fileData?.let {
- // dataScope.launch {
- // fileProgressChannel.send(
- // FileProgress(
- // currentFileName,
- // it.size * 100 / currentFileSize,
- // true
- // )
- // )
- // }
- // }
- // }
-
- if (currentPkg > pkgTotal) {
- // fileData?.apply {
- // result = 0
- // Log.i("file", "receive $currentFileName")
- // File(Constant.getPathX(currentFileName)).writeBytes(this)
- // }
- var pkg = EndReadPkg();
- log("file bytes ${pkg.buf}");
- sendCommand(pkg.buf);
- cmdState = 3;
- } else {
- var pkg = ReadContentPkg(currentPkg);
- sendCommand(pkg.buf);
- currentPkg++;
- }
- } else if (cmdState == 3) {
- currentPkg = 0;
- cmdState = 0;
- // dataScope.launch {
- // fileProgressChannel.send(
- // FileProgress(
- // currentFileName,
- // 100,
- // result == 0
- // )
- // )
- // fileChannel.send(result)
- // }
- }
- } else if (cmdState == 4) {
- var deviceInfo = DeviceInfo(temp);
- }
-
- List tempBytes;
- if (i + 8 + len == bytes.length) {
- tempBytes = null;
- } else {
- tempBytes = bytes.sublist(i + 8 + len, bytes.length);
- }
-
- return handleDataPool(tempBytes);
- }
- }
-
- return bytesLeft;
- }
-}
-
-extension BTExtensions on int {
- int toByte() {
- const int maxUnsignedByteValue = 255;
- const int maxSignedByteValue = 127;
- const int minSignedByteValue = -128;
-
- // Mask out all but the least significant 8 bits
- int maskedValue = this & maxUnsignedByteValue;
-
- // Check if the MSB is set (indicating a negative value)
- bool isNegative = maskedValue & (1 << 7) != 0;
-
- // If the MSB is set, convert to a signed byte using two's complement
- if (isNegative) {
- // Invert the bits
- maskedValue = ~maskedValue & maxUnsignedByteValue;
- // Add 1 to get the two's complement representation
- maskedValue = (maskedValue + 1) & maxSignedByteValue;
- // Negate the value
- maskedValue *= -1;
- }
-
- return maskedValue;
- }
-
- int inv() {
- return ~this;
- }
-}
-
-extension BTExtensionss on List {
- int toUInt() {
- var result = 0;
- for (var i = 0; i < this.length; i++) {
- result += this[i].toUnsigned(8) << (i * 8);
- }
- return result;
- }
-
- int calCRC8() {
- if (this == null || this.isEmpty) {
- return 0;
- }
- int crc = 0;
- for (int i = 0; i < this.length - 1; i++) {
- crc = BTConstants.Table_CRC8[0xFF & (crc ^ this[i].toByte())];
- }
- return crc;
}
}