Compare commits

...

79 Commits

Author SHA1 Message Date
Faiz Hashmi 66a9afa6f3 Merged latest 3.16 2 years ago
Faiz Hashmi 34e47421a3 Debugging exported crash 2 years ago
Faiz Hashmi 336536df4a Merged latest 3.16 2 years ago
Faiz Hashmi c10fb7f1a9 Merge branch 'dev_3.3_BLE' into dev_v3.13.6_BLE_Faiz
# Conflicts:
#	android/app/build.gradle
#	android/app/src/main/AndroidManifest.xml
#	android/build.gradle
#	assets/images/new-design/passport.svg
#	ios/Runner.xcodeproj/project.pbxproj
#	lib/config/config.dart
#	lib/config/localized_values.dart
#	lib/core/service/client/base_app_client.dart
#	lib/main.dart
#	lib/pages/Covid-DriveThru/covid-drivethru-location.dart
#	lib/pages/landing/landing_page.dart
#	lib/pages/medical/medical_profile_page_new.dart
#	lib/routes.dart
#	lib/uitl/translations_delegate_base.dart
#	lib/uitl/utils.dart
#	pubspec.yaml
2 years ago
Faiz Hashmi 6f2392bee3 Assets 2 years ago
Faiz Hashmi 6e96f9c0d0 Completed Flow 2 years ago
Faiz Hashmi 0830b4d248 Added rtSportsMode 2 years ago
Faiz Hashmi b136f63e40 Added SmartRingOperations 2 years ago
Faiz Hashmi c1751c05db Still in progress 2 years ago
Faiz Hashmi be294ae264 Connected the SmartRing 2 years ago
Faiz Hashmi 6cd410e2d9 Merge branch 'dev_3.3_BLE' of http://34.17.52.79/Haroon6138/diplomatic-quarter into dev_3.3_BLE 2 years ago
Faiz Hashmi 6fd429c883 Connected the SmartRing 2 years ago
haroon amjad 2922f74e9b updates 2 years ago
haroon amjad 518785323e Implementing CheckMePro on iOS 2 years ago
Faiz Hashmi 55b93feda3 Added ECG chart view 2 years ago
Faiz Hashmi 4ec93e8609 Completed the flow 2 years ago
Faiz Hashmi 6cd1e29998 Merge remote-tracking branch 'origin/dev_3.3_BLE' into dev_3.3_BLE
# Conflicts:
#	lib/pages/medical/my_trackers/ble_device_type_screens/ble_devices_screen.dart
2 years ago
Faiz Hashmi cd3783d9f6 Made data models for checkme pro operations 2 years ago
Faiz Hashmi 4d74d2143f Finally Got the CheckMePro Device Info 2 years ago
haroon amjad 32b32e34fd CheckMe Pro BLE implementation 2 years ago
Faiz Hashmi 322d0a8b5d Work in Progress for All in One Monitor 2 years ago
haroon amjad 1bf0f7558d updates 2 years ago
haroon amjad e0a54798ba VTPro lib added 2 years ago
haroon amjad 52e2e15b4d updates 2 years ago
haroon amjad b212fe6bbb updates 2 years ago
haroon amjad 275fa5ca3a Blood Pressure devices flow implemented 2 years ago
Faiz Hashmi fd79b10f41 Added andesfit Spirometer 2 years ago
Faiz Hashmi 0967e45752 Added till andesfit blood sugar device 2 years ago
Faiz Hashmi a494f454cb Andesfit WeightScale InProgress 2 years ago
Faiz Hashmi 4893a1f3af Merge remote-tracking branch 'origin/dev_3.3_BLE' into dev_3.3_BLE 2 years ago
Faiz Hashmi 43f149d940 Added ER1 Without fileList 2 years ago
haroon amjad 5dc0f571c8 Updates 2 years ago
haroon amjad c73333d164 BP Device implemented 2 years ago
Faiz Hashmi 1cc77e7d32 Completed the available ECG devices 2 years ago
Faiz Hashmi 8611903db0 Merge remote-tracking branch 'origin/dev_3.3_BLE' into dev_3.3_BLE 2 years ago
Faiz Hashmi 70ca4071fc Completed the oxymeter category 2 years ago
haroon amjad a271e700c7 Updates 2 years ago
haroon amjad 33b0900b37 SP-20 device integrated with iOS 2 years ago
haroon amjad be53844c58 DuoEK ECG iOS Integration done 2 years ago
haroon amjad c9994b8269 iOS ECG implementation 2 years ago
Faiz Hashmi 0a700270f4 Oxymeter integration completed 2 years ago
Faiz Hashmi c3ce151a79 Merge branch 'dev_3.3_BLE' of http://34.17.52.79/Haroon6138/diplomatic-quarter into dev_3.3_BLE
# Conflicts:
#	lib/viatom_ble/ble_connect.dart
2 years ago
Faiz Hashmi 6e97f8556f BP tracker Integration Completed 2 years ago
haroon amjad 6aea29e06a ECG iOS Updates 2 years ago
haroon amjad 83b681981d updates 2 years ago
haroon amjad 7e49dac7bd Updates 2 years ago
haroon amjad 886677d97e EKG iOS Integration 2 years ago
haroon amjad 3d1d61066f EKG iOS Integration in progress 2 years ago
Faiz Hashmi 7d023cdb35 BP tracker Integration in Progress 2 years ago
haroon amjad 6e6c4fef1a added EcgData file 2 years ago
haroon amjad 6ee64b923e updates 2 years ago
haroon amjad 6fd40305b4 ECG File list issue resolved 2 years ago
haroon amjad 1fd978e0c2 ECG Files concurrent reading from device 2 years ago
haroon amjad 68b83e5f98 LiveData retrieved from native layer 2 years ago
haroon amjad b137f4b09a ECG RealTime implementation 2 years ago
haroon amjad 433616c7b6 ECG Graph implemented 2 years ago
haroon amjad b6a3ae2380 updates EKG 2 years ago
haroon amjad 28cd6769ec updates for EKG 2 years ago
haroon amjad e52e75aefd Integrating EKG device 2 years ago
haroon amjad 2500441832 ViBeat device integrated 2 years ago
haroon amjad 9361d058fc update 2 years ago
haroon amjad e59734ce43 VT CheckMe O2 integrated 2 years ago
haroon amjad 55b447926e Merge branch 'development_v3.3' into dev_3.3_BLE
# Conflicts:
#	lib/config/localized_values.dart
#	lib/core/service/client/base_app_client.dart
#	lib/uitl/translations_delegate_base.dart
2 years ago
haroon amjad 1b39b1a5a8 updates 2 years ago
haroon amjad 448740a854 updates 2 years ago
haroon amjad 767f81c8cf Spirometer implementation completed 2 years ago
haroon amjad e282d73dcf Spirometer implementation 2 years ago
haroon amjad b183518a19 weight BLE implemented 2 years ago
haroon amjad efba7faa78 updates 2 years ago
haroon amjad 22d6a415c7 build.gradle changes 2 years ago
devamirsaleemahmad 3f2452c8fd Ble 2 years ago
haroon amjad 5b7cde43d1 Weight Scale BLE 2 years ago
haroon amjad 3f767f738a Weight scale in progress 2 years ago
haroon amjad aad249297c Flutter BLE version update 2 years ago
haroon amjad 382ff07a89 updates 2 years ago
haroon amjad 992f7dd454 updates 2 years ago
haroon amjad ee5f90aba1 BLE Blood Pressure implemented 2 years ago
haroon amjad 336c0f17b6 temperature device implemented 2 years ago
haroon amjad 23ab0483e0 BLE implementation started 2 years ago

@ -35,6 +35,12 @@ apply plugin: 'com.google.gms.google-services'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
//configurations.all {
// resolutionStrategy {
// force 'androidx.core:core-ktx:1.6.0'
// }
//}
configurations.all {
c ->
c.resolutionStrategy.eachDependency {
@ -42,8 +48,12 @@ configurations.all {
println dependency.requested.group
if (dependency.requested.group == 'org.bouncycastle') {
dependency.useTarget 'org.bouncycastle:bcprov-jdk15to18:1.68'
}
}
c.resolutionStrategy {
force 'androidx.core:core-ktx:1.6.0'
}
}
//configurations.all {
@ -117,11 +127,11 @@ android {
packagingOptions {
exclude 'META-INF/proguard/androidx-annotations.pro'
// pickFirst 'lib/x86/libc++_shared.so'
// pickFirst 'lib/x86_64/libc++_shared.so'
// pickFirst 'lib/armeabi-v7a/libc++_shared.so'
// pickFirst 'lib/arm64-v8a/libc++_shared.so'
// pickFirst '**/*.so'
pickFirst 'lib/x86/libc++_shared.so'
pickFirst 'lib/x86_64/libc++_shared.so'
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
pickFirst 'lib/arm64-v8a/libc++_shared.so'
pickFirst '**/*.so'
}
@ -129,6 +139,12 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
repositories {
flatDir {
dirs 'libs'
}
}
}
flutter {
@ -138,35 +154,13 @@ flutter {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.google.firebase:firebase-messaging:21.0.0"
// implementation ('com.google.firebase:firebase-inappmessaging-display:19.1.2',{
// exclude group: 'com.google.protobuf',module: 'protobuf-javalite'
// exclude group: 'com.google.protobuf',module: 'protobuf-lite'
// })
implementation 'pub.devrel:easypermissions:0.4.0'
// implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0'
// implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0'
implementation 'com.google.guava:guava:27.0.1-android'
// Dependency on local binaries
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.google.code.gson:gson:2.8.6'
// Dependency on a remote binary
// implementation 'com.example.android:app-magic:12.3'
implementation "us.zoom.videosdk:zoomvideosdk-core:1.10.1"
implementation "us.zoom.videosdk:zoomvideosdk-annotation:1.10.1"
implementation "us.zoom.videosdk:zoomvideosdk-videoeffects:1.10.1"
// Native Dependency
// implementation "us.zoom.videosdk:ZoomVideoSDK:1.10.11"
// implementation group: 'us.zoom.videosdk', name: 'zoomvideosdk-core', version: '1.10.11'
implementation "us.zoom.videosdk:zoomvideosdk-core:1.10.1"
implementation "us.zoom.videosdk:zoomvideosdk-annotation:1.10.1"
implementation "us.zoom.videosdk:zoomvideosdk-videoeffects:1.10.1"
implementation "org.jetbrains.anko:anko-commons:0.10.4"
implementation 'com.github.kittinunf.fuel:fuel:2.3.0' //for JVM
implementation 'com.github.kittinunf.fuel:fuel-android:2.3.0'
@ -178,5 +172,21 @@ dependencies {
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
androidTestImplementation "androidx.test:core:1.4.0"
// =======
implementation project(':blesdk_2301')
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
implementation 'androidx.work:work-runtime:2.7.0-alpha05'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2"
implementation 'com.android.support:appcompat-v7:27.1.1'
testImplementation 'junit:junit:4.12'
implementation 'io.reactivex.rxjava3:rxjava:3.1.3'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'no.nordicsemi.android:ble:2.2.4'
implementation(name: 'lepu-blepro-1.0.1', ext: 'aar')
implementation(name: 'liveeventbus-modified', ext: 'aar')
// implementation 'io.github.jeremyliao:live-event-bus-x:1.8.0'
implementation 'com.guolindev.permissionx:permissionx:1.7.1'
implementation 'org.apache.commons:commons-io:1.3.2' // for FileUtills in ER1 device configuration
}

@ -53,4 +53,6 @@
}
-dontwarn com.opentok.android.**
-dontwarn com.opentok.otc.**
-dontwarn com.opentok.otc.**
-keep class com.boskokg.flutter_blue_plus.* { *; }

@ -6,52 +6,113 @@
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" tools:node="remove"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:node="remove"/>
<uses-permission android:name="android.permission.BROADCAST_STICKY" tools:node="remove"/>
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" tools:node="remove"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" tools:node="remove"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission
android:name="android.permission.ACTIVITY_RECOGNITION"
tools:node="remove" />
<uses-permission
android:name="android.permission.READ_PHONE_STATE"
tools:node="remove" />
<!-- <uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove"/>-->
<!-- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" tools:node="remove"/>-->
<uses-permission
android:name="android.permission.BLUETOOTH_CONNECT"
tools:node="remove" />
<!-- <uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:node="remove"/>-->
<uses-permission
android:name="android.permission.BROADCAST_STICKY"
tools:node="remove" />
<uses-permission
android:name="com.google.android.gms.permission.AD_ID"
tools:node="remove" />
<!-- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" tools:node="remove"/>-->
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE"
tools:node="remove" />
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE"
tools:node="remove" />
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL"
tools:node="remove" />
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION"
tools:node="remove" />
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"
tools:node="remove" />
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE"
tools:node="remove" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera.autofocus"/>
<uses-feature android:name="android.hardware.camera" android:required="true"/>
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
<uses-feature
android:name="android.hardware.location.network"
android:required="false" />
<uses-feature
android:name="android.hardware.location.gps"
android:required="false" />
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA" />
<!-- Wifi Permissions-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>-->
<!-- Detect Reboot Permission -->
<!-- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>-->
<!-- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>-->
<!-- Tell Google Play Store that your app uses Bluetooth LE
Set android:required="true" if bluetooth is necessary -->
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="false" />
<!-- New Bluetooth permissions in Android 12
https://developer.android.com/about/versions/12/features/bluetooth-permissions -->
<uses-permission
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- legacy for Android 11 or lower -->
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!-- legacy for Android 9 or lower -->
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"
android:maxSdkVersion="28" />
<queries>
<intent>
<action android:name="android.speech.RecognitionService" />
@ -59,26 +120,28 @@
</queries>
<application
android:name=".Application"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true"
android:showOnLockScreen="true"
android:screenOrientation="sensorPortrait"
android:allowBackup="false"
android:extractNativeLibs="true"
tools:replace="android:extractNativeLibs"
android:label="Dr. Alhabib">
android:icon="@mipmap/ic_launcher"
android:label="Dr. Alhabib"
android:screenOrientation="sensorPortrait"
android:showOnLockScreen="true"
android:usesCleartextTraffic="true"
tools:replace="android:extractNativeLibs">
<meta-data android:name="push_kit_auto_init_enabled" android:value="true" />
<meta-data
android:name="push_kit_auto_init_enabled"
android:value="true" />
<activity
android:name=".MainActivity"
android:name="com.cloud.diplomaticquarterapp.MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:exported="true"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:showOnLockScreen="true"
android:theme="@style/LaunchTheme"
android:exported="true"
tools:node="merge"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="adjustResize"
tools:node="merge">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
@ -105,39 +168,58 @@
</intent-filter>
</activity>
<!-- <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver" android:exported="true">-->
<!-- <intent-filter>-->
<!-- <action android:name="android.intent.action.BOOT_COMPLETED"/>-->
<!-- <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>-->
<!-- </intent-filter>-->
<!-- </receiver>-->
<!-- <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver" android:exported="true">-->
<!-- <intent-filter>-->
<!-- <action android:name="android.intent.action.BOOT_COMPLETED"/>-->
<!-- <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>-->
<!-- </intent-filter>-->
<!-- </receiver>-->
<service android:name="com.cloud.diplomaticquarterapp.smart_ring_2301.BleService" />
<!-- Geofencing -->
<service android:name=".geofence.intent_receivers.GeofenceTransitionsJobIntentService" android:exported="true" android:permission="android.permission.BIND_JOB_SERVICE" />
<receiver android:name=".geofence.intent_receivers.GeofenceBroadcastReceiver" android:enabled="true" android:exported="false" />
<receiver android:name=".geofence.intent_receivers.GeofencingRebootBroadcastReceiver" android:enabled="true" android:exported="false">
<service
android:name=".geofence.intent_receivers.GeofenceTransitionsJobIntentService"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />
<receiver
android:name=".geofence.intent_receivers.GeofenceBroadcastReceiver"
android:enabled="true"
android:exported="false" />
<receiver
android:name=".geofence.intent_receivers.GeofencingRebootBroadcastReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
<receiver android:name=".geofence.intent_receivers.LocationProviderChangeReceiver" android:exported="false">
<receiver
android:name=".geofence.intent_receivers.LocationProviderChangeReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED"/>
<action android:name="android.location.PROVIDERS_CHANGED" />
</intent-filter>
</receiver>
<service android:name=".geofence.intent_receivers.ReregisterGeofenceJobService" android:exported="true" android:permission="android.permission.BIND_JOB_SERVICE" />
<service
android:name=".geofence.intent_receivers.ReregisterGeofenceJobService"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />
<!-- Geofencing -->
<!--
Huawei Push Notifications
Set push kit auto enable to true (for obtaining the token on initialize)
-->
<!-- <meta-data-->
<!-- android:name="push_kit_auto_init_enabled"-->
<!-- android:value="true" />-->
<!-- <meta-data-->
<!-- android:name="push_kit_auto_init_enabled"-->
<!-- android:value="true" />-->
<!-- These receivers are for sending scheduled local notifications -->
<receiver android:name="com.huawei.hms.flutter.push.receiver.local.HmsLocalNotificationBootEventReceiver" android:exported="false">
<receiver
android:name="com.huawei.hms.flutter.push.receiver.local.HmsLocalNotificationBootEventReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
@ -156,8 +238,9 @@
</receiver>
<!-- Huawei Push Notifications -->
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8"/>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8" />
<!-- Don't delete the meta-data below.
@ -168,11 +251,10 @@
</application>
<!-- <uses-permission android:name="android.permission.INTERNET" />-->
<!-- <uses-permission android:name="android.permission.USE_FINGERPRINT" />-->
<!-- <uses-permission android:name="android.permission.READ_CALENDAR" />-->
<!-- <uses-permission android:name="android.permission.WRITE_CALENDAR" />-->
<!-- <uses-permission android:name="android.permission.INTERNET" />-->
<!-- <uses-permission android:name="android.permission.USE_FINGERPRINT" />-->
<!-- <uses-permission android:name="android.permission.READ_CALENDAR" />-->
<!-- <uses-permission android:name="android.permission.WRITE_CALENDAR" />-->
</manifest>

@ -1,29 +1,33 @@
package com.ejada.hmg
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.ContentResolver
import android.media.AudioAttributes
import android.net.Uri
import android.os.Bundle
package com.cloud.diplomaticquarterapp
import android.util.Log
import android.os.Build
import android.view.WindowManager
import androidx.annotation.NonNull;
import com.cloud.diplomaticquarterapp.check_me_pro.ble.manager.BleScanManager
import com.ejada.hmg.utils.*
import com.ejada.hmg.*
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
import com.cloud.diplomaticquarterapp.ble.BleBridge
import com.cloud.diplomaticquarterapp.smart_ring_2301.BleManager
class MainActivity: FlutterFragmentActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
@Suppress("DEPRECATION")
class MainActivity : FlutterFragmentActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
// Create Flutter Platform Bridge
this.window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON)
PlatformBridge(flutterEngine, this).create()
OpenTokPlatformBridge(flutterEngine, this).create()
BleManager.init(this)
BleBridge(flutterEngine, this).createBleBridge(BleScanManager()) { name, bluetoothDevice ->
// Handle the scan result here
Log.d("MainActivity", "Received scan result: $name, $bluetoothDevice")
}
}
// 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()
@ -43,9 +47,12 @@ class MainActivity: FlutterFragmentActivity() {
// val time = timeToMillis("04:00:00", "HH:mm:ss")
}
}
// override fun onBleStateChanged(model: Int, state: Int) {
// println("onBleStateChanged")
// println("model $model, state: $state")
//
// }
override fun onResume() {
super.onResume()
}
}

@ -0,0 +1,17 @@
package com.cloud.diplomaticquarterapp.ble;
public class BPModelMeasuring {
public int pressure;
public int pr;
public boolean deflate;
public boolean pulse;
public BPModelMeasuring(int pressure, int pr, boolean deflate, boolean pulse) {
this.pressure = pressure;
this.pr = pr;
this.deflate = deflate;
this.pulse = pulse;
}
}

@ -0,0 +1,23 @@
package com.cloud.diplomaticquarterapp.ble;
public class BPModelResult {
public boolean deflate;
public int dia;
public int mean;
public int pr;
public int pressure;
public int result;
public int sys;
public BPModelResult(boolean deflate, int dia, int mean, int pr, int pressure, int result, int sys) {
this.deflate = deflate;
this.dia = dia;
this.mean = mean;
this.pr = pr;
this.pressure = pressure;
this.result = result;
this.sys = sys;
}
}

@ -0,0 +1,22 @@
package com.cloud.diplomaticquarterapp.ble;
public class OxymeterModel {
public int spo2;
public int pr;
public float pi;
public boolean isProbeOff;
public boolean isPulseSearching;
public boolean isCheckProbe;
public int battery;
public OxymeterModel(int spo2, int pr, float pi, boolean isProbeOff, boolean isPulseSearching, boolean isCheckProbe, int battery) {
this.spo2 = spo2;
this.pr = pr;
this.pi = pi;
this.isProbeOff = isProbeOff;
this.isPulseSearching = isPulseSearching;
this.isCheckProbe = isCheckProbe;
this.battery = battery;
}
}

@ -0,0 +1,12 @@
package com.cloud.diplomaticquarterapp.ble.utils;
public class AlgorithmUtil {
public static native double[] filter(double var0, boolean var2);
public static native short[] shortFilter(short[] var0);
static {
System.loadLibrary("online-lib");
System.loadLibrary("offline-lib");
}
}

@ -0,0 +1,57 @@
package com.cloud.diplomaticquarterapp.ble.utils;
import java.util.Arrays;
public class EcgData {
private long startTime; // 时间戳s
private int duration;
private String fileName;
private byte[] data;
private short[] shortData;
public long getStartTime() {
return startTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public short[] getShortData() {
return shortData;
}
public void setShortData(short[] shortData) {
this.shortData = shortData;
}
@Override
public String toString() {
return "{" + "startTime:" + startTime + ", duration:" + duration + ", fileName:'" + fileName + '\'' + ", data:" + Arrays.toString(data) + ", shortData:" + Arrays.toString(shortData) + '}';
}
}

@ -0,0 +1,49 @@
//package com.cloud.diplomaticquarterapp.ble.utils;
//
////
//// Source code recreated from a .class file by IntelliJ IDEA
//// (powered by FernFlower decompiler)
////
//
//
//import doac.doba;
//import doac.dobn;
//import doac.docn;
//
//public class FilterUtil {
// public FilterUtil() {
// }
//
// public static short[] getEcgFileFilterData(int var0, byte[] var1) {
// if (var0 != 7 && var0 != 8) {
// if (var0 == 19) {
// return AlgorithmUtil.shortFilter((new doba(var1)).doan());
// }
//
// if (var0 == 52) {
// return AlgorithmUtil.shortFilter((new docn("", var1, "")).doah());
// }
//
// if (var0 != 77 && var0 != 127) {
// if (var0 == 32) {
// return AlgorithmUtil.shortFilter((new doba(var1)).doan());
// }
//
// if (var0 != 33 && var0 != 74 && var0 != 75) {
// switch (var0) {
// case 145:
// case 146:
// case 147:
// case 148:
// case 149:
// break;
// default:
// return new short[0];
// }
// }
// }
// }
//
// return AlgorithmUtil.shortFilter(DecompressUtil.er1Decompress((new dobn(var1)).doad()));
// }
//}

@ -0,0 +1,50 @@
package com.cloud.diplomaticquarterapp.ble.utils;
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
public class HexString {
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
private HexString() {
}
public static String bytesToHex(byte[] var0) {
char[] var1 = new char[var0.length * 2];
for(int var2 = 0; var2 < var0.length; ++var2) {
int var3 = var0[var2] & 255;
int var4 = var2 * 2;
char[] var5;
char[] var10001 = var5 = HEX_ARRAY;
int var10002 = var3;
var1[var4] = var5[var3 >>> 4];
var3 = var4 + 1;
var1[var3] = var10001[var10002 & 15];
}
return new String(var1);
}
public static byte[] hexToBytes(String var0) {
if (var0.length() % 2 == 1) {
throw new IllegalArgumentException("hexToBytes requires an even-length String parameter");
} else {
int var1;
byte[] var2 = new byte[(var1 = var0.length()) / 2];
for(int var3 = 0; var3 < var1; var3 += 2) {
int var4 = var3 / 2;
var2[var4] = (byte)((Character.digit(var0.charAt(var3), 16) << 4) + Character.digit(var0.charAt(var3 + 1), 16));
}
return var2;
}
}
public static String trimStr(String var0) {
return var0.trim();
}
}

@ -0,0 +1,7 @@
package com.cloud.diplomaticquarterapp.check_me_pro
import kotlinx.coroutines.channels.Channel
//object UiChannel {
// val progressChannel = Channel<Int>(Channel.CONFLATED)
//}

@ -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)

@ -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
)

@ -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
)

@ -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
)

@ -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=""
)

@ -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
)

@ -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<PedBean> {
override fun createFromParcel(parcel: Parcel): PedBean {
return PedBean(parcel)
}
override fun newArray(size: Int): Array<PedBean?> {
return arrayOfNulls(size)
}
}
}

@ -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
)

@ -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
)

@ -0,0 +1,19 @@
package com.cloud.diplomaticquarterapp.check_me_pro.bean
import com.google.gson.Gson
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
)
fun UserBean.toJson(): String {
return Gson().toJson(this)
}

@ -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;
}

@ -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<BpBean> = arrayListOf<BpBean>()
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)
}
}

@ -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)
}

@ -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)
}
}

@ -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<DlcBean> = arrayListOf<DlcBean>()
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)
}
}

@ -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<EcgBean> = arrayListOf<EcgBean>()
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)
}
}

@ -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
}
}

@ -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<GluBean> = arrayListOf<GluBean>()
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)
}
}

@ -0,0 +1,56 @@
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<OxyBean> = 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)
}
}

@ -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()
}
}
}

@ -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<PedBean> = arrayListOf<PedBean>()
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)
}
}

@ -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<SlpBean> = arrayListOf<SlpBean>()
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)
}
}

@ -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<TmpBean> = arrayListOf<TmpBean>()
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)
}
}

@ -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<UserBean> = 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)
}
}

@ -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");
}

@ -0,0 +1,64 @@
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
import com.cloud.diplomaticquarterapp.utils.Constant
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<ScanResult>) {}
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)
}
}

@ -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)
}
}

@ -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)
}
}

@ -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)
}
}

@ -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)
}
}

@ -0,0 +1,224 @@
package com.cloud.diplomaticquarterapp.check_me_pro.ble.worker
import android.bluetooth.BluetoothDevice
import android.content.Context
import android.os.Environment
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.format.UserInfo
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<String, Any>) -> Unit) {
private var pool: ByteArray? = null
private val deviceChannel = Channel<DeviceInfo>(Channel.CONFLATED)
private val fileChannel = Channel<Int>(Channel.CONFLATED)
private val connectChannel = Channel<String>(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<FileProgress>(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)} "
}
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 {
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.buf.toString());
sendCmd(pkg.buf)
return fileChannel.receive()
}
}
private fun getDeviceInfo() {
cmdState = 4
val pkg = GetDeviceInfoPkg()
sendCmd(pkg.buf)
}
fun disconnect() {
myBleDataManager?.disconnect()?.enqueue()
}
}

@ -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

@ -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

@ -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) {

@ -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"

@ -0,0 +1,106 @@
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.cloud.diplomaticquarterapp.smart_ring_2301.BleManager
import com.cloud.diplomaticquarterapp.smart_ring_2301.BleService
import com.cloud.diplomaticquarterapp.smart_ring_2301.Util.BleData
import com.cloud.diplomaticquarterapp.smart_ring_2301.Util.RxBus
import com.jstyle.blesdk2301.Util.BleSDK.DataParsingWithData
import com.jstyle.blesdk2301.callback.DataListener2301
import com.jstyle.blesdk2301.constant.DeviceKey
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import javax.annotation.Nullable
open class BaseActivity : AppCompatActivity(), DataListener2301 {
private var subscription: Disposable? = null
public override fun onCreate(@Nullable savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// subscribeForSmartRingEvents()
}
protected open fun subscribeForSmartRingEvents() {
subscription = RxBus.instance.toObservable(BleData::class.java).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe { bleData ->
val action = bleData.action
if (action == BleService.ACTION_DATA_AVAILABLE) {
val value = bleData.value
if (value != null) {
DataParsingWithData(value, this@BaseActivity)
}
}
}
}
protected fun unSubscribe(disposable: Disposable?) {
if (disposable != null && !disposable.isDisposed) {
disposable.dispose()
}
}
protected override fun onDestroy() {
super.onDestroy()
unSubscribe(subscription)
}
protected fun Baseunsubscribe() {
unSubscribe(subscription)
}
protected fun Gateaus(count: Int) {}
override fun dataCallback(maps: Map<String?, Any?>?) {
Log.e("info", maps.toString())
}
override fun dataCallback(value: ByteArray?) {
}
/**
* 当蓝牙设备是连接的状态发送指令给设备
* When the Bluetooth device is connected, send instructions to the device
* @param value
*/
protected fun sendValue(value: ByteArray?) {
if (value == null) return
BleManager.instance?.writeValue(value)
}
protected fun showToast(text: String?) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
}
protected fun getEnd(maps: Map<String?, Any?>): Boolean {
return maps[DeviceKey.End] as Boolean
}
protected fun offerData(value: ByteArray?) {
BleManager.instance?.offerValue(value)
}
protected fun offerData() {
BleManager.instance?.writeValue()
}
companion object {
@JvmStatic
protected fun getDataType(maps: Map<String?, Any?>?): String? {
return if (null == maps) {
""
} else maps[DeviceKey.DataType] as String?
}
@JvmStatic
protected fun getData(maps: Map<String?, Any?>): Map<String, String>? {
return maps[DeviceKey.Data] as Map<String, String>?
}
}
}

@ -0,0 +1,235 @@
package com.cloud.diplomaticquarterapp.smart_ring_2301
import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.app.Service
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanResult
import android.bluetooth.le.ScanSettings
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Build
import android.os.IBinder
import android.text.TextUtils
import com.jstyle.blesdk2301.callback.BleConnectionListener
import com.jstyle.blesdk2301.callback.OnScanResults
import com.jstyle.blesdk2301.model.Device
import java.util.Locale
/**
* 蓝牙管理类 Bluetooth management class
*/
@SuppressLint("MissingPermission")
class BleManager private constructor(var context: Context) {
private var address: String? = null
private var bleService: BleService? = null
private val serviceConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceDisconnected(name: ComponentName) { // TODO Auto-generated method stub
bleService = null
}
override fun onServiceConnected(name: ComponentName, service: IBinder) {
bleService = (service as BleService.LocalBinder).service
if (!TextUtils.isEmpty(address)) {
bleService!!.initBluetoothDevice(address, context, NeedReconnect1, bleConnectionListener1)
}
}
}
private var serviceIntent: Intent? = null
var bluetoothAdapter: BluetoothAdapter?
val isBleEnable: Boolean
get() = bluetoothAdapter!!.enable()
/**
* 连接蓝牙设备
* Connect Bluetooth device
*
* @param address
*/
protected var NeedReconnect1 = true
protected var bleConnectionListener1: BleConnectionListener? = null
fun connectDevice(address: String?, NeedReconnect: Boolean, bleConnectionListener: BleConnectionListener?) {
NeedReconnect1 = NeedReconnect
bleConnectionListener1 = bleConnectionListener
if (!bluetoothAdapter!!.isEnabled || TextUtils.isEmpty(address) || isConnected) return
if (bleService == null) {
this.address = address
} else {
bleService!!.initBluetoothDevice(address, context, NeedReconnect, bleConnectionListener)
}
}
/**
* 关闭蓝牙服务通知
* Turn off Bluetooth service notification
*/
fun enableNotifaction() {
if (bleService == null) return
bleService!!.setCharacteristicNotification(true)
}
/**
* 写入指令到蓝牙设备
* Write command to Bluetooth device
*/
fun writeValue(value: ByteArray?) {
if (bleService == null || instance == null) return
bleService!!.writeValue(value)
}
/**
* 多条指令同时添加后发送到设备
* Multiple instructions are added at the same time and sent to the device
*
* @param data
*/
fun offerValue(data: ByteArray?) {
if (bleService == null) return
if (data != null) {
bleService!!.offerValue(data)
}
}
/**
* 写入指令到蓝牙设备
* Write command to Bluetooth device
*/
fun writeValue() {
if (bleService == null) return
bleService!!.nextQueue()
}
/**
* 断开设备 Disconnect the device
*/
fun disconnectDevice() {
if (bleService == null) return
bleService!!.disconnect()
}
val isConnected: Boolean
/**
* 查询设备是否已经连接
* Query whether the device is connected
*
* @return
*/
get() = if (bleService == null) false else bleService!!.isConnected
/**
* 取消扫描设备
* Cancel scanning device
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun StopDeviceScan() {
isinScan = false
if (null != bluetoothAdapter && null != bluetoothAdapter!!.bluetoothLeScanner) {
bluetoothAdapter!!.bluetoothLeScanner.stopScan(scanCallback)
}
}
/**
* 扫描蓝牙设备,用于开始绑定设备
* Scan Bluetooth device to start binding device
*/
private var DevicesName: Array<String>? = null
private var onScanResult: OnScanResults? = null
private var isinScan = false
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun DeviceScanResults(Devicesname: Array<String>, onScanResults: OnScanResults) {
if (!isinScan && instance!!.isBleEnable) { //如果蓝牙开关是开启的就进行扫描
isinScan = true
DevicesName = Devicesname
onScanResult = onScanResults
//返回已配对设备
//获得已配对的远程蓝牙设备的集合
val devices = bluetoothAdapter!!.bondedDevices
if (devices.size > 0) {
for (bluetoothDevice in devices) {
if (Canctians(bluetoothDevice.name.lowercase(Locale.getDefault()))) {
val device = Device()
device.bluetoothDevice = bluetoothDevice
device.isIsconted = false
device.isPaired = true
device.isIsdfu = bluetoothDevice.name.lowercase(Locale.getDefault()).contains("dfu")
device.name = bluetoothDevice.name
device.mac = bluetoothDevice.address
onScanResult!!.Success(device)
}
}
}
bluetoothAdapter!!.bluetoothLeScanner.startScan(null, ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(), scanCallback)
}
}
private val scanCallback: ScanCallback = object : ScanCallback() {
override fun onScanResult(callbackType: Int, result: ScanResult) {
super.onScanResult(callbackType, result)
val deviceName = result.device.name
if (isinScan && !TextUtils.isEmpty(deviceName) && Canctians(deviceName.lowercase(Locale.getDefault()).trim { it <= ' ' })) {
val device = Device()
device.bluetoothDevice = result.device
device.isIsconted = false
device.isPaired = false
device.isIsdfu = deviceName.lowercase(Locale.getDefault()).contains("dfu")
device.name = result.device.name
device.mac = result.device.address
device.riss = result.rssi
onScanResult!!.Success(device)
}
}
override fun onBatchScanResults(results: List<ScanResult>) {
super.onBatchScanResults(results)
}
override fun onScanFailed(errorCode: Int) {
super.onScanFailed(errorCode)
onScanResult!!.Fail(errorCode)
}
}
init {
if (serviceIntent == null) {
serviceIntent = Intent(context, BleService::class.java)
context.bindService(serviceIntent!!, serviceConnection, Service.BIND_AUTO_CREATE)
}
val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
bluetoothAdapter = bluetoothManager.adapter
}
private fun Canctians(name: String): Boolean {
var catian = false
if (null == DevicesName || DevicesName!!.size == 0) {
return false
} else {
for (devicesname in DevicesName!!) {
if (name.lowercase(Locale.getDefault()).contains(devicesname.lowercase(Locale.getDefault()))) {
catian = true
break
}
}
}
return catian
}
companion object {
var instance: BleManager? = null
private set
fun init(context: Context) {
if (instance != null) {
return
}
synchronized(BleManager::class.java) {
if (instance == null) {
instance = BleManager(context)
}
}
}
}
}

@ -0,0 +1,11 @@
package com.cloud.diplomaticquarterapp.smart_ring_2301.Util
/**
* Created by Administrator on 2017/4/11.
*/
class BleData {
var value: ByteArray? = null
var action: String? = null
var data: String? = null
}

@ -0,0 +1,137 @@
package com.cloud.diplomaticquarterapp.smart_ring_2301.Util
import android.os.Handler
import android.os.Looper
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit
/**
* 计时器
*/
class CustomCountDownTimer(
//Millis since epoch when alarm should stop.
private var millisInFuture: Long, countDownInterval: Long,
tickListener: TimerTickListener
) {
//thread on which the callbacks will be called
private val mainThreadHandler = Handler(Looper.getMainLooper())
//listener interface which is to be implemented by the users of the count down timer
interface TimerTickListener {
/**
* Callback on each tick
*
* @param millisLeft time left in millisec for the timer to shutdown
*/
fun onTick(millisLeft: Long)
/**
* Callback to be invokded when timer's time finishes
*/
fun onFinish()
/**
* Callback to be invokded when timer is canceled
*/
fun onCancel()
}
/**
* Inner class which delegates the events to callbacks provided in the TimerTickListener
*/
private inner class TimerRunnable : Runnable {
override fun run() {
if (isCancelled) {
scheduler.shutdown()
mainThreadHandler.post { tickListener.onCancel() }
} else if (isPaused) {
} else {
stopTimeInFuture = stopTimeInFuture - countdownInterval
mainThreadHandler.post(object : Runnable {
val millisLeft = stopTimeInFuture
override fun run() {
if (millisLeft <= 0) {
tickListener.onFinish()
scheduler.shutdown()
} else {
tickListener.onTick(millisLeft)
}
}
})
}
}
}
//The interval in millis that the user receives callbacks
private val countdownInterval: Long
//the time at which timer is to stop
private var stopTimeInFuture: Long
//boolean representing if the timer was cancelled
var isCancelled = false
//boolean representing if the timer was paused
private var isPaused = false
//listener which listens to the timer events
private val tickListener: TimerTickListener
//scheduler which provides the thread to create timer
private val scheduler: ScheduledExecutorService
/**
* Constructor
*
* @param millisInFuture time in millisec for which timer is to run
* @param countDownInterval interval frequency in millisec at which the callback will be invoked
* @param tickListener implementation of TimerTickListener which provides callbacks code
*/
init {
stopTimeInFuture = millisInFuture
countdownInterval = countDownInterval
this.tickListener = tickListener
scheduler = Executors.newSingleThreadScheduledExecutor()
}
/**
* Start the countdown.
*/
@Synchronized
fun start() {
isCancelled = false
isPaused = false
scheduler.scheduleWithFixedDelay(
TimerRunnable(), countdownInterval, countdownInterval,
TimeUnit.MILLISECONDS
)
}
/**
* Cancels the countdown timer
*/
@Synchronized
fun cancel() {
isCancelled = true
}
@Synchronized
fun pause() {
isPaused = true
}
@Synchronized
fun resume() {
isPaused = false
}
fun extendTime(delta: Long) {
stopTimeInFuture = stopTimeInFuture + delta
millisInFuture = millisInFuture + delta
}
companion object {
const val TAG = "CustomCountDownTimer"
}
}

@ -0,0 +1,504 @@
package com.cloud.diplomaticquarterapp.smart_ring_2301.Util
import android.content.Context
import java.text.NumberFormat
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
/**
* Created by Administrator on 2017/3/24.
*/
object DateUtil {
const val oneDayMillis = 24 * 60 * 60 * 1000L
private const val oneMinMillis = 60 * 1000L
const val Default_FormatString = "yy.MM.dd"
const val SHOW_FormatString = "MM-dd,yyyy"
val format = SimpleDateFormat("yy.MM.dd HH:mm:ss")
var defaultFormat = SimpleDateFormat(Default_FormatString)
const val DATA_MONTH_FormatString = "yy.MM"
const val DATA_Year_FormatString = "yyyy.M" //数据年日期
const val last_month = -1
const val this_month = 0
const val next_month = 1
const val nextWeek = 326
const val lastWeek = 396
/**
* 明天的日期
*/
fun getTomorrowDateString(today: String?): String {
val c = Calendar.getInstance()
c.timeInMillis = getDateLong(today) + oneDayMillis
return getDefaultFormatTime(c.time)
}
fun getDateString(today: String?, days: Int): String {
val c = Calendar.getInstance()
c.timeInMillis = getDateLong(today) - oneDayMillis * days
return getDefaultFormatTime(c.time)
}
/**
* 昨天的日期
*/
@Synchronized
fun getYesterdayDateString(today: String?): String {
val c = Calendar.getInstance()
c.timeInMillis = getDateLong(today) - oneDayMillis
return getDefaultFormatTime(c.time)
}
/**
* 获取指定格式的日期字符串
*
* @param time
* @param formatString
* @return
*/
@Synchronized
fun getFormatTimeString(time: Long, formatString: String?): String {
val format = SimpleDateFormat(formatString)
return format.format(Date(time))
}
@Synchronized
fun getFormatTimeString(time: Long): String {
return format.format(Date(time))
}
@Synchronized
fun getEcgFormatTimeString(time: Long): String {
val simpleDateFormat = SimpleDateFormat("yyyy.MM.dd HH:mm:ss")
return simpleDateFormat.format(Date(time))
}
@Synchronized
fun getEcgFormatTodayString(time: Long): String {
val simpleDateFormat = SimpleDateFormat("yyyy.MM.dd")
return simpleDateFormat.format(Date(time))
}
/**
* 获取默认格式日期字符串
*
* @return
*/
@Synchronized
fun getDefaultFormatTime(date: Date): String {
return getFormatTimeString(date.time, Default_FormatString)
}
/**字符串代表日期的毫秒数
* @param date
* @return
*/
@Synchronized
fun getDateLong(date: String?): Long {
var time: Long = 0
try {
val dates = defaultFormat.parse(date)
time = dates.time
} catch (e: Exception) {
// TODO: handle exception
}
return time
}
@Synchronized
fun getGpsDateLong(date: String?): Long {
var time: Long = 0
try {
val dates = format.parse(date)
time = dates.time
} catch (e: Exception) {
// TODO: handle exception
}
return time
}
/**字符串转date
* @param dateString
* @return
*/
fun String2Date(dateString: String?, formatString: String?): Date? {
val format = SimpleDateFormat(formatString)
var date: Date? = null
try {
date = format.parse(dateString)
} catch (e: ParseException) {
e.printStackTrace()
}
return date
}
fun getMonthString(thisMonth: String?, monthType: Int): String {
val calendar = Calendar.getInstance()
if (monthType != this_month) calendar.time = String2Date(thisMonth, DATA_MONTH_FormatString)
calendar.add(Calendar.MONTH, monthType)
return getFormatTimeString(calendar.timeInMillis, DATA_MONTH_FormatString)
}
fun getTodayWeek(time: Long): Array<String?> {
val format = SimpleDateFormat(Default_FormatString)
val week = arrayOfNulls<String>(7)
val calendar = Calendar.getInstance()
if (time != 0L) {
calendar.timeInMillis = time
}
setToFirstDay(calendar)
for (i in 0..6) {
week[i] = format.format(calendar.time)
calendar.add(Calendar.DATE, 1)
}
return week
}
private fun setToFirstDay(calendar: Calendar) {
while (calendar[Calendar.DAY_OF_WEEK] != Calendar.MONDAY) {
calendar.add(Calendar.DATE, -1)
}
}
fun getWeekString(time: String?, type: Int): Array<String?> {
val format = SimpleDateFormat(Default_FormatString)
var date: Date? = null
try {
date = format.parse(time)
} catch (e: Exception) {
// TODO: handle exception
}
val nowL = if (type == lastWeek) date!!.time - oneDayMillis else date!!.time + oneDayMillis
return getTodayWeek(nowL)
}
/**时间段在一天中的时间节点一分钟一点)
* @param time
* @param defaultTime
* @return
*/
fun get1MIndex(time: String?, defaultTime: String?): Int {
val format = SimpleDateFormat("yy.MM.dd HH:mm:ss")
var count = 0
try {
val date = format.parse(time)
val dateBase = format.parse(defaultTime)
val min = date.time - dateBase.time
count = (min / oneMinMillis).toInt()
} catch (e: Exception) {
// TODO: handle exception
}
return count
}
fun get1SIndex(time: String?, defaultTime: String?): Int {
val format = SimpleDateFormat("yy.MM.dd HH:mm:ss")
var count = 0
try {
val date = format.parse(time)
val dateBase = format.parse(defaultTime)
val min = date.time - dateBase.time
count = (min / 1000L).toInt()
} catch (e: Exception) {
// TODO: handle exception
}
return count
}
fun get5MIndex(time: String?, defaultTime: String?): Int {
val format = SimpleDateFormat("yy.MM.dd HH:mm:ss")
var count = 0
try {
val date = format.parse(time)
val dateBase = format.parse(defaultTime)
val min = date.time - dateBase.time
count = (min / (oneMinMillis * 5)).toInt()
} catch (e: Exception) {
// TODO: handle exception
}
return count
}
fun getMIndex(time: String?, defaultTime: String?, countMIN: Int): Int {
val format = SimpleDateFormat("yy.MM.dd HH:mm:ss")
var count = 0
try {
val date = format.parse(time)
val dateBase = format.parse(defaultTime)
val min = date.time - dateBase.time
count = (min / (oneMinMillis * countMIN)).toInt()
} catch (e: Exception) {
// TODO: handle exception
}
return count
}
@Synchronized
fun getHistoryTime(time: Long): String {
val defaultTime = getDateLong("00.01.01")
return getFormatTimeString(time * 1000 * 5 + defaultTime)
}
private const val TAG = "DateUtil"
@Synchronized
fun getDefaultLongMi(defaultTime: String?): Long {
var date = Date()
// SimpleDateFormat format = new SimpleDateFormat("yy.MM.dd HH:mm:ss");
// Log.i(TAG, "getDefaultLongMi: "+defaultTime);
try {
date = format.parse(defaultTime)
} catch (e: Exception) {
// Log.i(TAG, "getDefaultLongMi: "+e.getMessage());
}
return date.time
}
fun getSleepTime(minute: Int): String {
val hour = minute / 60
val min = minute % 60
return String.format("%1$02dh%2$02dmin", hour, min)
}
fun getActivityShowTime(minute: Int): String {
val hour = minute / 60
val min = minute % 60
return String.format("%1$02d:%2$02d", hour, min)
}
fun getSportTime(seconds: Int): String {
var hour = 0
var min = seconds / 60
var second = seconds % 60
if (min >= 60) {
hour = min / 60
min = min % 60
second = seconds - hour * 3600 - min * 60
}
return String.format("%1$02d:%2$02d:%3$02d", hour, min, second)
}
fun getExerciseListTotalTime(seconds: Int): String {
var hour = 0
var min = seconds / 60
// int second=seconds%60;
if (min >= 60) {
hour = min / 60
min = min % 60
//second = seconds - hour * 3600 - min * 60;
}
return String.format("%1$02dh%2$02dmin", hour, min)
}
fun getSportAxieTime(seconds: Int): String {
var hour = 0
var min = seconds / 60
var second = seconds % 60
if (min >= 60) {
hour = min / 60
min = min % 60
second = seconds - hour * 3600 - min * 60
}
return if (hour == 0) String.format("%1$02d:%2$02d", min, second) else String.format("%1$02d:%2$02d:%3$02d", hour, min, second)
}
fun getPaceTime(seconds: Int): String {
val min = seconds / 60
val second = seconds % 60
// if(min>60){
// hour=min/60;
// min=min%60;
// second = seconds - hour * 3600 - min * 60;
// }
return String.format("%1$02d'%2$02d\"", min, second)
}
fun getActivityTime(seconds: Int): String {
var hour = 0
var min = seconds / 60
var second = seconds % 60
if (min > 60) {
hour = min / 60
min = min % 60
second = seconds - hour * 3600 - min * 60
}
return if (hour == 0) String.format("%1$02d:%2$02d", min, second) else String.format("%1$02d:%2$02d:%3$02d", hour, min, second)
}
fun getPointSleepTime(minute: Float): String {
val nf = NumberFormat.getInstance()
nf.minimumFractionDigits = 2
return nf.format((minute / 60f).toDouble()) + "h"
}
fun getSleepTimeFloat(minute: Int): Float {
val hour = minute / 60
val min = minute % 60
return hour + min / 60f
}
/**时间点换成时间段
* @param count
* @return
*/
fun getCountTime(count: Int, defaultTime: String?): String {
val format = SimpleDateFormat("yy.MM.dd HH:mm:ss")
// String base = "00:00:00";
var time: Long = 0
try {
time = format.parse(defaultTime).time + count * oneMinMillis
} catch (e: Exception) {
// TODO: handle exception
}
return format.format(Date(time))
}
fun getSleepCountTime(count: Int, defaultTime: String?): String {
val format = SimpleDateFormat("yy.MM.dd HH:mm:ss")
// String base = "00:00:00";
var time: Long = 0
try {
time = format.parse(defaultTime).time + 5 * count * oneMinMillis
} catch (e: Exception) {
// TODO: handle exception
}
return format.format(Date(time))
}
val thisMonth: Array<String?>
get() {
val format = SimpleDateFormat("yy.MM.dd")
// String[] month = new String[3];
val cal_1 = Calendar.getInstance() // 获取当前日期
val max = cal_1.getActualMaximum(Calendar.DAY_OF_MONTH)
val month = arrayOfNulls<String>(max)
for (i in 1 until max + 1) {
cal_1[Calendar.DAY_OF_MONTH] = i
month[i - 1] = format.format(cal_1.time)
}
return month
}
fun getNextMonth(date: String?): Array<String?> {
val format = SimpleDateFormat("yy.MM.dd")
var dates: Date? = Date()
try {
dates = format.parse(date)
} catch (e: Exception) {
// TODO: handle exception
}
val cal_1 = Calendar.getInstance() // 获取当前日期
cal_1.time = dates
var months = cal_1[Calendar.MONTH]
var year = cal_1[Calendar.YEAR]
if (months == Calendar.DECEMBER) {
year++
months = Calendar.JANUARY
} else {
months++
}
cal_1[Calendar.YEAR] = year
cal_1[Calendar.MONTH] = months
val max = cal_1.getActualMaximum(Calendar.DAY_OF_MONTH)
val month = arrayOfNulls<String>(max)
for (i in 1 until max + 1) {
cal_1[Calendar.DAY_OF_MONTH] = i
month[i - 1] = format.format(cal_1.time)
}
// cal_1.set(Calendar.DAY_OF_MONTH,
// cal_1.getActualMaximum(Calendar.DAY_OF_MONTH));// 设置为1号,当前日期既为本月第一天
// month[1] = format.format(cal_1.getTime());
// month[2]=cal_1.getActualMaximum(Calendar.DAY_OF_MONTH)+"";
return month
}
fun getMonth(year: Int, month: Int): Array<String?> {
val format = SimpleDateFormat("yy.MM.dd")
val cal_1 = Calendar.getInstance() // 获取当前日期
cal_1[Calendar.YEAR] = year
cal_1[Calendar.MONTH] = month
val max = cal_1.getActualMaximum(Calendar.DAY_OF_MONTH)
val months = arrayOfNulls<String>(max)
for (i in 1 until max + 1) {
cal_1[Calendar.DAY_OF_MONTH] = i
months[i - 1] = format.format(cal_1.time)
}
return months
}
fun getLastMonth(date: String?): Array<String?> {
val format = SimpleDateFormat("yy.MM.dd")
var dates: Date? = Date()
try {
dates = format.parse(date)
} catch (e: Exception) {
// TODO: handle exception
}
val cal_1 = Calendar.getInstance() // 获取当前日期
cal_1.time = dates
var months = cal_1[Calendar.MONTH]
var year = cal_1[Calendar.YEAR]
if (months == Calendar.JANUARY) {
year--
months = Calendar.DECEMBER
} else {
months--
}
cal_1[Calendar.YEAR] = year
cal_1[Calendar.MONTH] = months
val max = cal_1.getActualMaximum(Calendar.DAY_OF_MONTH)
val month = arrayOfNulls<String>(max)
for (i in 1 until max + 1) {
cal_1[Calendar.DAY_OF_MONTH] = i
month[i - 1] = format.format(cal_1.time)
}
// 设置为1号,当前日期既为本月第一天
// cal_1.set(Calendar.DAY_OF_MONTH,
// cal_1.getActualMaximum(Calendar.DAY_OF_MONTH));// 设置为1号,当前日期既为本月第一天
// month[1] = format.format(cal_1.getTime());
return month
}
fun beforeData(lastTime: String?, bleTime: String?): Boolean {
var isBefore = false
try {
val lastDate = format.parse(lastTime)
val bleDate = format.parse(bleTime)
isBefore = lastDate.before(bleDate)
} catch (e: ParseException) {
e.printStackTrace()
}
return isBefore
}
fun getCountTime(count: Int): String {
val format = SimpleDateFormat("HH:mm")
val base = "12:00"
var time: Long = 0
try {
time = format.parse(base).time + count * 5 * 60 * 1000L
} catch (e: Exception) {
// TODO: handle exception
}
return format.format(Date(time))
}
fun getShowDate(context: Context, monthString: String?): String {
val locale = context.resources.configuration.locale
val language = locale.language
val time = getDateLong(monthString)
var format = ""
// if (language.equals("zh")) {
format = "yyyy-MM"
// } else {
// format = "MM-yyyy";
// }
return getFormatTimeString(time, format)
}
private val timestamp: String
private get() = (System.currentTimeMillis() / 1000).toString() + ""
}

@ -0,0 +1,203 @@
package com.cloud.diplomaticquarterapp.smart_ring_2301.Util
import android.app.Activity
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PorterDuff
import android.util.AttributeSet
import android.util.DisplayMetrics
import android.util.Log
import android.view.SurfaceHolder
import android.view.SurfaceView
/**
* 自定义心电图
*
* @author manhongjie
*/
// public class EcgGraphicView<AttributeSet> extends View {
class EcgGraphicView(context: Context, attrs: AttributeSet?) : SurfaceView(context, attrs), SurfaceHolder.Callback, Runnable {
private val mSurfaceHolder: SurfaceHolder
private val mPaint: Paint
private val blackPaint: Paint? = null
private val wangge_Paint: Paint? = null
private val pixPaint: Paint? = null
private var mPath = Path()
// 屏幕的长<E79A84>?
private var SCREEN_WIDTH = 480f
//
private val POINT_LEN = 3000
private val rulerStartX = 0
// public float[] x = new float[POINT_LEN];
// public float[] y = new float[POINT_LEN];
// 数组中有3000个点
var x = FloatArray(POINT_LEN)
var y = FloatArray(POINT_LEN)
var scale = 0f
var x0 = 240f
var y0 = 192f
private val context: Context
var distanceY = 0f
private var isDrawing = false
private var mCanvas: Canvas? = null
// @Override
// public void onDraw(Canvas canvas) {
//
// float width = SCREEN_WIDTH;
// scale = 1;
//
// // String ruleStr = new String(scale * 10 + "mm/100mv");
// // 移动后的坐标
// makeFollowPathOne();
//
// // rulerStartX = SCREEN_WIDTH - 60;
// // 每列的间隔是32
// // int colomn = (int) (width / 32);
//
// // 画网格线行和<E8A18C>?
//
// // for (int i = 0; i <= 13; i++) {
// // canvas.drawLine(0, i * 32, width, i * 32, wangge_Paint);
// // }
// // for (int i = 0; i <= colomn; i++) {
// // canvas.drawLine(i * 32, 0, i * 32, 12 * 32, wangge_Paint);
// // }
//
// // 画标<E794BB>?
//
// // canvas.drawLine(rulerStartX + 0, 192, rulerStartX + 8, 192,
// // pixPaint);
// // canvas.drawLine(rulerStartX + 24, 192, rulerStartX + 32, 192,
// // pixPaint);
// // canvas.drawLine(rulerStartX + 8, 128, rulerStartX + 24, 128,
// // pixPaint);
// // canvas.drawLine(rulerStartX + 8, 128, rulerStartX + 8, 192,
// // pixPaint);
// // canvas.drawLine(rulerStartX + 24, 128, rulerStartX + 24, 192,
// // pixPaint);
//
// // 文本<E69687>?25mm/s 10.0mm/100mv
// // canvas.drawText(ruleStr, rulerStartX - 120, 40, pixPaint);
// // canvas.drawText("25mm/s", rulerStartX - 200, 40, pixPaint);
//
// canvas.drawPath(mPath, mPaint);
// }
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
// TODO Auto-generated method stub
if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
SCREEN_WIDTH = MeasureSpec.getSize(widthMeasureSpec).toFloat()
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
//
fun makeFollowPathOne(canvas: Canvas) {
val height = height.toFloat()
val size = ecgValues.size
if (size == 0) return
mPath.reset()
val width = SCREEN_WIDTH / maxSize
val heightI = height / 16000
mPath.moveTo(0f, (8000 - ecgValues[0]) * heightI)
for (i in 1 until size - 1) {
canvas.drawPoint(i * width, (8000 - ecgValues[i]) * heightI, mPaint)
// mPath.lineTo(i * width, (8000 - ecgValues.get(i)) * heightI);
}
}
var ecgValues: MutableList<Int> = ArrayList()
var maxSize = 1516f
fun setValue(value: Int) {
if (ecgValues.size > maxSize) ecgValues.removeAt(0)
ecgValues.add(value)
}
fun clearData() {
ecgValues.clear()
}
fun setYDistance(distance: Float) {
distanceY = distance
}
override fun surfaceCreated(holder: SurfaceHolder) {
isDrawing = true
Thread(this).start()
}
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {}
override fun surfaceDestroyed(holder: SurfaceHolder) {
isDrawing = false
}
override fun run() {
while (isDrawing) {
drawing()
}
}
init {
// TODO Auto-generated constructor stub
// 分辨率矩<E78E87>?
val dm = DisplayMetrics()
// 取得窗口属<E58FA3>??
if (context is Activity) {
context.windowManager.defaultDisplay.getMetrics(dm)
SCREEN_WIDTH = dm.widthPixels.toFloat()
Log.d("EcgGraphicView", "width: $SCREEN_WIDTH")
}
mPath = Path()
// 画心电图的画<E79A84>?
mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
mPaint.style = Paint.Style.STROKE
mPaint.strokeWidth = ScreenUtils.Companion.dip2px(context, 1f).toFloat()
mPaint.textSize = 2f
mPaint.color = Color.WHITE
this.context = context
// blackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// blackPaint.setStyle(Paint.Style.STROKE);
// blackPaint.setStrokeWidth(2);
// blackPaint.setTextSize(2);
// blackPaint.setColor(Color.RED);
// 网格线画<E7BABF>?
// wangge_Paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// wangge_Paint.setStyle(Paint.Style.STROKE);
// wangge_Paint.setStrokeWidth(1.0f);
// wangge_Paint.setTextSize(0.5f);
// wangge_Paint.setColor(Color.parseColor("#000000"));
// pixPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// pixPaint.setStyle(Paint.Style.FILL);
// pixPaint.setStrokeWidth(2.0f);
// pixPaint.setTextSize(20.0f);
// pixPaint.setColor(Color.RED);
mSurfaceHolder = holder
mSurfaceHolder.addCallback(this)
}
private fun drawing() {
try {
mCanvas = mSurfaceHolder.lockCanvas()
if (mCanvas == null) return
mCanvas!!.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
makeFollowPathOne(mCanvas!!)
// mCanvas.drawPath(mPath, mPaint);
} finally {
if (mCanvas != null) {
mSurfaceHolder.unlockCanvasAndPost(mCanvas)
}
}
}
companion object {
private const val TAG = "EcgGraphicView"
}
}

@ -0,0 +1,248 @@
package com.cloud.diplomaticquarterapp.smart_ring_2301.Util
import android.annotation.SuppressLint
import android.bluetooth.BluetoothDevice
import android.content.ContentResolver
import android.content.ContentUris
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import android.text.TextUtils
import android.util.Log
import java.io.UnsupportedEncodingException
/**
* Created by Administrator on 2017/4/6.
*/
object ResolveData {
private const val TAG = "ResolveData"
private const val SHORTENED_LOCAL_NAME = 0x08
private const val COMPLETE_LOCAL_NAME = 0x09
private const val oneMinMillis = 60 * 1000L
var startString = " 12:00:00"
fun getBcd(value: String): Int {
return value.toInt(16)
}
fun decodeDeviceName(data: ByteArray): String? {
var name: String? = null
var fieldLength: Int
var fieldName: Int
val packetLength = data.size
var index = 0
while (index < packetLength) {
fieldLength = data[index].toInt()
if (fieldLength <= 0) break
fieldName = data[++index].toInt()
if (fieldName == COMPLETE_LOCAL_NAME
|| fieldName == SHORTENED_LOCAL_NAME
) {
name = decodeLocalName(data, index + 1, fieldLength - 1)
break
}
index += fieldLength - 1
index++
}
return name
}
@SuppressLint("MissingPermission")
@JvmStatic
fun decodeDeviceName(bluetoothDevice: BluetoothDevice, data: ByteArray): String? {
var name = bluetoothDevice.name
if (!TextUtils.isEmpty(name)) return name
var fieldLength: Int
var fieldName: Int
val packetLength = data.size
var index = 0
while (index < packetLength) {
fieldLength = data[index].toInt()
if (fieldLength <= 0) break
fieldName = data[++index].toInt()
if (fieldName == COMPLETE_LOCAL_NAME
|| fieldName == SHORTENED_LOCAL_NAME
) {
name = decodeLocalName(data, index + 1, fieldLength - 1)
break
}
index += fieldLength - 1
index++
}
return name
}
/**
* Decodes the local name
*/
fun decodeLocalName(
data: ByteArray?, start: Int,
length: Int
): String? {
return try {
kotlin.String()
} catch (e: UnsupportedEncodingException) {
Log.e(
"scan", "Unable to convert the complete local name to UTF-8",
e
)
null
} catch (e: IndexOutOfBoundsException) {
Log.e("scan", "Error when reading complete local name", e)
null
}
}
/**
* 转十六进制字符串
*
* @param data
* @return
*/
@JvmStatic
fun byte2Hex(data: ByteArray?): String {
if (data != null && data.size > 0) {
val sb = StringBuilder(data.size)
for (tmp in data) {
sb.append(String.format("%02X ", tmp))
}
return sb.toString()
}
return "no data"
}
fun getRealFilePath(context: Context, uri: Uri?): String? {
if (null == uri) return null
val scheme = uri.scheme
var data: String? = null
if (scheme == null) data = uri.path else if (ContentResolver.SCHEME_FILE == scheme) {
data = uri.path
} else if (ContentResolver.SCHEME_CONTENT == scheme) {
val cursor = context.contentResolver.query(uri, arrayOf(MediaStore.Images.ImageColumns.DATA), null, null, null)
if (null != cursor) {
if (cursor.moveToFirst()) {
val index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
if (index > -1) {
data = cursor.getString(index)
}
}
cursor.close()
}
}
return data
}
/**
* 专为Android4.4设计的从Uri获取文件绝对路径
*/
fun getPath(context: Context, uri: Uri): String? {
// DocumentProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val type = split[0]
if ("primary".equals(type, ignoreCase = true)) {
return Environment.getExternalStorageDirectory().toString() + "/" + split[1]
}
// TODO handle non-primary volumes
} else if (isDownloadsDocument(uri)) {
val id = DocumentsContract.getDocumentId(uri)
val contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id)
)
return getDataColumn(context, contentUri, null, null)
} else if (isMediaDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val type = split[0]
var contentUri: Uri? = null
if ("image" == type) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
} else if ("video" == type) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
} else if ("audio" == type) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
}
val selection = "_id=?"
val selectionArgs = arrayOf(split[1])
return getDataColumn(context, contentUri, selection, selectionArgs)
}
} else if ("content".equals(uri.scheme, ignoreCase = true)) {
return getDataColumn(context, uri, null, null)
} else if ("file".equals(uri.scheme, ignoreCase = true)) {
return uri.path
}
return null
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context
* The context.
* @param uri
* The Uri to query.
* @param selection
* (Optional) Filter used in the query.
* @param selectionArgs
* (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
fun getDataColumn(
context: Context, uri: Uri?, selection: String?,
selectionArgs: Array<String>?
): String? {
var cursor: Cursor? = null
val column = "_data"
val projection = arrayOf(column)
try {
cursor = context.contentResolver.query(
uri!!, projection, selection, selectionArgs,
null
)
if (cursor != null && cursor.moveToFirst()) {
val column_index = cursor.getColumnIndexOrThrow(column)
return cursor.getString(column_index)
}
} finally {
cursor?.close()
}
return null
}
/**
* @param uri
* The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
fun isExternalStorageDocument(uri: Uri): Boolean {
return "com.android.externalstorage.documents" == uri.authority
}
/**
* @param uri
* The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
fun isDownloadsDocument(uri: Uri): Boolean {
return "com.android.providers.downloads.documents" == uri.authority
}
/**
* @param uri
* The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
fun isMediaDocument(uri: Uri): Boolean {
return "com.android.providers.media.documents" == uri.authority
}
}

@ -0,0 +1,34 @@
package com.cloud.diplomaticquarterapp.smart_ring_2301.Util
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.processors.FlowableProcessor
import io.reactivex.rxjava3.processors.PublishProcessor
import io.reactivex.rxjava3.subjects.PublishSubject
import io.reactivex.rxjava3.subjects.Subject
/**
* Created by zhuge on 2017/1/19 0019.
*/
class RxBus private constructor() {
private val bus: Subject<Any>
private val mBus: FlowableProcessor<Any>
init {
mBus = PublishProcessor.create<Any>().toSerialized()
bus = PublishSubject.create<Any>().toSerialized()
}
fun post(`object`: Any) {
bus.onNext(`object`)
}
fun <T : Any> toObservable(eventType: Class<T>): Observable<T> {
return bus.ofType(eventType)
}
companion object {
val instance = RxBus()
}
}

@ -0,0 +1,17 @@
package com.cloud.diplomaticquarterapp.smart_ring_2301.Util
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.ObservableTransformer
import io.reactivex.rxjava3.schedulers.Schedulers
/**
* Created by Administrator on 2017/4/26.
*/
object SchedulersTransformer {
private const val TAG = "SchedulersTransformer"
fun <T : Any> io2MainObservable(): ObservableTransformer<T, T> {
return ObservableTransformer { upstream -> upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) }
}
}

@ -0,0 +1,120 @@
package com.cloud.diplomaticquarterapp.smart_ring_2301.Util
import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Paint
import android.util.DisplayMetrics
import android.view.WindowManager
/**
* 获得屏幕相关的辅助类
*
*
*
*/
class ScreenUtils private constructor() {
init {
/* cannot be instantiated */
throw UnsupportedOperationException("cannot be instantiated")
}
companion object {
/**
* 获得屏幕高度
*
* @param context
* @return
*/
fun getScreenWidth(context: Context): Int {
val wm = context
.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val outMetrics = DisplayMetrics()
wm.defaultDisplay.getMetrics(outMetrics)
return outMetrics.widthPixels
}
/**
* 获得屏幕宽度
*
* @param context
* @return
*/
fun getScreenHeight(context: Context): Int {
val wm = context
.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val outMetrics = DisplayMetrics()
wm.defaultDisplay.getMetrics(outMetrics)
return outMetrics.heightPixels
}
/**
* 获得状态栏的高度
*
* @param context
* @return
*/
fun getStatusHeight(context: Context): Int {
var statusHeight = -1
try {
val clazz = Class.forName("com.android.internal.R\$dimen")
val `object` = clazz.newInstance()
val height = clazz.getField("status_bar_height")[`object`].toString().toInt()
statusHeight = context.resources.getDimensionPixelSize(height)
} catch (e: Exception) {
e.printStackTrace()
}
return statusHeight
}
/**
* 获取当前屏幕截图包含状态栏
*
* @param activity
* @return
*/
fun snapShotWithStatusBar(activity: Activity): Bitmap? {
val view = activity.window.decorView
view.isDrawingCacheEnabled = true
view.buildDrawingCache()
val bmp = view.drawingCache
val width = getScreenWidth(activity)
val height = getScreenHeight(activity)
var bp: Bitmap? = null
bp = Bitmap.createBitmap(bmp, 0, 0, width, height)
view.destroyDrawingCache()
return bp
}
/**
* 获取当前屏幕截图不包含状态栏
*
* @param activity
* @return
*/
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
fun dip2px(context: Context, dpValue: Float): Int {
val scale = context.resources.displayMetrics.density
return (dpValue * scale + 0.5f).toInt()
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
fun px2dip(context: Context, pxValue: Float): Int {
val scale = context.resources.displayMetrics.density
return (pxValue / scale + 0.5f).toInt()
}
fun sp2px(context: Context, spValue: Float): Int {
val scale = context.resources.displayMetrics.density
return (scale * spValue).toInt()
}
fun getFontHeight(paint: Paint): Float {
val fm = paint.fontMetrics
return fm.descent - fm.ascent
}
}
}

@ -0,0 +1,93 @@
package com.cloud.diplomaticquarterapp.smart_ring_2301.Util
import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
object SharedPreferenceUtils {
const val KEY_REMIND_PSD = "REMIND_PSD"
const val KEY_account_type = "KEY_account_type"
const val KEY_countryCode = "KEY_countryCode"
const val KEY_TimeZone = "KEY_TimeZone"
const val KEY_DFU_ADDRESS = "KEY_DFU_ADDRESS"
const val KEY_Exercise_Mode = "KEY_Exercise_Mode"
const val KEY_Enable_ActivityClock = "KEY_Enable_ActivityClock"
const val KEY_UNIT_WEIGHT = "KEY_UNIT_WEIGHT"
const val KEY_UNIT_HEIGHT = "KEY_UNIT_HEIGHT"
const val KEY_RES_FILEPATH = "KEY_RES_FILEPATH"
const val KEY_Is_First = "KEY_Is_First"
const val KEY_From_Login = "KEY_From_Login"
const val KEY_PHONE = "PHONE"
const val KEY_UID = "uid"
const val KEY_PSD = "PSD"
const val KEY_ADDRESS = "ADDRESS"
const val KEY_Language = "Language"
const val KEY_LOGIN = "lOGIN"
const val KEY_NICKNAME = "nickname"
private const val spName = "jstyle_sleep"
const val KEY_AUTH_USERID = "KEY_AUTH_USERID"
const val KEY_highHeart = "highHeart"
const val KEY_highBrEATH = "highBrEATH"
const val KEY_lowHeart = "lowHeart"
const val KEY_lowBreath = "lowBreath"
const val KEY_deviceName = "deviceName"
const val KEY_PLAN_ON = "PLAN_ON"
const val KEY_PLAN_first = "PLAN_first"
const val KEY_Sleep_goal = "KEY_Sleep_goal"
const val KEY_Step_goal = "KEY_Step_goal"
const val KEY_deviceType = "KEY_deviceType"
var sharedPreferences: SharedPreferences? = null
private set
const val DefaultCountryCode = "0086-"
fun init(context: Context) {
sharedPreferences = context.getSharedPreferences(spName, Activity.MODE_PRIVATE)
}
fun setSpBoolean(name: String?, bool: Boolean) {
sharedPreferences!!.edit().putBoolean(name, bool).commit()
}
fun getSpBoolean(name: String?): Boolean {
return sharedPreferences!!.getBoolean(name, false)
}
fun getBoolean(name: String?, defaultValue: Boolean): Boolean {
return sharedPreferences!!.getBoolean(name, defaultValue)
}
fun setSpString(name: String?, value: String?) {
sharedPreferences!!.edit().putString(name, value).commit()
}
fun getSpString(name: String?): String? {
return getString(name, null)
}
fun getString(name: String?, defaultValue: String?): String? {
return sharedPreferences!!.getString(name, defaultValue)
}
fun setSpInteger(name: String?, value: Int) {
sharedPreferences!!.edit().putInt(name, value).commit()
}
fun getInteger(name: String?, defaultValue: Int): Int {
return sharedPreferences!!.getInt(name, defaultValue)
}
fun getSpInteger(name: String?): Int {
return getInteger(name, -1)
}
fun setSpFloat(name: String?, value: Float) {
sharedPreferences!!.edit().putFloat(name, value).commit()
}
fun getSpFloat(name: String?): Float {
return getFloat(name, 0.0f)
}
fun getFloat(name: String?, defaultValue: Float): Float {
return sharedPreferences!!.getFloat(name, defaultValue)
}
}

@ -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()
}

@ -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;
}
}

@ -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() + "/";
}
}
}

@ -1,7 +1,6 @@
package com.ejada.hmg.utils
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.Result
class FlutterText{

@ -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<String, Any?>{
fun defaultHTTPParams(context: Context): Map<String, Any?> {
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 <T>scheduleJob(context: Context, pendingIntentClassType:Class<T>, jobId:Int, intervalDuration:String, deadlineMillis:Long = (30 * 1000)) { // default deadline: 30 Seconds
@SuppressLint("MissingPermission")
fun <T> scheduleJob(context: Context, pendingIntentClassType: Class<T>, 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<T>(data: T){
final var data:T = data
class HTTPResponse<T>(data: T) {
final var data: T = data
}
fun <T>httpPost(url: String, body: Map<String, Any?>, onSuccess: (response: HTTPResponse<T>) -> Unit, onError: (error: Exception) -> Unit){
fun <T> httpPost(url: String, body: Map<String, Any?>, onSuccess: (response: HTTPResponse<T>) -> Unit, onError: (error: Exception) -> Unit) {
val gson = Gson()
val type = object : TypeToken<T>() {}.type
val type = object : TypeToken<T>() {}.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<T>(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<T>(dataString, type)
onSuccess(HTTPResponse(responseData))
} else {
onError(Exception("Invalid response from server (Not a valid JSON)"))
}
}, {
onError(it)
})
}
}
}

@ -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<LogModel>{
return Logs.Common.list(context,"GeofenceEvent", tag, status)
fun list(context: Context, tag: String? = null, status: Logs.STATUS? = null): List<LogModel> {
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<LogModel>{
return Logs.Common.list(context,"RegisterGeofence", tag, status)
fun list(context: Context, tag: String? = null, status: Logs.STATUS? = null): List<LogModel> {
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<LogModel>{
return Logs.Common.list(context,"Logs", tag, status)
fun list(context: Context, tag: String? = null, status: Logs.STATUS? = null): List<LogModel> {
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<LogsContainerModel>(string,LogsContainerModel::class.java)
val string = pref.getString(key, "{}")
val json = gson.fromJson<LogsContainerModel>(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<LogModel>{
fun list(context: Context, key: String, tag: String? = null, status: Logs.STATUS? = null): List<LogModel> {
val pref = Logs.storage(context)
val string = pref.getString(key,"{}")
val json = gson.fromJson<LogsContainerModel>(string,LogsContainerModel::class.java)
if(tag == null && status == null) {
val string = pref.getString(key, "{}")
val json = gson.fromJson<LogsContainerModel>(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<LogModel>()
fun add(log:LogModel){
fun add(log: LogModel) {
LOGS.add(log)
}
}

@ -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

@ -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

@ -0,0 +1,7 @@
package com.cloud.diplomaticquarterapp.utils
import kotlinx.coroutines.channels.Channel
object UiChannel {
val progressChannel = Channel<Int>(Channel.CONFLATED)
}

@ -0,0 +1,54 @@
apply plugin: 'com.android.library'
apply plugin: 'org.jetbrains.kotlin.android'
android {
compileSdkVersion 33
lintOptions{
abortOnError false
}
defaultConfig {
minSdkVersion 18
targetSdkVersion 33
versionCode 3
versionName "3.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
consumerProguardFiles 'proguard-rules.pro'
}
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
consumerProguardFiles 'proguard-rules.pro'
}
}
task makejar(type: Jar) {
from file('build/intermediates/javac/debug/classes')
archiveName = '2301sdk' + defaultConfig.versionName + '.jar'
destinationDir = file('build/libs')
include "com/jstyle/blesdk2301/**"
}
makejar.dependsOn(build)
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.core:core-ktx:+'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

@ -0,0 +1,26 @@
package com.jstyle.blesdk2301;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.jstyle.blesdk.test", appContext.getPackageName());
}
}

@ -0,0 +1,886 @@
package com.jstyle.blesdk2301.Util
import android.text.TextUtils
import com.jstyle.blesdk2301.callback.DataListener2301
import com.jstyle.blesdk2301.constant.BleConst
import com.jstyle.blesdk2301.constant.DeviceConst
import com.jstyle.blesdk2301.constant.DeviceKey
import com.jstyle.blesdk2301.model.AutoMode
import com.jstyle.blesdk2301.model.AutoTestMode
import com.jstyle.blesdk2301.model.MyAutomaticHRMonitoring
import com.jstyle.blesdk2301.model.MyDeviceTime
import com.jstyle.blesdk2301.model.MyPersonalInfo
import com.jstyle.blesdk2301.other.ResolveUtil
import java.io.UnsupportedEncodingException
import java.text.SimpleDateFormat
import java.util.Arrays
import java.util.Date
import kotlin.experimental.and
/**
* Created by Administrator on 2018/4/9.
*/
object BleSDK {
const val DATA_READ_START = 0
const val DATA_READ_CONTINUE = 2
const val DATA_DELETE = 99
const val DistanceMode_MILE = 0x81.toByte()
const val DistanceMode_KM = 0x80.toByte()
const val TimeMode_12h = 0x81.toByte()
const val TimeMode_24h = 0x80.toByte()
const val WristOn_Enable = 0x81.toByte()
const val WristOn_DisEnable = 0x80.toByte()
const val TempUnit_C = 0x80.toByte()
const val TempUnit_F = 0x81.toByte()
const val TAG = "BleSDK"
var isruning = false
private fun getByteArray(f: Float): ByteArray {
val intbits = java.lang.Float.floatToIntBits(f) //将float里面的二进制串解释为int整数
return getByteArrays(intbits)
}
fun getByteArrays(i: Int): ByteArray {
val b = ByteArray(4)
b[3] = (i and -0x1000000 shr 24).toByte()
b[2] = (i and 0x00ff0000 shr 16).toByte()
b[1] = (i and 0x0000ff00 shr 8).toByte()
b[0] = (i and 0x000000ff).toByte()
return b
}
fun DataParsingWithData(value: ByteArray, dataListener: DataListener2301) {
val map: Map<String, String> = HashMap()
when (value[0]) {
DeviceConst.CMD_Set_UseInfo -> dataListener.dataCallback(ResolveUtil.setMethodSuccessful(BleConst.SetPersonalInfo))
DeviceConst.CMD_Set_Auto -> dataListener.dataCallback(ResolveUtil.setMethodSuccessful(BleConst.SetAutomatic))
DeviceConst.CMD_Set_DeviceID -> dataListener.dataCallback(ResolveUtil.setMacSuccessful())
DeviceConst.CMD_SET_TIME -> dataListener.dataCallback(ResolveUtil.setTimeSuccessful(value))
DeviceConst.CMD_GET_TIME -> dataListener.dataCallback(ResolveUtil.getDeviceTime(value))
DeviceConst.CMD_GET_USERINFO -> dataListener.dataCallback(ResolveUtil.getUserInfo(value))
DeviceConst.CMD_Enable_Activity -> dataListener.dataCallback(ResolveUtil.getActivityData(value))
DeviceConst.CMD_Get_BatteryLevel -> dataListener.dataCallback(ResolveUtil.getDeviceBattery(value))
DeviceConst.CMD_Get_Address -> dataListener.dataCallback(ResolveUtil.getDeviceAddress(value))
DeviceConst.CMD_Get_Version -> dataListener.dataCallback(ResolveUtil.getDeviceVersion(value))
DeviceConst.CMD_Get_Auto -> dataListener.dataCallback(ResolveUtil.getAutoHeart(value))
DeviceConst.CMD_Reset -> dataListener.dataCallback(ResolveUtil.Reset())
DeviceConst.CMD_Mcu_Reset -> dataListener.dataCallback(ResolveUtil.MCUReset())
DeviceConst.CMD_Get_TotalData -> if (GetTotalActivityDataWithMode) {
dataListener.dataCallback(ResolveUtil.setMethodSuccessful(BleConst.Delete_GetTotalActivityData))
} else {
dataListener.dataCallback(ResolveUtil.getTotalStepData(value))
}
DeviceConst.CMD_Get_DetailData -> if (GetDetailActivityDataWithMode) {
dataListener.dataCallback(ResolveUtil.setMethodSuccessful(BleConst.deleteGetDetailActivityDataWithMode))
} else {
dataListener.dataCallback(ResolveUtil.getDetailData(value))
}
DeviceConst.CMD_Get_SleepData -> if (Delete_GetDetailSleepData) {
dataListener.dataCallback(ResolveUtil.setMethodSuccessful(BleConst.Delete_GetDetailSleepData))
} else {
dataListener.dataCallback(ResolveUtil.getSleepData(value))
}
DeviceConst.CMD_Get_HeartData -> if (GetDynamicHRWithMode) {
dataListener.dataCallback(ResolveUtil.setMethodSuccessful(BleConst.Delete_GetDynamicHR))
} else {
dataListener.dataCallback(ResolveUtil.getHeartData(value))
}
DeviceConst.CMD_Get_OnceHeartData -> if (GetStaticHRWithMode) {
dataListener.dataCallback(ResolveUtil.setMethodSuccessful(BleConst.Delete_GetStaticHR))
} else {
dataListener.dataCallback(ResolveUtil.getOnceHeartData(value))
}
DeviceConst.CMD_Get_HrvTestData -> if (readhrv) {
dataListener.dataCallback(ResolveUtil.getHrvTestData(value))
} else {
dataListener.dataCallback(ResolveUtil.DeleteHrv())
}
DeviceConst.ReadTempHisrory -> if (GetTemperature_historyDataWithMode) {
dataListener.dataCallback(ResolveUtil.setMethodSuccessful(BleConst.deleteGetTemperature_historyDataWithMode))
} else {
dataListener.dataCallback(ResolveUtil.getTempData(value))
}
DeviceConst.Oxygen_data -> if (Obtain_The_data_of_manual_blood_oxygen_test) {
dataListener.dataCallback(ResolveUtil.setMethodSuccessful(BleConst.Delete_Obtain_The_data_of_manual_blood_oxygen_test))
} else {
dataListener.dataCallback(ResolveUtil.GetAutomaticSpo2Monitoring(value))
}
DeviceConst.CMD_HeartPackageFromDevice -> dataListener.dataCallback(ResolveUtil.getActivityExerciseData(value))
DeviceConst.CMD_Set_Name -> dataListener.dataCallback(ResolveUtil.setMethodSuccessful(BleConst.CMD_Set_Name))
DeviceConst.CMD_Get_Name -> dataListener.dataCallback(ResolveUtil.getDeviceName(value))
DeviceConst.CMD_Get_SPORTData -> if (GetActivityModeDataWithMode) {
dataListener.dataCallback(ResolveUtil.setMethodSuccessful(BleConst.Delete_ActivityModeData))
} else {
dataListener.dataCallback(ResolveUtil.getExerciseData(value))
}
DeviceConst.MeasurementWithType -> if (StartDeviceMeasurementWithType) {
val vv: MutableMap<String?, Any?> = HashMap()
when (value[1]) {
1.toByte() -> {
vv[DeviceKey.DataType] = BleConst.MeasurementHrvCallback
vv[DeviceKey.End] = true
val lm: MutableMap<String, String> = HashMap()
lm[DeviceKey.Type] = ResolveUtil.getValue(value[1], 0).toString() + ""
lm[DeviceKey.HeartRate] = ResolveUtil.getValue(value[2], 0).toString() + ""
lm[DeviceKey.Blood_oxygen] = ResolveUtil.getValue(value[3], 0).toString() + ""
lm[DeviceKey.HRV] = ResolveUtil.getValue(value[4], 0).toString() + ""
lm[DeviceKey.Stress] = ResolveUtil.getValue(value[5], 0).toString() + ""
lm[DeviceKey.HighPressure] = ResolveUtil.getValue(value[6], 0).toString() + ""
lm[DeviceKey.LowPressure] = ResolveUtil.getValue(value[7], 0).toString() + ""
vv[DeviceKey.Data] = lm
dataListener.dataCallback(vv)
}
2.toByte() -> {
vv[DeviceKey.DataType] = BleConst.MeasurementHeartCallback
vv[DeviceKey.End] = true
val lmB: MutableMap<String, String> = HashMap()
lmB[DeviceKey.Type] = ResolveUtil.getValue(value[1], 0).toString() + ""
lmB[DeviceKey.HeartRate] = ResolveUtil.getValue(value[2], 0).toString() + ""
lmB[DeviceKey.Blood_oxygen] = ResolveUtil.getValue(value[3], 0).toString() + ""
lmB[DeviceKey.HRV] = ResolveUtil.getValue(value[4], 0).toString() + ""
lmB[DeviceKey.Stress] = ResolveUtil.getValue(value[5], 0).toString() + ""
lmB[DeviceKey.HighPressure] = ResolveUtil.getValue(value[6], 0).toString() + ""
lmB[DeviceKey.LowPressure] = ResolveUtil.getValue(value[7], 0).toString() + ""
vv[DeviceKey.Data] = lmB
dataListener.dataCallback(vv)
}
3.toByte() -> {
vv[DeviceKey.DataType] = BleConst.MeasurementOxygenCallback
vv[DeviceKey.End] = true
val lmC: MutableMap<String, String> = HashMap()
lmC[DeviceKey.Type] = ResolveUtil.getValue(value[1], 0).toString() + ""
lmC[DeviceKey.HeartRate] = ResolveUtil.getValue(value[2], 0).toString() + ""
lmC[DeviceKey.Blood_oxygen] = ResolveUtil.getValue(value[3], 0).toString() + ""
lmC[DeviceKey.HRV] = ResolveUtil.getValue(value[4], 0).toString() + ""
lmC[DeviceKey.Stress] = ResolveUtil.getValue(value[5], 0).toString() + ""
lmC[DeviceKey.HighPressure] = ResolveUtil.getValue(value[6], 0).toString() + ""
lmC[DeviceKey.LowPressure] = ResolveUtil.getValue(value[7], 0).toString() + ""
vv[DeviceKey.Data] = lmC
dataListener.dataCallback(vv)
}
}
} else {
val vv: MutableMap<String?, Any?> = HashMap()
when (value[1]) {
1.toByte() -> {
vv[DeviceKey.DataType] = BleConst.StopMeasurementHrvCallback
vv[DeviceKey.End] = true
vv[DeviceKey.Data] = HashMap<Any, Any>()
dataListener.dataCallback(vv)
}
2.toByte() -> {
vv[DeviceKey.DataType] = BleConst.StopMeasurementHeartCallback
vv[DeviceKey.End] = true
vv[DeviceKey.Data] = HashMap<Any, Any>()
dataListener.dataCallback(vv)
}
3.toByte() -> {
vv[DeviceKey.DataType] = BleConst.StopMeasurementOxygenCallback
vv[DeviceKey.End] = true
vv[DeviceKey.Data] = HashMap<Any, Any>()
dataListener.dataCallback(vv)
}
}
}
DeviceConst.CMD_Get_Bloodsugar -> if (startBloodsugar) { //只有开始测量才返回状态
val vv: MutableMap<String?, Any?> = HashMap()
vv[DeviceKey.DataType] = BleConst.Blood_glucose_status
vv[DeviceKey.End] = true
val lm: MutableMap<String, String> = HashMap()
lm[DeviceKey.Type] = ResolveUtil.getValue(value[1], 0).toString() + ""
vv[DeviceKey.Data] = lm
dataListener.dataCallback(vv)
}
DeviceConst.Bloodsugar_data -> {
val vv: MutableMap<String?, Any?> = HashMap()
vv[DeviceKey.DataType] = BleConst.Blood_glucose_data
vv[DeviceKey.End] = false
val lm: MutableMap<String, String> = HashMap()
lm[DeviceKey.Time] = getFormatTimeString(System.currentTimeMillis(), "yyyy.MM.dd HH:mm:ss")
val simplePpg: MutableList<Int> = ArrayList()
if (value.size == 153) { //新血糖解析
val valueer = ByteArray(value.size - 3)
System.arraycopy(value, 3, valueer, 0, valueer.size)
var i = 0
while (i < valueer.size / 3) {
val valuedata = (ResolveUtil.getValue(valueer[3 * i], 2)
+ ResolveUtil.getValue(valueer[3 * i + 1], 1)
+ ResolveUtil.getValue(valueer[3 * i + 2], 0))
simplePpg.add(valuedata)
i++
}
lm[DeviceKey.PPG] = Arrays.toString(simplePpg.toTypedArray())
}
vv[DeviceKey.Data] = lm
dataListener.dataCallback(vv)
}
DeviceConst.CMD_Start_EXERCISE -> if (FindActivityMode) {
val mapEXERCISE: MutableMap<String?, Any?> = HashMap()
mapEXERCISE[DeviceKey.DataType] = BleConst.FindActivityMode
mapEXERCISE[DeviceKey.End] = true
val mapsx: MutableMap<String, String> = HashMap()
mapsx[DeviceKey.Type] = ResolveUtil.getValue(value[1], 0).toString() + ""
mapsx[DeviceKey.Status] = ResolveUtil.getValue(value[2], 0).toString() + ""
mapEXERCISE[DeviceKey.Data] = mapsx
dataListener.dataCallback(mapEXERCISE)
} else {
val mapEXERCISE: MutableMap<String?, Any?> = HashMap()
mapEXERCISE[DeviceKey.DataType] = BleConst.EnterActivityMode
mapEXERCISE[DeviceKey.End] = true
val mapsx: MutableMap<String, String> = HashMap()
mapsx[DeviceKey.enterActivityModeSuccess] = ResolveUtil.getValue(value[1], 0).toString() + ""
mapEXERCISE[DeviceKey.Data] = mapsx
dataListener.dataCallback(mapEXERCISE)
}
}
// return map;
}
internal var Delete_GetDetailSleepData = false
fun GetDetailSleepDataWithMode(mode: Byte, dateOfLastData: String): ByteArray {
Delete_GetDetailSleepData = 0x99.toByte() == mode
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_SleepData
value[1] = mode
insertDateValue(value, dateOfLastData)
crcValue(value)
return value
}
/**
* 开始实时计步
*
* @return
*/
fun RealTimeStep(enable: Boolean, tempEnable: Boolean): ByteArray {
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Enable_Activity
value[1] = (if (enable) 1 else 0).toByte()
value[2] = (if (tempEnable) 1 else 0).toByte()
crcValue(value)
return value
}
/**
* 设置个人信息
*
* @param
* @return
*/
fun SetPersonalInfo(info: MyPersonalInfo): ByteArray {
val value = ByteArray(16)
val male = info.sex
val age = info.age
val height = info.height
val weight = info.weight
val stepLength = info.stepLength
value[0] = DeviceConst.CMD_Set_UseInfo
value[1] = male.toByte()
value[2] = age.toByte()
value[3] = height.toByte()
value[4] = weight.toByte()
value[5] = stepLength.toByte()
crcValue(value)
return value
}
/**
* 获取个人信息
*
* @return
*/
fun GetPersonalInfo(): ByteArray {
val value = ByteArray(16)
value[0] = DeviceConst.CMD_GET_USERINFO
crcValue(value)
return value
}
/**
* 设置设备时间
*
* @param
* @return
*/
fun SetDeviceTime(time: MyDeviceTime): ByteArray {
val value = ByteArray(16)
val timeZone = ResolveUtil.getCurrentTimeZone()
var zone = timeZone.substring(3)
var zoneValue: Byte = 0
if (zone.contains("-")) {
zone = zone.replace("-", "")
zoneValue = java.lang.Byte.valueOf(zone)
} else {
zoneValue = (java.lang.Byte.valueOf(zone) + 0x80).toByte()
}
val year = time.year
val month = time.month
val day = time.day
val hour = time.hour
val min = time.minute
val second = time.second
value[0] = DeviceConst.CMD_SET_TIME
value[1] = ResolveUtil.getTimeValue(year)
value[2] = ResolveUtil.getTimeValue(month)
value[3] = ResolveUtil.getTimeValue(day)
value[4] = ResolveUtil.getTimeValue(hour)
value[5] = ResolveUtil.getTimeValue(min)
value[6] = ResolveUtil.getTimeValue(second)
value[8] = zoneValue
crcValue(value)
return value
}
/**
* 获取设备时间
*
* @return
*/
fun GetDeviceTime(): ByteArray {
val value = ByteArray(16)
value[0] = DeviceConst.CMD_GET_TIME
crcValue(value)
return value
}
/**
* 99: 删除步数详细数据 ,
* 0:读最近的步数详细数据
* 1读指定位置的步数详细数据
* 2继续上次读的位置下一段数据
*
* @param
* @return * dateOfLastData "yyyy-MM-dd HH:mm:ss or yyyy.MM.dd HH:mm:ss"
*/
private var GetDetailActivityDataWithMode = false
fun GetDetailActivityDataWithMode(mode: Byte, dateOfLastData: String): ByteArray {
GetDetailActivityDataWithMode = 0x99.toByte() == mode
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_DetailData
value[1] = mode
insertDateValue(value, dateOfLastData)
crcValue(value)
return value
}
/**
* 99: 删除温度数据 ,
* 0:读最近的温度详细数据
* 1读指定位置的步数详细数据
* 2继续上次读的位置下一段数据
*
* @param
* @return
*/
internal var GetTemperature_historyDataWithMode = false
fun GetTemperature_historyData(mode: Byte, dateOfLastData: String): ByteArray {
GetTemperature_historyDataWithMode = 0x99.toByte() == mode
val value = ByteArray(16)
value[0] = DeviceConst.ReadTempHisrory
value[1] = mode
insertDateValue(value, dateOfLastData)
crcValue(value)
return value
}
var StartDeviceMeasurementWithType = false
fun SetDeviceMeasurementWithType(dataType: AutoTestMode?, second: Long, open: Boolean): ByteArray {
StartDeviceMeasurementWithType = open
val value = ByteArray(16)
value[0] = DeviceConst.MeasurementWithType
when (dataType) {
AutoTestMode.AutoHeartRate -> value[1] = 0x02.toByte()
AutoTestMode.AutoSpo2 -> value[1] = 0x03.toByte()
else -> {}
}
value[2] = if (open) 0x01.toByte() else 0x00.toByte()
value[3] = (second and 0xffL).toByte()
value[4] = (second shr 8 and 0xffL).toByte()
crcValue(value)
return value
}
fun SetAutomaticHRMonitoring(autoHeart: MyAutomaticHRMonitoring, type: AutoMode?): ByteArray {
val value = ByteArray(16)
val time = autoHeart.time
value[0] = DeviceConst.CMD_Set_Auto
value[1] = autoHeart.open.toByte()
value[2] = ResolveUtil.getTimeValue(autoHeart.startHour)
value[3] = ResolveUtil.getTimeValue(autoHeart.startMinute)
value[4] = ResolveUtil.getTimeValue(autoHeart.endHour)
value[5] = ResolveUtil.getTimeValue(autoHeart.endMinute)
value[6] = autoHeart.week.toByte()
value[7] = (time and 0xff).toByte()
value[8] = (time shr 8 and 0xff).toByte()
if (null == type) {
value[9] = 0x01.toByte()
} else {
when (type) {
AutoMode.AutoHeartRate -> value[9] = 0x01.toByte()
AutoMode.AutoSpo2 -> value[9] = 0x02.toByte()
AutoMode.AutoTemp -> value[9] = 0x03.toByte()
AutoMode.AutoHrv -> value[9] = 0x04.toByte()
}
}
crcValue(value)
return value
}
fun GetAutomatic(type: AutoMode?): ByteArray {
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_Auto
if (null == type) {
value[1] = 0x01.toByte()
} else {
when (type) {
AutoMode.AutoHeartRate -> value[1] = 0x01.toByte()
AutoMode.AutoSpo2 -> value[1] = 0x02.toByte()
AutoMode.AutoTemp -> value[1] = 0x03.toByte()
AutoMode.AutoHrv -> value[1] = 0x04.toByte()
}
}
crcValue(value)
return value
}
/**
* 获取某天总数据
* 0
*
* @param mode 0:是从最新的位置开始读取(最多50组数据) 2:接着读取(当数据总数于50的时候) 0x99:删除所有运
* 动数据
* @return
*/
internal var GetTotalActivityDataWithMode = false
fun GetTotalActivityDataWithMode(mode: Byte, dateOfLastData: String): ByteArray {
GetTotalActivityDataWithMode = 0x99.toByte() == mode
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_TotalData
value[1] = mode
insertDateValueNoH(value, dateOfLastData)
crcValue(value)
return value
}
/**
* 获取设备版本号
*
* @return
*/
fun GetDeviceVersion(): ByteArray {
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_Version
crcValue(value)
return value
}
/**
* 恢复出厂设置
*
* @return
*/
fun Reset(): ByteArray {
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Reset
crcValue(value)
return value
}
/**
* 获取设备mac地址
*
* @return
*/
fun GetDeviceMacAddress(): ByteArray {
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_Address
crcValue(value)
return value
}
/**
* 获取设备电量
*
* @return
*/
fun GetDeviceBatteryLevel(): ByteArray {
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_BatteryLevel
crcValue(value)
return value
}
/**
* 重启设备
*
* @return
*/
fun MCUReset(): ByteArray {
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Mcu_Reset
crcValue(value)
return value
}
private var readhrv = false
fun GetHRVDataWithMode(mode: Byte, dateOfLastData: String): ByteArray {
readhrv = 0x99.toByte() != mode
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_HrvTestData
value[1] = mode
insertDateValue(value, dateOfLastData)
crcValue(value)
return value
}
internal var GetStaticHRWithMode = false
fun GetStaticHRWithMode(mode: Byte, dateOfLastData: String): ByteArray {
GetStaticHRWithMode = 0x99.toByte() == mode
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_OnceHeartData
value[1] = mode
insertDateValue(value, dateOfLastData)
crcValue(value)
return value
}
internal var GetDynamicHRWithMode = false
fun GetDynamicHRWithMode(Number: Byte, dateOfLastData: String): ByteArray {
GetDynamicHRWithMode = 0x99.toByte() == Number
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_HeartData
value[1] = Number
insertDateValue(value, dateOfLastData)
crcValue(value)
return value
}
fun SetDeviceID(deviceId: String): ByteArray {
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Set_DeviceID
for (i in 0..5) {
value[i + 1] = deviceId[i].code.toByte()
}
crcValue(value)
return value
}
fun intTobyte(num: Int): ByteArray {
return byteArrayOf((num shr 8 and 0xff).toByte(), (num and 0xff).toByte())
}
@JvmStatic
fun byteArrayToInt(arr: ByteArray): Int {
val targets = (arr[1].toInt() and 0xff or (arr[0].toInt() shl 8 and 0xff00)).toShort()
return targets.toInt()
}
fun getInfoValue(info: String, maxLength: Int): ByteArray? {
var nameBytes: ByteArray? = null
try {
nameBytes = info.toByteArray(charset("UTF-8"))
if (nameBytes.size >= maxLength) { //两条命令总共32个字节内容只占24个字节32-2*1cmd+1消息类型+1长度+1校验
val real = ByteArray(maxLength)
val chars = info.toCharArray()
var length = 0
for (i in chars.indices) {
val s = chars[i].toString()
val nameB = s.toByteArray(charset("UTF-8"))
if (length + nameB.size == maxLength) {
System.arraycopy(nameBytes, 0, real, 0, real.size)
return real
} else if (length + nameB.size > maxLength) { //大于24会导致有个字节发不到下位机导致乱码
System.arraycopy(nameBytes, 0, real, 0, length)
return real
}
length += nameB.size
}
}
} catch (e: UnsupportedEncodingException) {
// TODO Auto-generated catch block
e.printStackTrace()
}
return nameBytes
}
fun crcValue(value: ByteArray) {
var crc: Byte = 0
for (i in 0 until value.size - 1) {
crc = (crc + value[i]).toByte()
}
value[value.size - 1] = (crc and 0xff.toByte())
}
fun insertDateValue(value: ByteArray, time: String) {
if (!TextUtils.isEmpty(time) && time.length > 8) {
val timeArray = time.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val INDEX: String
INDEX = if (time.contains("-")) {
"-"
} else {
"\\."
}
val year = timeArray[0].split(INDEX.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].toInt()
val month = timeArray[0].split(INDEX.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1].toInt()
val day = timeArray[0].split(INDEX.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[2].toInt()
val hour = timeArray[1].split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].toInt()
val min = timeArray[1].split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1].toInt()
val second = timeArray[1].split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[2].toInt()
value[4] = ResolveUtil.getTimeValue(year)
value[5] = ResolveUtil.getTimeValue(month)
value[6] = ResolveUtil.getTimeValue(day)
value[7] = ResolveUtil.getTimeValue(hour)
value[8] = ResolveUtil.getTimeValue(min)
value[9] = ResolveUtil.getTimeValue(second)
}
}
fun insertDateValueNoH(value: ByteArray, time: String) {
if (!TextUtils.isEmpty(time) && time.contains("-")) {
val timeArray = time.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val INDEX: String
INDEX = if (time.contains("-")) {
"-"
} else {
"\\."
}
val year = timeArray[0].split(INDEX.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0].toInt()
val month = timeArray[0].split(INDEX.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1].toInt()
val day = timeArray[0].split(INDEX.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[2].toInt()
value[4] = ResolveUtil.getTimeValue(year)
value[5] = ResolveUtil.getTimeValue(month)
value[6] = ResolveUtil.getTimeValue(day)
}
}
/**
* 转十六进制字符串
*
* @param data
* @return
*/
fun byte2Hex(data: ByteArray?): String {
if (data != null && data.size > 0) {
val sb = StringBuilder(data.size)
for (tmp in data) {
sb.append(String.format("%02X ", tmp))
}
return sb.toString()
}
return "no data"
}
/**
* OObtain automated test oximetry data
* 获得自动测试血氧数据
*/
internal var Obtain_The_data_of_manual_blood_oxygen_test = false
fun Oxygen_data(Number: Byte): ByteArray {
Obtain_The_data_of_manual_blood_oxygen_test = 0x99.toByte() == Number
val value = ByteArray(16)
value[0] = DeviceConst.Oxygen_data
value[1] = Number
crcValue(value)
return value
}
fun EnterActivityMode(time: Int, activityMode: Int, WorkMode: Int): ByteArray {
FindActivityMode = false
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Start_EXERCISE
value[1] = WorkMode.toByte()
value[2] = activityMode.toByte()
value[4] = time.toByte()
crcValue(value)
return value
}
private var FindActivityMode = false
fun FindActivityMode(): ByteArray {
FindActivityMode = true
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Start_EXERCISE
value[1] = 0x05.toByte()
crcValue(value)
return value
}
/**
* @param status 级别 0,1,2
* @param time 分钟
* @param WorkMode START=1;PAUSE=2;CONTUINE=3;FINISH=4;
* @return
*/
fun setExerciseModeByBreath(status: Int, time: Int, WorkMode: Int): ByteArray {
FindActivityMode = false
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Start_EXERCISE
value[1] = WorkMode.toByte()
value[2] = 0x06.toByte()
value[3] = status.toByte()
value[4] = time.toByte()
crcValue(value)
return value
}
fun sendHeartPackage(distance: Float, space: Int, rssi: Int): ByteArray {
val value = ByteArray(16)
val distanceValue = getByteArray(distance)
val min = space / 60
val second = space % 60
value[0] = DeviceConst.CMD_heart_package
System.arraycopy(distanceValue, 0, value, 1, distanceValue.size)
value[5] = min.toByte()
value[6] = second.toByte()
value[7] = rssi.toByte()
crcValue(value)
return value
}
/**
* 设置设备名字
*
* @param
* @return
*/
fun SetDeviceName(strDeviceName: String): ByteArray {
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Set_Name
val length = if (strDeviceName.length > 14) 14 else strDeviceName.length
for (i in 0 until length) {
value[i + 1] = strDeviceName[i].code.toByte()
}
crcValue(value)
return value
}
/**
* 获取设备名字
*
* @return
*/
fun GetDeviceName(): ByteArray {
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_Name
crcValue(value)
return value
}
/**
* 获取多模式运动数据
*
* @param mode 0:是从最新的位置开始读取(最多50组数据) 2:接着读取(当数据总数于50的时候) 0x99:删除所有
* GPS数据
* @return
*/
internal var GetActivityModeDataWithMode = false
fun GetActivityModeDataWithMode(mode: Byte): ByteArray {
GetActivityModeDataWithMode = 0x99.toByte() == mode
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_SPORTData
value[1] = mode
crcValue(value)
return value
}
/**
* 开始血氧测量
* Start blood oxygen measurement
*/
var startBloodsugar = false
fun startBloodsugar(): ByteArray {
startBloodsugar = true
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_Bloodsugar
value[1] = 0x01.toByte()
crcValue(value)
return value
}
/**
* 停止血氧测量
* Stop blood oxygen measurement
*/
fun BloodsugarStop(): ByteArray {
startBloodsugar = false
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_Bloodsugar
value[1] = 0x05.toByte()
crcValue(value)
return value
}
/**
* 血氧测量停止信号采集
* Blood oxygen measurement stop signal acquisition
*/
fun BloodsugarStopSiss(): ByteArray {
startBloodsugar = false
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_Bloodsugar
value[1] = 0x03.toByte()
crcValue(value)
return value
}
/**
* 血氧测量进度更新
* Blood oxygen measurement progress update
*/
fun BloodsugarProgress(Progress: Int): ByteArray {
startBloodsugar = false
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_Bloodsugar
value[1] = 0x04.toByte()
value[2] = Progress.toByte() //0-100
crcValue(value)
return value
}
/**
* 血氧测量结果
* Send blood glucose results to the device
* status 1 2 3 0测试失败
* Status 1 low 2 3 high 0 test failed
*/
fun SendBloodGlucoseResultsToTheDevice(status: Int): ByteArray {
startBloodsugar = false
val value = ByteArray(16)
value[0] = DeviceConst.CMD_Get_Bloodsugar
value[1] = 0x02.toByte()
value[2] = status.toByte()
crcValue(value)
return value
}
/**
* 获取指定格式的日期字符串
*/
@Synchronized
fun getFormatTimeString(time: Long, formatString: String?): String {
val format = SimpleDateFormat(formatString)
var data = ""
try {
data = format.format(Date(time))
} catch (E: Exception) {
E.printStackTrace()
}
return data
}
}

@ -0,0 +1,230 @@
package com.jstyle.blesdk2301.Util
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Rect
import android.graphics.pdf.PdfDocument
import android.os.Build
import android.text.TextUtils
import com.jstyle.blesdk2301.model.UserInfo
import java.io.File
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
object PDFCreate {
private const val TAG = "PDFCreate"
const val maxXSize = 5120
var length = 20f
var totalWidth = 1070f
var startX = 35
var endX = (startX + 1000).toFloat()
var startY = 0f
private var endY = 0f
private var height = 0f
private var width = 0f
private var strokeWidthTime = 0
private var strokeWidthLine = 0
private var totalHeight = 0f
fun createPdf(path: String?, context: Context, data: List<Int>, userInfo: UserInfo?) {
val size = data.size
val col = (if (size % maxXSize == 0) size / maxXSize else size / maxXSize + 1).toFloat() //一次画5120个点分多少次画
length = dip2px(context, 10f).toFloat()
height = length
width = length
startX = dip2px(context, 20f)
endX = startX + 50 * length
totalWidth = endX + startX
totalHeight = col * height * 5 + dip2px(context, 130f) //一次需要5个高度
val pdfDocument = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
PdfDocument()
} else {
TODO("VERSION.SDK_INT < KITKAT")
}
val pageInfo = PdfDocument.PageInfo.Builder(totalWidth.toInt(), totalHeight.toInt(), 1) // .setContentRect(new Rect(0,0,(int)totalWidth,(int)totalHeight))
.create()
val page = pdfDocument.startPage(pageInfo)
val canvas = page.canvas
val paint = Paint()
strokeWidthTime = dip2px(context, 1.5f)
strokeWidthLine = dip2px(context, 0.5f)
drawReportInfo(context, canvas, paint, userInfo)
val pathCanvas = Path()
endY = startY + col * height * 5
paint.textSize = dip2px(context, 15f).toFloat()
drawAxes(pathCanvas, canvas, paint, col)
drawTimeLine(pathCanvas, canvas, paint)
drawDataLine(context, pathCanvas, canvas, paint, col, data)
pdfDocument.finishPage(page)
val file = File(path)
var outputStream: FileOutputStream? = null
try {
outputStream = FileOutputStream(file)
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
try {
pdfDocument.writeTo(outputStream)
} catch (e: IOException) {
e.printStackTrace()
}
}
/**用户信息
* @param context
* @param canvas
* @param paint
* @param
*/
private fun drawReportInfo(context: Context, canvas: Canvas, paint: Paint, userInfo: UserInfo?) {
paint.textSize = dip2px(context, 15f).toFloat()
paint.color = Color.BLACK
paint.style = Paint.Style.FILL
if (null != userInfo) {
if (!TextUtils.isEmpty(userInfo.ecgTitle)) {
val title = userInfo.ecgTitle
val rect = Rect()
paint.getTextBounds(title, 0, title.length, rect)
val heightTitle = rect.height()
val startTextY = (heightTitle + dip2px(context, 8f)).toFloat()
val marginTop = dip2px(context, 4f).toFloat()
val marginRight = dip2px(context, 8f).toFloat()
//标题
canvas.drawText(title, totalWidth / 2 - 150, startTextY, paint)
//提醒
paint.textSize = dip2px(context, 12f).toFloat()
val widthTips = rect.width()
val heightTips = rect.height()
if (!TextUtils.isEmpty(userInfo.ecgReportTips)) {
val tips = userInfo.ecgReportTips
val tipsTextY = startTextY + heightTitle + marginTop
paint.getTextBounds(tips, 0, tips.length, rect)
canvas.drawText(tips, totalWidth - widthTips - marginRight, tipsTextY, paint)
}
val tipsTextY = startTextY + heightTitle + marginTop
val name = userInfo.name
val genderString = userInfo.gender
val age = userInfo.age
val userWeight = userInfo.weight
val userHeight = userInfo.height
//个人信息
val infoTextY = tipsTextY + heightTips + marginTop
@SuppressLint("StringFormatMatches") val info = "$name $genderString $age $userHeight $userWeight"
paint.getTextBounds(info, 0, info.length, rect)
val heightInfo = rect.height()
val widthInfo = rect.width()
canvas.drawText(info, totalWidth / 2 - (widthInfo shr 1), infoTextY, paint)
//时间
val dateTextY = infoTextY + heightInfo + marginTop
val dateString = userInfo.date
paint.getTextBounds(dateString, 0, dateString.length, rect)
val widthDate = rect.width()
val heightDate = rect.height()
canvas.drawText(dateString, totalWidth - widthDate - marginRight, dateTextY, paint)
startY = dateTextY + heightDate + marginTop
}
}
}
/**
* 画网格
*
* @param pathCanvas
* @param canvas
* @param paint
* @param col
*/
private fun drawAxes(pathCanvas: Path, canvas: Canvas, paint: Paint, col: Float) {
//画网格竖线
val colorLine = Color.rgb(243, 119, 99)
paint.color = colorLine
paint.style = Paint.Style.STROKE
paint.strokeWidth = strokeWidthLine.toFloat()
paint.alpha = 200
for (i in 0..50) {
pathCanvas.moveTo(i * width + startX, startY)
pathCanvas.lineTo(i * width + startX, endY)
}
//画网格横线
var i = 0
while (i <= col * 5) {
pathCanvas.moveTo((startX - (strokeWidthTime shr 1)).toFloat(), i * height + startY)
pathCanvas.lineTo(endX + (strokeWidthTime shr 1), i * height + startY)
i++
}
canvas.drawPath(pathCanvas, paint)
pathCanvas.reset()
}
/**
* 加粗时间线
*
* @param pathCanvas
* @param canvas
* @param paint
*/
private fun drawTimeLine(pathCanvas: Path, canvas: Canvas, paint: Paint) {
paint.color = Color.BLACK
paint.strokeWidth = strokeWidthTime.toFloat()
paint.style = Paint.Style.FILL
val rect = Rect()
for (i in 0..10) {
pathCanvas.moveTo(i * 5 * width + startX, startY)
pathCanvas.lineTo(i * 5 * width + startX, endY + 20)
val time = i.toString() + "s"
paint.getTextBounds(time, 0, time.length, rect)
val widthTime = rect.width()
canvas.drawText(time, i * 5 * width + startX - (widthTime shr 1), endY + 50, paint)
}
val colorS = Color.rgb(255, 119, 99)
paint.color = colorS
paint.alpha = 255
paint.style = Paint.Style.STROKE
canvas.drawPath(pathCanvas, paint)
pathCanvas.reset()
}
/**
* 画数据
*
* @param pathCanvas
* @param canvas
* @param paint
* @param col
* @param data
*/
private fun drawDataLine(context: Context, pathCanvas: Path, canvas: Canvas, paint: Paint, col: Float, data: List<Int>) {
val size = data.size
paint.strokeWidth = strokeWidthLine.toFloat()
paint.color = Color.BLACK
var i = 0
out@ while (i < col) {
val startPoint = i * maxXSize
`in`@ for (j in 0 until maxXSize) {
if (startPoint + j >= size) break@out
val y = data[startPoint + j]
if (j == 0) pathCanvas.moveTo(startX.toFloat(), i * height * 5 + getCanvasY(y.toDouble(), context))
pathCanvas.lineTo(startX + j * (endX - startX) / maxXSize, i * height * 5 + getCanvasY(y.toDouble(), context))
}
i++
}
canvas.drawPath(pathCanvas, paint)
}
private fun getCanvasY(value: Double, context: Context): Float {
val height = (5 * 10 / 16000f).toDouble()
return dip2px(context, (height * (8000 - value)).toFloat()) + startY
}
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
fun dip2px(context: Context, dpValue: Float): Int {
val scale = context.resources.displayMetrics.density
return (dpValue * scale + 0.5f).toInt()
}
}

@ -0,0 +1,10 @@
package com.jstyle.blesdk2301.callback
interface BleConnectionListener {
fun BleStatus(status: Int, newState: Int) //蓝牙4.0连接状态 Bluetooth 4.0 connection status
fun ConnectionSucceeded() //连接设备成功 Successfully connected the device
fun Connecting() //设备连接中 Device is connected
fun ConnectionFailed() //设备连接失败 Device connection failed
fun OnReconnect() //重新连接中 Reconnecting
fun BluetoothSwitchIsTurnedOff() //蓝牙开关被关闭 Bluetooth switch is turned off
}

@ -0,0 +1,9 @@
package com.jstyle.blesdk2301.callback
/**
* Created by Administrator on 2018/4/10.
*/
interface DataListener2301 {
fun dataCallback(maps: Map<String?, Any?>?)
fun dataCallback(value: ByteArray?)
}

@ -0,0 +1,8 @@
package com.jstyle.blesdk2301.callback
import com.jstyle.blesdk2301.model.Device
interface OnScanResults {
fun Success(date: Device?)
fun Fail(code: Int)
}

@ -0,0 +1,24 @@
package com.jstyle.blesdk2301.cmdenum
import java.io.Serializable
class YhDeviceData : Serializable {
var dataType = 0 // is index
var data: String? = "" //data object
var isDataEnd = false //Is it over?
fun srgetDeviceData(): String {
return if (data == null) "" else data!!
}
fun srsetData(data: String?) {
this.data = data
}
override fun toString(): String {
return "YhDeviceData{" +
"dataType=" + dataType +
", data=" + data +
", dataEnd=" + isDataEnd +
'}'
}
}

@ -0,0 +1,128 @@
package com.jstyle.blesdk2301.constant
/**
* Created by Administrator on 2020/4/9.
*/
object BleConst {
const val GetDeviceTime = "0"
const val SetDeviceTime = "1"
const val GetPersonalInfo = "2"
const val SetPersonalInfo = "3"
const val GetDeviceInfo = "4"
const val SetDeviceInfo = "5" //设置手环基本参数
const val CMD_Set_Mac = "6"
const val GetStepGoal = "7"
const val SetStepGoal = "8"
const val GetDeviceBatteryLevel = "9"
const val GetDeviceMacAddress = "10"
const val GetDeviceVersion = "11"
const val CMD_Reset = "12"
const val CMD_MCUReset = "13"
const val SetMotorVibrationWithTimes = "14"
const val GetDeviceName = "15"
const val GetAutomatic = "16"
const val SetAutomatic = "17"
const val GetAlarmClock = "18"
const val SetAlarmClockWithAllClock = "19"
const val Notify = "20"
const val GetSedentaryReminder = "21"
const val SetSedentaryReminder = "22"
const val RealTimeStep = "23"
const val GetTotalActivityData = "24"
const val GetDetailActivityData = "25"
const val GetDetailSleepData = "26"
const val GetDynamicHR = "27"
const val GetStaticHR = "28"
const val GetActivityModeData = "29"
const val EnterActivityMode = "30"
const val DeviceSendDataToAPP = "31"
const val BackHomeView = "35"
const val GetTempHistoryData = "36"
const val ECGDATA = "37"
const val EcgppGstatus = "38"
const val EcgppG = "39"
const val GPSControlCommand = "40"
const val Gps = "41" //手环发送给app
const val GetHRVData = "42"
const val CMD_Set_TemperatureCorrection = "43"
const val Weather = "44"
const val Braceletdial = "45"
const val Braceletdialok = "46"
const val SportMode = "47"
const val GetSportMode = "48"
const val CMD_Set_WorkOutReminder = "49"
const val CMD_Get_WorkOutReminder = "50"
const val ReadSerialNumber = "51"
const val ECG = "53"
const val Clear_Bracelet_data = "54"
const val Blood_oxygen = "55"
const val SocialdistanceGetting = "56"
const val SocialdistanceSetting = "57"
const val Sos = "58"
const val Temperature_history = "59"
const val SetDialinterface = "60"
const val HeartBeatpacket = "61"
const val GetAxillaryTemperatureDataWithMode = "62"
const val GetMAC = "63"
const val Getppg = "64"
const val CloseECGPPG = "65"
const val GetEcgPpgStatus = "66"
const val ECGdata = "67"
const val GetAutomaticSpo2Monitoring = "68"
const val SetSpo2 = "69"
const val GEtSpo2 = "70"
const val DeleteECGdata = "71"
const val DeleteHrv = "72"
const val MeasurementHrvCallback = "73"
const val MeasurementHeartCallback = "74"
const val MeasurementOxygenCallback = "75"
const val StopMeasurementHrvCallback = "76"
const val StopMeasurementHeartCallback = "77"
const val StopMeasurementOxygenCallback = "78"
const val ExitQRcode = "79"
const val EnterQRcode = "80"
const val QRcodebandBack = "81"
const val SportData = "82"
const val Delete_Obtain_The_data_of_manual_blood_oxygen_test = "83"
const val Delete_Blood_oxygen = "84"
const val Delete_GetTotalActivityData = "85"
const val Delete_AlarmClock = "87"
const val Delete_ActivityModeData = "88"
const val Delete_GetStaticHR = "89"
const val Delete_GetDynamicHR = "90"
const val deleteGetTemperature_historyDataWithMode = "91"
const val deleteGetAxillaryTemperatureDataWithMode = "92"
const val deleteGetDetailActivityDataWithMode = "93"
const val Delete_GetDetailSleepData = "94"
const val Enter_photo_mode = "95"
const val openRRInterval = "96"
const val closeRRInterval = "97"
const val realtimeRRIntervalData = "98"
const val realtimePPGData = "99"
const val realtimePPIData = "100"
const val ppgWithMode = "101"
const val ppgStartSucessed = "102"
const val ppgStartFailed = "103"
const val ppgStop = "104"
const val ppgQuit = "105"
const val ppgMeasurementProgress = "106"
const val ppgResult = "107"
const val SetBloodpressure_calibration = "108"
const val GetBloodpressure_calibration = "109"
const val SetWomenHealth = "110"
const val GetWomenHealth = "111"
const val SetPregnancyCycle = "112"
const val GetPregnancyCycle = "113"
const val Getpeisu = "114"
const val GetpeisuER = "115"
const val CMD_Set_Name = "116"
const val CMD_Get_Name = "117"
const val Blood_glucose_status = "118"
const val Blood_glucose_data = "119"
const val FindActivityMode = "120"
const val FindMobilePhoneMode = "FindMobilePhoneMode"
const val RejectTelMode = "RejectTelMode"
const val TelMode = "TelMode"
const val ECGResult = "ECGResult"
const val ENTERECG = "ENTERECG"
}

@ -0,0 +1,37 @@
package com.jstyle.blesdk2301.constant
/**
* Created by Administrator on 2018/1/17.
*/
object DeviceConst {
const val CMD_SET_TIME = 0x01.toByte()
const val CMD_GET_TIME = 0x41.toByte()
const val CMD_Set_UseInfo = 0x02.toByte()
const val CMD_GET_USERINFO = 0x42.toByte()
const val CMD_Set_DeviceID = 0x05.toByte()
const val CMD_Enable_Activity = 0x09.toByte() //
const val CMD_Get_BatteryLevel = 0x13.toByte() //
const val CMD_Get_Address = 0x22.toByte()
const val CMD_Get_Version = 0x27.toByte()
const val CMD_Reset = 0x12.toByte()
const val CMD_Mcu_Reset = 0x2e.toByte()
const val CMD_Set_Auto = 0x2a.toByte()
const val CMD_Get_Auto = 0x2b.toByte()
const val CMD_Get_TotalData = 0x51.toByte() //
const val CMD_Get_DetailData = 0x52.toByte()
const val CMD_Get_SleepData = 0x53.toByte()
const val CMD_Get_HeartData = 0x54.toByte()
const val CMD_Get_OnceHeartData = 0x55.toByte()
const val CMD_Get_HrvTestData = 0x56.toByte() //
const val ReadTempHisrory = 0x62.toByte()
const val MeasurementWithType = 0x28.toByte()
const val Oxygen_data = 0x66.toByte()
const val CMD_Start_EXERCISE = 0x19.toByte()
const val CMD_heart_package = 0x17.toByte()
const val CMD_HeartPackageFromDevice = 0x18.toByte() //
const val CMD_Set_Name = 0x3d.toByte()
const val CMD_Get_Name = 0x3e.toByte()
const val CMD_Get_SPORTData = 0x5C.toByte()
const val CMD_Get_Bloodsugar = 0x78.toByte()
const val Bloodsugar_data = 0x3a.toByte() //血糖数据
}

@ -0,0 +1,373 @@
package com.jstyle.blesdk2301.constant
/**
* Created by Administrator on 2018/4/10.
*/
object DeviceKey {
const val heartValue = "heartValue"
const val hrvValue = "hrvValue"
const val Quality = "Quality"
const val HangUp = "HangUp"
const val Telephone = "Telephone"
const val Photograph = "Photograph"
const val CanclePhotograph = "CanclePhotograph"
const val type = "type"
const val Play = "Play"
const val Suspend = "Suspend"
const val LastSong = "LastSong"
const val NextSong = "NextSong"
const val VolumeReduction = "VolumeReduction"
const val VolumeUp = "VolumeUp"
const val FindYourPhone = "FindYourPhone"
const val Cancle_FindPhone = "Cancle_FindPhone"
const val SOS = "SOS"
const val DataType = "dataType"
const val enterActivityModeSuccess = "enterActivityModeSuccess"
const val Type = "Type"
const val Status = "Status"
const val RRIntervalData = "RRIntervalData"
const val Manual = "Manual"
const val automatic = "automatic"
const val Data = "dicData"
const val End = "dataEnd"
const val index = "index"
const val scanInterval = "scanInterval"
const val scanTime = "scanTime"
const val signalStrength = "signalStrength"
const val arrayX = "arrayX"
const val arrayY = "arrayY"
const val arrayZ = "arrayZ"
const val arrayPpgRawData = "arrayPpgRawData"
const val KGpsResCheck0 = "KGpsResCheck0" // 设备时间 GET_DEVICE_Time
const val KGpsResCheck1 = "KGpsResCheck1" // 设备时间
const val Band = "Band"
const val KFinishFlag = "finish"
const val DeviceTime = "strDeviceTime" // 设备时间 GET_DEVICE_Time
const val GPSTime = "gpsExpirationTime" // 设备时间 GET_DEVICE_Time
const val TimeZone = "TimeZone" // 设备时间 GET_DEVICE_Time
const val KHrvBloodHighPressure = "KHrvBloodHighPressure"
const val KHrvBloodLowPressure = "KHrvBloodLowPressure"
/*
* GET_PERSONAL_INFO
* sex 性别
* Age 年龄
* Height 身高
* Weight 体重
* stepLength 步长
* deviceId 设备ID
*/
const val Gender = "MyGender"
const val Age = "MyAge"
const val Height = "MyHeight"
const val Weight = "MyWeight"
const val Stride = "MyStride"
const val KUserDeviceId = "deviceId"
/*
* GET_DEVICE_INFO
* distanceUnit 距离单位
* hourState 12小时24小时显示
* handleEnable 抬手检查使能标志
* handleSign 抬手检测左右手标志
* screenState 横竖屏显示
* anceEnable ANCS使能开关
*/
const val DistanceUnit = "distancUnit"
const val TimeUnit = "timeUnit"
const val TempUnit = "temperatureUnit"
const val WristOn = "wristOn"
const val TemperatureUnit = "TemperatureUnit"
const val NightMode = "NightMode"
const val LeftOrRight = "handleSign"
//public static final String ScreenShow = "screenState";
const val Dialinterface = "dialinterface"
const val SocialDistancedwitch = "SocialDistancedwitch"
const val ChineseOrEnglish = "ChineseOrEnglish"
const val Lauage = "Lauage"
const val ScreenBrightness = "dcreenBrightness"
const val KBaseHeart = "baseHeartRate"
const val isHorizontalScreen = "isHorizontalScreen"
const val Year = "Year"
const val Month = "Month"
const val Day = "Day"
const val MenstrualPeriod_Lenth = "MenstrualPeriod_Lenth"
const val MenstrualPeriod_Period = "MenstrualPeriod_Period"
/*
* SET_STEP_MODEL
*totalSteps 总步数
*calories 卡路里
*distance 距离
*time 时间
*heartValue 心率值
*/
const val Step = "step"
const val Calories = "calories"
const val Distance = "distance"
const val ExerciseMinutes = "exerciseMinutes"
const val HeartRate = "heartRate"
const val ActiveMinutes = "ExerciseTime"
const val TempData = "TempData"
const val StepGoal = "stepGoal" // 目标步数值 GET_GOAL
const val BatteryLevel = "batteryLevel" // 电量级别 READ_DEVICE_BATTERY
const val Chargingstate = "Chargingstate" // 充电状态
const val Voltage_value = "VoltageValue" // 电压值
const val MacAddress = "macAddress" // MAC地址 READ_MAC_ADDRESS
const val DeviceVersion = "deviceVersion" // 版本号 READ_VERSION
const val DeviceName = "deviceName" // 设备名称 GET_DEVICE_NAME
const val TemperatureCorrectionValue = "TemperatureCorrectionValue" // 设备名称 GET_DEVICE_NAME
/*
* GET_AUTOMIC_HEART
*workModel 工作模式
*heartStartHour 开始运动时间的小时
*heartStartMinter 开始运动时间的分钟
*heartEndHour 结束运动时间的小时
*heartEndMinter 结束运动时间的分钟
*heartWeek 星期使能
*workTime 工作模式时间
*/
const val WorkMode = "workModel"
const val StartTime = "heartStartHour"
const val KHeartStartMinter = "heartStartMinter"
const val EndTime = "heartEndHour"
const val KHeartEndMinter = "heartEndMinter"
const val Weeks = "weekValue"
const val IntervalTime = "intervalTime"
const val Time = "Time"
const val PPG = "PPG"
/*
* READ_SPORT_PERIOD
*StartTimeHour 开始运动时间的小时
*StartTimeMin 开始运动时间的分钟
*EndTimeHour 结束运动时间的小时
*EndTimeMin 结束运动时间的分钟
*Week 星期使能
*KSportNotifierTime 运动提醒周期
*/
const val StartTimeHour = "sportStartHour"
const val StartTimeMin = "sportStartMinter"
const val EndTimeHour = "sportEndHour"
const val EndTimeMin = "sportEndMinter"
const val LeastSteps = "leastSteps"
/*
* GET_STEP_DATA
*historyDate 日期年月日
*historySteps 步数
*historyTime 运动时间
*historyDistance 距离
*Calories 卡路里
*historyGoal 目标
*/
const val Date = "date"
const val Size = "size"
const val Goal = "goal"
/*
* GET_STEP_DETAIL
*Date 日期年月日时分秒
*ArraySteps 步数
*Calories 卡路里
*Distance 距离
*KDetailMinterStep 10分钟内每一分钟的步数
*/
const val ArraySteps = "arraySteps"
const val KDetailMinterStep = "detailMinterStep"
const val temperature = "temperature"
const val axillaryTemperature = "axillaryTemperature"
/*
* GET_SLEEP_DETAIL
*Date 日期年月日时分秒
*KSleepLength 睡眠数据的长度
*ArraySleep 5分钟的睡眠质量 (总共24个数据每一个数据代表五分钟)
*/
const val KSleepLength = "sleepLength"
const val ArraySleep = "arraySleepQuality"
const val sleepUnitLength = "sleepUnitLength" //是不是一分钟的睡眠数据 1为1分钟数据 0为5分钟数据
/*
* GET_HEART_DATA
*Date 日期年月日时分秒
*ArrayDynamicHR 10秒一个心率值总共12个心率值
*/
const val ArrayDynamicHR = "arrayDynamicHR"
const val Blood_oxygen = "Blood_oxygen"
/*
* GET_ONCE_HEARTDATA
*Date 日期年月日时分秒
*StaticHR 心率值
*/
const val StaticHR = "onceHeartValue"
/*
* GET_HRV_DATA
*Date 日期年月日时分秒
*HRV HRV值
*VascularAging 血管老化度值
*HeartRate 心率值
*Stress 疲劳度
*/
const val HRV = "hrv"
const val VascularAging = "vascularAging"
const val Fatiguedegree = "fatigueDegree"
const val Stress = "stress"
const val HighPressure = "highPressure"
const val LowPressure = "lowPressure"
const val highBP = "highBP"
const val lowBP = "lowBP"
/*
*GET_ALARM
*KAlarmId 0到4闹钟编号
*ClockType 闹钟类型
*ClockTime 闹钟时间的小时
*KAlarmMinter 闹钟时间的分钟
*Week 星期使能
*KAlarmLength 长度
*KAlarmContent 文本的内容
*/
const val KAlarmId = "alarmId"
const val OpenOrClose = "clockOpenOrClose"
const val ClockType = "clockType"
const val ClockTime = "alarmHour"
const val KAlarmMinter = "alarmMinter"
const val Week = "weekValue"
const val KAlarmLength = "alarmLength"
const val KAlarmContent = "dicClock"
/***********************GET_HRV_TESTDATA */ /*
*KBloodTestLength 数据长度
*KBloodTestProgress 进度
*KBloodTestValue 本次PPG获得的值
*KBolldTestCurve 本次波型的高度
*/
const val KBloodTestLength = "bloodTestLength"
const val KBloodTestProgress = "bloodTestProgress"
const val KBloodTestValue = "bloodTestValue"
const val KBloodTestCurve = "bloodTestCurve"
/*
*KBloodResultPercent 反弹的百分比
*KBloodResultRebound 平均反弹高度
*KBloodResultMax 最大高度
*KBloodResultRank 结果级别1到6
*/
const val KBloodResultPercent = "bloodPercent"
const val KBloodResultRebound = "bloodRebound"
const val KBloodResultMax = "bloodResultMax"
const val KBloodResultRank = "bloodResultRank"
/*
*KHrvTestProgress 进度
*KHrvTestWidth 本次心跳的宽度
*KHrvTestValue 心率值
*/
const val KHrvTestProgress = "hrvTestProgress"
const val KHrvTestWidth = "hrvTestWidth"
const val KHrvTestValue = "hrvTestValue"
/*
*KHrvResultState SDNN结果 如果是0,说明检测失败
*KHrvResultAvg SDNN平均值
*KHrvResultTotal 总SDNN结果
*KHrvResultCount 有效数据个数
*KHrvResultTired 疲劳指数据
*KHrvResultValue 心率值
*/
const val KHrvResultState = "hrvResultState"
const val KHrvResultAvg = "hrvResultAvg"
const val KHrvResultTotal = "hrvResultTotal"
const val KHrvResultCount = "hrvResultCount"
const val KHrvResultTired = "hrvResultTired"
const val KHrvResultValue = "hrvResultValue"
/*
*KDisturbState 1:开始运动 0停止运动
*KSlipHand 1: 带在手上 0;脱手
*KPPGData PPG的波型值
*/
const val KDisturbState = "disturbState"
const val KSlipHand = "slipHand"
const val KPPGData = "ppgData"
const val KPPIData = "ppiData"
const val ppgResult = "ppgResult"
const val ppgStartSucessed = "ppgStartSucessed"
const val ppgStartFailed = "ppgStartFailed"
const val ppgStop = "ppgStop"
const val ppgQuit = "ppgQuit"
const val ppgMeasurementProgress = "ppgMeasurementProgress"
/*
*@param Date 时间年月日时分秒
*@param Latitude 纬度数据
*@param Longitude 经度数据
*/
const val Latitude = "locationLatitude"
const val Longitude = "locationLongitude"
const val KActivityLocationTime = "ActivityLocationTIme"
const val KActivityLocationLatitude = "ActivityLocationLatitude"
const val KActivityLocationLongitude = "ActivityLocationLongitude"
const val KActivityLocationCount = "KActivityLocationCount"
/*
* GET_SPORTMODEL_DATA
*@param Date 时间年月日时分秒
*@param ActivityMode 运动类型
0=Run,
1=Cycling,
2=Swimming,
3=Badminton,
4=Football,
5=Tennis,
6=Yoga,
7=Medication,
8=Dance
*@param HeartRate 心率
*@param ActiveMinutes 运动时间
*@param Step 运动步数
*@param Pace 运动速度
*@param Calories 卡路里
*@param Distance 距离
*/
const val ActivityMode = "sportModel"
const val Pace = "sportModelSpeed"
const val KDataID = "KDataID"
const val KPhoneDataLength = "KPhoneDataLength"
const val KClockLast = "KClockLast"
const val TakePhotoMode = "TakePhotoMode"
const val KFunction_tel = "TelMode"
const val KFunction_reject_tel = "RejectTelMode"
const val FindMobilePhoneMode = "FindMobilePhoneMode"
const val KEnable_exercise = "KEnable_exercise"
const val ECGQualityValue = "ECGQualityValue"
const val ECGResultValue = "ECGResultVALUE"
const val ECGHrvValue = "ECGHrvValue"
const val ECGAvBlockValue = "ECGAvBlockValue"
const val ECGHrValue = "ECGHrValue"
const val PPGHrValue = "PPGHrValue"
const val ECGStreesValue = "ECGStreesValue"
const val ECGhighBpValue = "ECGhighBpValue"
const val ECGLowBpValue = "ECGLowBpValue"
const val ECGMoodValue = "ECGMoodValue"
const val ECGBreathValue = "ECGBreathValue"
const val KEcgDataString = "KEcgDataString" // ecg
const val ECGValue = "ECGValue"
const val PPGValue = "PPGValue"
const val EcgStatus = "EcgStatus"
const val EcgSBP = "PPGSBP"
const val EcgDBP = "PPGDBP"
const val EcgHR = "PPGHR"
const val WaveformDownTime = "WaveformDownTime"
const val WaveformRiseTime = "WaveformRiseTime"
const val EcgGender = "Gender"
const val EcgAge = "Age"
const val EcgHeight = "Height"
const val EcgWeight = "Weight"
}

@ -0,0 +1,5 @@
package com.jstyle.blesdk2301.model
enum class AutoMode {
AutoHeartRate, AutoSpo2, AutoTemp, AutoHrv
}

@ -0,0 +1,5 @@
package com.jstyle.blesdk2301.model
enum class AutoTestMode {
AutoHeartRate, AutoSpo2
}

@ -0,0 +1,35 @@
package com.jstyle.blesdk2301.model
import java.io.Serializable
/**
* Created by Administrator on 2018/1/16.
*/
class Clock : SendData(), Serializable {
var number = 0
var type = 0
var hour = 0
var minute = 0
var week: Byte = 0
var content: String? = null
var isEnable = false
fun srgetWeek(): Int {
return week.toInt()
}
fun srsetWeek(week: Byte) {
this.week = week
}
override fun toString(): String {
return "Clock{" +
"number=" + number +
", type=" + type +
", hour=" + hour +
", minute=" + minute +
", week=" + week +
", content='" + content + '\'' +
", enable=" + isEnable +
'}'
}
}

@ -0,0 +1,50 @@
package com.jstyle.blesdk2301.model
import android.bluetooth.BluetoothDevice
import java.io.Serializable
import java.util.concurrent.ScheduledThreadPoolExecutor
class Device : Serializable {
var name: String? = null //设备名字
var mac: String? = null //设备的mac
var productID = 0 //产品id,预留
var bluetoothDevice: BluetoothDevice? = null //蓝牙
var isIsconted = false //蓝牙是否连接
var isPaired = false //是否是配对设备
var isIsdfu = false //是否直接升级
var riss = 100
var time: ScheduledThreadPoolExecutor? = null //每一个设备轮询器
fun srsetIsdfu(isdfu: Boolean) {
isIsdfu = isdfu
}
fun srsetIsconted(isconted: Boolean) {
isIsconted = isconted
}
fun srgetName(): String {
return if (name == null) "" else name!!
}
fun srsetName(name: String?) {
this.name = name
}
fun srgetMac(): String {
return if (mac == null) "" else mac!!
}
fun srsetMac(mac: String?) {
this.mac = mac
}
override fun toString(): String {
return "Device{" +
"name='" + name + '\'' +
", mac='" + mac + '\'' +
", productID=" + productID +
", getBluetoothDevice=" + bluetoothDevice +
", isconted=" + isIsconted +
'}'
}
}

@ -0,0 +1,9 @@
package com.jstyle.blesdk2301.model
/**
* Created by Administrator on 2018/4/28.
*/
class DeviceBean {
var dataList: List<Map<String, String>>? = null
var isFinish = false
}

@ -0,0 +1,8 @@
package com.jstyle.blesdk2301.model
/**
* Created by Administrator on 2018/4/9.
*/
class DeviceName : SendData() {
var name: String? = null
}

@ -0,0 +1,41 @@
package com.jstyle.blesdk2301.model
/**
* Created by Administrator on 2018/8/2.
*/
class ExerciseMode : SendData() {
var exerciseMode = 0
var enableStatus = 0
fun getExerciseMode(position: Int): Int {
return modes[position]
}
companion object {
const val Status_START = 1
const val Status_PAUSE = 2
const val Status_CONTUINE = 3
const val Status_FINISH = 4
const val Mode_RUN = 0
const val Mode_CYCLING = 1
const val Mode_BADMINTON = 2
const val Mode_FOOTBALL = 3
const val Mode_TENNIS = 4
const val Mode_YOGA = 5
const val Mode_BREATH = 6
const val Mode_DANCE = 7
const val Mode_BASKETBALL = 8
const val Mode_Walk = 9
const val Mode_workout = 10
const val Mode_Cricket = 11
const val Mode_Hiking = 12
const val Mode_Aerobics = 13
const val Mode_PingPong = 14
const val Mode_RopeJump = 15
const val Mode_Situps = 16
const val Volleyball = 17
var modes = intArrayOf(
Mode_RUN, Mode_CYCLING, Mode_BADMINTON, Mode_FOOTBALL,
Mode_TENNIS, Mode_YOGA, Mode_BREATH, Mode_DANCE, Mode_BASKETBALL, Mode_Walk, Mode_workout, Mode_Cricket, Mode_Hiking, Mode_Aerobics, Mode_PingPong, Mode_RopeJump, Mode_Situps, Volleyball
)
}
}

@ -0,0 +1,53 @@
/*
* Copyright (c) 2015, Nordic Semiconductor
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jstyle.blesdk2301.model
import android.bluetooth.BluetoothDevice
class ExtendedBluetoothDevice {
val device: BluetoothDevice
/** The name is not parsed by some Android devices, f.e. Sony Xperia Z1 with Android 4.3 (C6903). It needs to be parsed manually. */
var name: String
var rssi: Int
constructor(device: BluetoothDevice, name: String, rssi: Int) {
this.device = device
this.name = name
this.rssi = rssi
}
constructor(device: BluetoothDevice) {
this.device = device
name = device.name
rssi = NO_RSSI
}
fun matches(mdevice: BluetoothDevice): Boolean {
return device.address == mdevice.address
}
companion object {
/* package */
const val NO_RSSI = -1000
}
}

@ -0,0 +1,16 @@
package com.jstyle.blesdk2301.model
/**
* Created by Administrator on 2018/4/9.
*/
class GetData : SendData() {
/**
* 99删除数据0获取数据
*/
var dataNum = DataNum_Last
companion object {
const val DataNum_Delete = 0x99.toByte()
const val DataNum_Last = 0
}
}

@ -0,0 +1,27 @@
package com.jstyle.blesdk2301.model
/**
* Created by Administrator on 2018/1/16.
*/
class MyAutomaticHRMonitoring : SendData() {
var open = 0 //1 开启整个时间段都测量 2时间段内间隔测量 0关闭
// 1. Enable measurement throughout the entire time period 2. Measure intervals within the time period 0. Close
var startHour = 0 //开始小时 Starting hours
var startMinute = 0 //开始分钟 Start minute
var endHour = 0 //结束小时 End Hour
var endMinute = 0 //结束分钟 End minute
var week = 0 //星期一到星期日 开启选择 Monday to Sunday open selection
var time = 0 //多少时间测试一次,单位是分钟。 How many times does it take to test, in minutes.
override fun toString(): String {
return "MyAutomaticHRMonitoring{" +
"open=" + open +
", startHour=" + startHour +
", startMinute=" + startMinute +
", endHour=" + endHour +
", endMinute=" + endMinute +
", week=" + week +
", time=" + time +
'}'
}
}

@ -0,0 +1,22 @@
package com.jstyle.blesdk2301.model
/**
* Created by Administrator on 2018/4/9.
*/
class MyDeviceInfo : SendData() {
var isDistanceUnit = false //1 miletrue,0km(false)
var isIs12Hour = false //112小时true024小时制(false)
var isBright_screen = false //1 turn on the bright screen, 0 turn off the bright screen
var isFahrenheit_or_centigrade = false //Fahrenheit or centigrade
var isHorizontalScreen = false //1 Horizontal screen, 0 Vertical screen
var isNight_mode = false //夜间模式
var isTemperature_unit = false //夜间模式
var isSocial_distance_switch = false //社交距离开关 Social distance switch
var lauageNumber = -1 //中英文切换 Chinese_English_switch
var baseheart = 60 //Basic heart rate
var screenBrightness = -1 //Screen brightness 屏幕亮度0-5
var dialinterface = -1 //表盘更换 Dial replacement 0-10
fun srsetIs12Hour(is12Hour: Boolean) {
isIs12Hour = is12Hour
}
}

@ -0,0 +1,36 @@
package com.jstyle.blesdk2301.model
import java.util.Calendar
/**
* Created by Administrator on 2018/1/16.
*/
class MyDeviceTime : SendData() {
var year: Int
var month: Int
var day: Int
var hour: Int
var minute: Int
var second: Int
init {
val calendar = Calendar.getInstance()
year = calendar[Calendar.YEAR]
month = calendar[Calendar.MONTH] + 1
day = calendar[Calendar.DAY_OF_MONTH]
hour = calendar[Calendar.HOUR_OF_DAY]
minute = calendar[Calendar.MINUTE]
second = calendar[Calendar.SECOND]
}
override fun toString(): String {
return "MyDeviceTime{" +
"year=" + year +
", month=" + month +
", day=" + day +
", hour=" + hour +
", minute=" + minute +
", second=" + second +
'}'
}
}

@ -0,0 +1,21 @@
package com.jstyle.blesdk2301.model
/**
* Created by Administrator on 2018/1/16.
*/
class MyPersonalInfo : SendData() {
var sex = 0 //1 male,0female
var age = 0
var height = 0
var weight = 0
var stepLength = 70
override fun toString(): String {
return "MyPersonalInfo{" +
"sex=" + sex +
", age=" + age +
", height=" + height +
", weight=" + weight +
", stepLength=" + stepLength +
'}'
}
}

@ -0,0 +1,27 @@
package com.jstyle.blesdk2301.model
/**
* Created by Administrator on 2018/1/16.
*/
class MySedentaryReminder : SendData() {
var startHour = 0
var startMinute = 0
var endHour = 0
var endMinute = 0
var week = 0
var intervalTime = 0
var leastStep = 0
var isEnable = false
override fun toString(): String {
return "MySedentaryReminder{" +
"startHour=" + startHour +
", startMinute=" + startMinute +
", endHour=" + endHour +
", endMinute=" + endMinute +
", week=" + week +
", intervalTime=" + intervalTime +
", leastStep=" + leastStep +
", enable=" + isEnable +
'}'
}
}

@ -0,0 +1,33 @@
package com.jstyle.blesdk2301.model
/**
* Created by Administrator on 2018/1/16.
*/
class Notifier : SendData() {
var type = 0
var info = ""
var title = ""
override fun toString(): String {
return "Notifier{" +
"type=" + type +
", info='" + info + '\'' +
", title='" + title + '\'' +
'}'
}
companion object {
const val Data_Tel = 0
const val Data_Sms = 1
const val Data_WeChat = 2
const val Data_Facebook = 3
const val Data_Instagram = 4
const val Data_Skype = 5
const val Data_Telegram = 6
const val Data_Twitter = 7
const val Data_Vkclient = 8
const val Data_WhatApp = 9
const val Data_QQ = 10
const val Data_IN = 11
const val Data_Stop_Tel = 0xff
}
}

@ -0,0 +1,36 @@
package com.jstyle.blesdk2301.model
/**
* 怀孕周期
* 算法 开始到生产 280 每7天算一周
*/
class PregnancyCycle {
var address = ""
var userId = ""
var menstrualPeriod_StartTime = "1990-01-01" //经期开始时间 yyyy-MM-dd
var dueDateTime = "" //预产期
var menstrualPeriod_Period: Long = 30 //经期周期默认30天 21-35
constructor()
constructor(
address: String, userId: String,
MenstrualPeriod_StartTime: String, DueDateTime: String,
MenstrualPeriod_Period: Long
) {
this.address = address
this.userId = userId
menstrualPeriod_StartTime = MenstrualPeriod_StartTime
dueDateTime = DueDateTime
menstrualPeriod_Period = MenstrualPeriod_Period
}
override fun toString(): String {
return "PregnancyCycle{" +
"address='" + address + '\'' +
", userId='" + userId + '\'' +
", MenstrualPeriod_StartTime='" + menstrualPeriod_StartTime + '\'' +
", DueDateTime='" + dueDateTime + '\'' +
", MenstrualPeriod_Period=" + menstrualPeriod_Period +
'}'
}
}

@ -0,0 +1,6 @@
package com.jstyle.blesdk2301.model
/**
* Created by Administrator on 2018/4/8.
*/
open class SendData

@ -0,0 +1,16 @@
package com.jstyle.blesdk2301.model
/**
* Created by Administrator on 2018/1/16.
*/
class SportPeriod : SendData() {
var startHour = 0
var startMinute = 0
var endHour = 0
var endMinute = 0
var week = 0
var days = 0
var intervalTime = 0
var leastStep = 0
var isEnable = false
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save