diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml
new file mode 100644
index 0000000..4a53bee
--- /dev/null
+++ b/.idea/AndroidProjectSystem.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..639c779
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/migrations.xml b/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..74dd639
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/.~lock.CS_BIAS_V2.3.5标准样本.xlsx# b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/.~lock.CS_BIAS_V2.3.5标准样本.xlsx#
new file mode 100644
index 0000000..7052658
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/.~lock.CS_BIAS_V2.3.5标准样本.xlsx#
@@ -0,0 +1 @@
+,prathiyuman,csh-machine-2,10.12.2025 12:58,file:///home/prathiyuman/.config/libreoffice/4;
\ No newline at end of file
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/CS-BIAS-V2.3.5_1_APP库API使用说明.pdf b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/CS-BIAS-V2.3.5_1_APP库API使用说明.pdf
new file mode 100644
index 0000000..94fe595
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/CS-BIAS-V2.3.5_1_APP库API使用说明.pdf differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/CS_BIAS_V2.3.5标准样本.xlsx b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/CS_BIAS_V2.3.5标准样本.xlsx
new file mode 100644
index 0000000..9a52b23
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/CS_BIAS_V2.3.5标准样本.xlsx differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/CS_BIAS_V2.3.5算法用户手册.pdf b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/CS_BIAS_V2.3.5算法用户手册.pdf
new file mode 100644
index 0000000..15b4c70
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/CS_BIAS_V2.3.5算法用户手册.pdf differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/OKOK健康最新指标标准 (已经旧了,可参考).pdf b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/OKOK健康最新指标标准 (已经旧了,可参考).pdf
new file mode 100644
index 0000000..845bb03
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/OKOK健康最新指标标准 (已经旧了,可参考).pdf differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android.zip b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android.zip
new file mode 100644
index 0000000..357bea4
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android.zip differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.gitignore b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.gitignore
new file mode 100644
index 0000000..fd45b12
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.gitignore
@@ -0,0 +1,11 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches/build_file_checksums.ser
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.idea/codeStyles/Project.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..30aa626
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.idea/codeStyles/Project.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.idea/gradle.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.idea/gradle.xml
new file mode 100644
index 0000000..7ac24c7
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.idea/misc.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.idea/misc.xml
new file mode 100644
index 0000000..b0c7b20
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.idea/misc.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.idea/runConfigurations.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/.gitignore b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/build.gradle b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/build.gradle
new file mode 100644
index 0000000..0feed7e
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/build.gradle
@@ -0,0 +1,35 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 28
+ defaultConfig {
+ applicationId "com.example.chipsea.demo235_android"
+ minSdkVersion 15
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ sourceSets {
+ main {
+ jniLibs.srcDirs = ['libs']
+ }
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ 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'
+}
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/arm64-v8a/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/arm64-v8a/libchipsea_bias_v235.so
new file mode 100644
index 0000000..92b23a3
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/arm64-v8a/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/armeabi-v7a/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/armeabi-v7a/libchipsea_bias_v235.so
new file mode 100644
index 0000000..9502a24
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/armeabi-v7a/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/armeabi/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/armeabi/libchipsea_bias_v235.so
new file mode 100644
index 0000000..55f1639
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/armeabi/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/mips/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/mips/libchipsea_bias_v235.so
new file mode 100644
index 0000000..76f8e8d
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/mips/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/mips64/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/mips64/libchipsea_bias_v235.so
new file mode 100644
index 0000000..5363dd2
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/mips64/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/x86/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/x86/libchipsea_bias_v235.so
new file mode 100644
index 0000000..29d7b4e
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/x86/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/x86_64/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/x86_64/libchipsea_bias_v235.so
new file mode 100644
index 0000000..ca35c74
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/libs/x86_64/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/proguard-rules.pro b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/androidTest/java/com/example/chipsea/demo235_android/ExampleInstrumentedTest.java b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/androidTest/java/com/example/chipsea/demo235_android/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..f504fa9
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/androidTest/java/com/example/chipsea/demo235_android/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.chipsea.demo235_android;
+
+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 Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.chipsea.demo235_android", appContext.getPackageName());
+ }
+}
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/AndroidManifest.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..927865f
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/java/chipsea/bias/v235/CSBiasAPI.java b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/java/chipsea/bias/v235/CSBiasAPI.java
new file mode 100644
index 0000000..f4e1d91
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/java/chipsea/bias/v235/CSBiasAPI.java
@@ -0,0 +1,119 @@
+package chipsea.bias.v235;
+
+/**
+ * Created by liangyc
+ * Time :2018/11/26
+ * Des:
+ */
+
+/*
+测试数据
+身高, 体重,阻抗,性别, 年龄
+{170, 500, 4080, 1, 30},
+{170, 1000, 4280, 1, 30},
+{170, 1500, 4480, 1, 30},
+{170, 500, 4080, 0, 30},
+{170, 1000, 4280, 0, 30},
+{170, 1500, 4480, 0, 30},
+{170, 509, 4547, 1, 28},
+{164, 790, 3797, 1, 28},
+{174, 669, 4221, 1, 24},
+{158, 603, 4388, 0, 21},
+{163, 474, 4759, 0, 22},
+{160, 553, 4549, 1, 26},
+*/
+/*
+测试结果
+BFP SLM BWP BMC VFR PP SMM BMR BMI SBW MC WC FC age score
+5.0 45.3 62.9 2.2 1.0 27.7 26.0 1324 17.3 62.3 4.2 12.3 8.1 15 60
+33.0 64.8 50.2 2.3 20.5 14.5 34.8 1981 34.6 62.3 - 15.3 - 37.7 - 22.4 56 50
+42.7 84.2 46.0 1.7 41.5 10.1 43.5 2639 51.9 62.3 - 34.2 - 87.7 - 53.5 80 50
+15.3 40.4 55.6 1.9 1.0 25.3 23.6 1239 17.3 60.4 3.0 10.4 7.4 15 66
+45.0 51.0 42.6 4.0 13.5 8.4 32.3 1737 34.6 60.4 - 9.7 - 39.6 - 29.9 80 49
+45.0 78.5 38.3 4.0 26.5 14.0 41.1 2235 51.9 60.4 - 37.2 - 89.5 - 52.4 80 50
+6.1 44.7 61.4 3.1 1 26.5 24.9 1318 17.6 62.3 3.9 11.4 7.5 15 63
+27 55.7 53.5 1.9 12 17.1 30.7 1692 29.4 58 - 9.5 - 21 - 11.5 37 56
+16.6 53.1 57 2.7 5 22.4 29.9 1598 22.1 65.3 - 1.6 - 1.6 0 21 86
+32.4 38.2 48.8 2.6 4.5 14.5 21.7 1269 24.2 52.2 - 1.6 - 8.1 - 6.5 33 68
+18.4 36.3 54 2.3 1 22.6 19.5 1153 17.8 55.6 3 8.2 5.2 15 70
+*/
+
+public class CSBiasAPI {
+
+ public static final int CSBIAS_OK = 0;
+ public static final int CSBIAS_ERR_WEIGTH = -2;
+ public static final int CSBIAS_ERR_HEIGHT = -3;
+ public static final int CSBIAS_ERR_AGE = -4;
+ public static final int CSBIAS_ERR_SEX = -5;
+ public static final int CSBIAS_ERR_IMPEDANCE = -6;
+ public static final int CSBIAS_ERR_MODE = -7;
+ public static final int CSBIAS_ERR_VCODE = -8;
+
+ static {
+ System.loadLibrary("chipsea_bias_v235");
+ }
+
+ /*
+ 人体成分算法
+ - mode 模式,默认为0
+ - sex 性别, 1男, 0女
+ - age 年龄,取值在18 ~ 99岁之间
+ - height 身高, 取值在90 ~ 220之间,表示90 ~ 220厘米.
+ - weight 体重,取值在200 ~ 1500之间,表示20公斤~150公斤.
+ - impedance 阻抗值, 取值在2000 ~ 15000.
+ - vkeyCode 指纹验证中的验证码
+ */
+ public static native CSBiasV235Resp cs_bias_v235(int mode, int sex, int age, int height, int weight, int impedance, int vkeyCode);
+
+ /**
+ * Created by liangyc
+ * Time :2018/11/26
+ * Des:
+ */
+ public static class CSBiasDataV235 {
+ //体脂率
+ public double BFP;
+ //肌肉量
+ public double SLM;
+ //骨盐量
+ public double BMC;
+ //体水分率
+ public double BWP;
+ //蛋白质率
+ public double PP;
+ //骨骼肌量
+ public double SMM;
+ //内脏脂肪等级
+ public double VFR;
+ //身体质量指数
+ public double BMI;
+ //标准体重
+ public double SBW;
+ //肌肉控制
+ public double MC;
+ //体重控制
+ public double WC;
+ //脂肪控制
+ public double FC;
+ //基础代谢率
+ public int BMR;
+ //身体年龄
+ public int MA;
+ //身体得分
+ public int SBC;
+
+ }
+
+ /**
+ * Created by liangyc
+ * Time :2018/11/26
+ * Des:
+ */
+ public static class CSBiasV235Resp {
+ public int result;
+
+ public CSBiasDataV235 data;
+
+
+ }
+}
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/java/com/example/chipsea/demo235_android/MainActivity.java b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/java/com/example/chipsea/demo235_android/MainActivity.java
new file mode 100644
index 0000000..2cb9b13
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/java/com/example/chipsea/demo235_android/MainActivity.java
@@ -0,0 +1,119 @@
+package com.example.chipsea.demo235_android;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.RadioButton;
+import android.widget.TextView;
+import com.example.chipsea.demo235_android.R;
+import chipsea.bias.v235.CSBiasAPI;
+
+
+/*
+测试数据
+身高, 体重,阻抗,性别, 年龄
+{170, 500, 4080, 1, 30},
+{170, 1000, 4280, 1, 30},
+{170, 1500, 4480, 1, 30},
+{170, 500, 4080, 0, 30},
+{170, 1000, 4280, 0, 30},
+{170, 1500, 4480, 0, 30},
+{170, 509, 4547, 1, 28},
+{164, 790, 3797, 1, 28},
+{174, 669, 4221, 1, 24},
+{158, 603, 4388, 0, 21},
+{163, 474, 4759, 0, 22},
+{160, 553, 4549, 1, 26},
+*/
+/*
+测试结果
+BFP SLM BWP BMC VFR PP SMM BMR BMI SBW MC WC FC age score
+5.0 45.3 62.9 2.2 1.0 27.7 26.0 1324 17.3 62.3 4.2 12.3 8.1 15 60
+33.0 64.8 50.2 2.3 20.5 14.5 34.8 1981 34.6 62.3 - 15.3 - 37.7 - 22.4 56 50
+42.7 84.2 46.0 1.7 41.5 10.1 43.5 2639 51.9 62.3 - 34.2 - 87.7 - 53.5 80 50
+15.3 40.4 55.6 1.9 1.0 25.3 23.6 1239 17.3 60.4 3.0 10.4 7.4 15 66
+45.0 51.0 42.6 4.0 13.5 8.4 32.3 1737 34.6 60.4 - 9.7 - 39.6 - 29.9 80 49
+45.0 78.5 38.3 4.0 26.5 14.0 41.1 2235 51.9 60.4 - 37.2 - 89.5 - 52.4 80 50
+6.1 44.7 61.4 3.1 1 26.5 24.9 1318 17.6 62.3 3.9 11.4 7.5 15 63
+27 55.7 53.5 1.9 12 17.1 30.7 1692 29.4 58 - 9.5 - 21 - 11.5 37 56
+16.6 53.1 57 2.7 5 22.4 29.9 1598 22.1 65.3 - 1.6 - 1.6 0 21 86
+32.4 38.2 48.8 2.6 4.5 14.5 21.7 1269 24.2 52.2 - 1.6 - 8.1 - 6.5 33 68
+18.4 36.3 54 2.3 1 22.6 19.5 1153 17.8 55.6 3 8.2 5.2 15 70
+*/
+public class MainActivity extends AppCompatActivity {
+
+ private EditText txtHeight, txtAge, txtWeight, txtR;
+ private RadioButton radioMale;
+ private TextView txtTest;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ txtHeight = (EditText) findViewById(R.id.txtHeight);
+ txtAge = (EditText) findViewById(R.id.txtAge);
+ txtWeight = (EditText) findViewById(R.id.txtWeight);
+ txtR = (EditText) findViewById(R.id.txtR);
+ radioMale = (RadioButton) findViewById(R.id.radioMale);
+ txtTest=findViewById(R.id.txtTest);
+
+ }
+
+
+ public void newClick(View view) {
+ float height = Float.parseFloat(txtHeight.getText().toString());
+ int age = Integer.parseInt(txtAge.getText().toString());
+ float weight = Float.parseFloat(txtWeight.getText().toString());
+ float r = Float.parseFloat(txtR.getText().toString());
+ byte sex = 0;
+ if (radioMale.isChecked()) {
+ sex = 1;
+ }
+
+ CSBiasAPI.CSBiasV235Resp cSBiasV235Resp = CSBiasAPI.cs_bias_v235(0, sex, age,
+ (int) height, (int) (weight*10), (int) (r*10), 2018);
+
+ StringBuilder sb = new StringBuilder();
+
+ if (cSBiasV235Resp.result == CSBiasAPI.CSBIAS_OK) {
+ //计算
+ try {
+ sb.append("输入\r\n");
+ sb.append("性别:" + sex + " 身高:" + height + " 年龄:" + age + " 电阻:" + r + " 体重:" + weight + "\r\n");
+ sb.append("**************************************\r\n");
+ sb.append("**************************************\r\n");
+ sb.append("脂肪率%:" + cSBiasV235Resp.data.BFP + "\r\n");
+ sb.append("肌肉重kg:" + cSBiasV235Resp.data.SLM + "\r\n");
+ sb.append("水含量%:" + cSBiasV235Resp.data.BWP + "\r\n");
+ sb.append("骨盐量:" + cSBiasV235Resp.data.BMC + "\r\n");
+ sb.append("内脏脂肪等级:" + cSBiasV235Resp.data.VFR + "\r\n");
+ sb.append("蛋白质%:" + cSBiasV235Resp.data.PP+ "\r\n");
+ sb.append("骨骼肌kg:" + cSBiasV235Resp.data.SMM+ "\r\n");
+ sb.append("基础代谢:" + cSBiasV235Resp.data.BMR + "\r\n");
+ sb.append("身体质量指数:" + cSBiasV235Resp.data.BMI + "\r\n");
+ sb.append("标准体重kg:" + cSBiasV235Resp.data.SBW + "\r\n");
+ sb.append("肌肉控制:" + cSBiasV235Resp.data.MC + "\r\n");
+ sb.append("体重控制:" + cSBiasV235Resp.data.WC + "\r\n");
+ sb.append("脂肪控制:" + cSBiasV235Resp.data.FC + "\r\n");
+ sb.append("身体年龄:" + cSBiasV235Resp.data.MA + "\r\n");
+ sb.append("评分:" + cSBiasV235Resp.data.SBC + "\r\n");
+
+
+// sb.append("脂肪重:" + builderEx.getFM() +"\r\n");
+// sb.append("瘦体重kg:" + builderEx.getLBM() + "\r\n");
+// sb.append("水重kg:" + builderEx.getTF() + "\r\n");
+// sb.append("肥胖度:" + builderEx.getOD() + "\r\n");
+ sb.append("**************************************\r\n");
+
+// sb.append("反查电阻:" + CsAlgoBuilderEx.getResistance(100f,(byte)0,38.0f,18,20.2f));
+ } catch (Exception ex) {
+ sb.append("输入错误,错误码:" + ex.getLocalizedMessage());
+ }
+ } else {
+ sb.append("输入错误,错误码:" + cSBiasV235Resp.result);
+ }
+ txtTest.setText(sb.toString());
+ }
+}
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..1f6bb29
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/drawable/ic_launcher_background.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..0d025f9
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/layout/activity_main.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..f862c5a
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,154 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..898f3ed
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dffca36
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..64ba76f
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dae5e08
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..e5ed465
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..14ed0af
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b0907ca
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..d8ae031
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..2c18de9
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..beed3cd
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/values/colors.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..69b2233
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #008577
+ #00574B
+ #D81B60
+
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/values/strings.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..4f09399
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Demo235_Android
+
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/values/styles.xml b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/test/java/com/example/chipsea/demo235_android/ExampleUnitTest.java b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/test/java/com/example/chipsea/demo235_android/ExampleUnitTest.java
new file mode 100644
index 0000000..a0bb104
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/app/src/test/java/com/example/chipsea/demo235_android/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.chipsea.demo235_android;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/build.gradle b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/build.gradle
new file mode 100644
index 0000000..4e8009d
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/build.gradle
@@ -0,0 +1,27 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.2.0'
+
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradle.properties b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradle.properties
new file mode 100644
index 0000000..1487463
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradle.properties
@@ -0,0 +1,14 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradle/wrapper/gradle-wrapper.jar b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..f6b961f
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradle/wrapper/gradle-wrapper.properties b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..9a4163a
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradlew b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradlew
new file mode 100644
index 0000000..cccdd3d
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradlew.bat b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/settings.gradle b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/Demo_Android/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/arm64-v8a/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/arm64-v8a/libchipsea_bias_v235.so
new file mode 100644
index 0000000..92b23a3
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/arm64-v8a/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/armeabi-v7a/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/armeabi-v7a/libchipsea_bias_v235.so
new file mode 100644
index 0000000..9502a24
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/armeabi-v7a/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/armeabi/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/armeabi/libchipsea_bias_v235.so
new file mode 100644
index 0000000..55f1639
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/armeabi/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/mips/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/mips/libchipsea_bias_v235.so
new file mode 100644
index 0000000..76f8e8d
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/mips/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/mips64/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/mips64/libchipsea_bias_v235.so
new file mode 100644
index 0000000..5363dd2
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/mips64/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/x86/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/x86/libchipsea_bias_v235.so
new file mode 100644
index 0000000..29d7b4e
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/x86/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/x86_64/libchipsea_bias_v235.so b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/x86_64/libchipsea_bias_v235.so
new file mode 100644
index 0000000..ca35c74
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/android/libs/x86_64/libchipsea_bias_v235.so differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/ios.zip b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/ios.zip
new file mode 100644
index 0000000..7f298e6
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/ios.zip differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/人体成分含义及判定标准-BIAS-2.3.5.pdf b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/人体成分含义及判定标准-BIAS-2.3.5.pdf
new file mode 100644
index 0000000..8397bca
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/2406 - Ivy SDK for EBS7007E/人体成分含义及判定标准-BIAS-2.3.5.pdf differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/25-26 Sagar Incentive.xlsx b/app/2406 - Ivy SDK for EBS7007E/25-26 Sagar Incentive.xlsx
new file mode 100644
index 0000000..93ee7d7
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/25-26 Sagar Incentive.xlsx differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/__MACOSX/._2406 - Ivy SDK for EBS7007E b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/._2406 - Ivy SDK for EBS7007E
new file mode 100644
index 0000000..8968b3a
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/._2406 - Ivy SDK for EBS7007E differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._CS-BIAS-V2.3.5_1_APP库API使用说明.pdf b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._CS-BIAS-V2.3.5_1_APP库API使用说明.pdf
new file mode 100644
index 0000000..235409a
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._CS-BIAS-V2.3.5_1_APP库API使用说明.pdf differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._CS_BIAS_V2.3.5标准样本.xlsx b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._CS_BIAS_V2.3.5标准样本.xlsx
new file mode 100644
index 0000000..0ef0192
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._CS_BIAS_V2.3.5标准样本.xlsx differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._CS_BIAS_V2.3.5算法用户手册.pdf b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._CS_BIAS_V2.3.5算法用户手册.pdf
new file mode 100644
index 0000000..5cca910
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._CS_BIAS_V2.3.5算法用户手册.pdf differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._OKOK健康最新指标标准 (已经旧了,可参考).pdf b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._OKOK健康最新指标标准 (已经旧了,可参考).pdf
new file mode 100644
index 0000000..913d260
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._OKOK健康最新指标标准 (已经旧了,可参考).pdf differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._android.zip b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._android.zip
new file mode 100644
index 0000000..0ef0192
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._android.zip differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._ios.zip b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._ios.zip
new file mode 100644
index 0000000..0ef0192
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._ios.zip differ
diff --git a/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._人体成分含义及判定标准-BIAS-2.3.5.pdf b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._人体成分含义及判定标准-BIAS-2.3.5.pdf
new file mode 100644
index 0000000..c3c5f30
Binary files /dev/null and b/app/2406 - Ivy SDK for EBS7007E/__MACOSX/2406 - Ivy SDK for EBS7007E/._人体成分含义及判定标准-BIAS-2.3.5.pdf differ
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
new file mode 100644
index 0000000..1686949
--- /dev/null
+++ b/app/build.gradle.kts
@@ -0,0 +1,60 @@
+plugins {
+ alias(libs.plugins.android.application)
+}
+
+android {
+ namespace = "com.cureselect.weighingscale"
+ compileSdk = 36
+
+ defaultConfig {
+ applicationId = "com.cureselect.weighingscale"
+ minSdk = 24
+ targetSdk = 36
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+
+ ndk {
+ abiFilters += listOf("arm64-v8a", "armeabi-v7a")
+ }
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ }
+
+ buildFeatures {
+ viewBinding = true
+ }
+
+ sourceSets {
+ getByName("main") {
+ jniLibs.srcDirs("libs")
+ }
+ }
+}
+
+dependencies {
+ implementation(libs.appcompat)
+ implementation(libs.material)
+ implementation(libs.activity)
+ implementation(libs.constraintlayout)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.ext.junit)
+ androidTestImplementation(libs.espresso.core)
+ implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
+ implementation("androidx.constraintlayout:constraintlayout:2.1.4")
+ implementation("androidx.core:core-ktx:1.13.1") // For context compat
+}
\ No newline at end of file
diff --git a/app/libs/arm64-v8a/libchipsea_bias_v235.so b/app/libs/arm64-v8a/libchipsea_bias_v235.so
new file mode 100644
index 0000000..92b23a3
Binary files /dev/null and b/app/libs/arm64-v8a/libchipsea_bias_v235.so differ
diff --git a/app/libs/armeabi-v7a/libchipsea_bias_v235.so b/app/libs/armeabi-v7a/libchipsea_bias_v235.so
new file mode 100644
index 0000000..9502a24
Binary files /dev/null and b/app/libs/armeabi-v7a/libchipsea_bias_v235.so differ
diff --git a/app/libs/armeabi/libchipsea_bias_v235.so b/app/libs/armeabi/libchipsea_bias_v235.so
new file mode 100644
index 0000000..55f1639
Binary files /dev/null and b/app/libs/armeabi/libchipsea_bias_v235.so differ
diff --git a/app/libs/mips/libchipsea_bias_v235.so b/app/libs/mips/libchipsea_bias_v235.so
new file mode 100644
index 0000000..76f8e8d
Binary files /dev/null and b/app/libs/mips/libchipsea_bias_v235.so differ
diff --git a/app/libs/mips64/libchipsea_bias_v235.so b/app/libs/mips64/libchipsea_bias_v235.so
new file mode 100644
index 0000000..5363dd2
Binary files /dev/null and b/app/libs/mips64/libchipsea_bias_v235.so differ
diff --git a/app/libs/x86/libchipsea_bias_v235.so b/app/libs/x86/libchipsea_bias_v235.so
new file mode 100644
index 0000000..29d7b4e
Binary files /dev/null and b/app/libs/x86/libchipsea_bias_v235.so differ
diff --git a/app/libs/x86_64/libchipsea_bias_v235.so b/app/libs/x86_64/libchipsea_bias_v235.so
new file mode 100644
index 0000000..ca35c74
Binary files /dev/null and b/app/libs/x86_64/libchipsea_bias_v235.so differ
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/cureselect/weighingscale/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/cureselect/weighingscale/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..a43de10
--- /dev/null
+++ b/app/src/androidTest/java/com/cureselect/weighingscale/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.cureselect.weighingscale;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.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 Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation ().getTargetContext ();
+ assertEquals ( "com.cureselect.weighingscale" , appContext.getPackageName () );
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..0e756f1
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/chipsea/bias/v235/CSBiasAPI.java b/app/src/main/java/chipsea/bias/v235/CSBiasAPI.java
new file mode 100644
index 0000000..f4e1d91
--- /dev/null
+++ b/app/src/main/java/chipsea/bias/v235/CSBiasAPI.java
@@ -0,0 +1,119 @@
+package chipsea.bias.v235;
+
+/**
+ * Created by liangyc
+ * Time :2018/11/26
+ * Des:
+ */
+
+/*
+测试数据
+身高, 体重,阻抗,性别, 年龄
+{170, 500, 4080, 1, 30},
+{170, 1000, 4280, 1, 30},
+{170, 1500, 4480, 1, 30},
+{170, 500, 4080, 0, 30},
+{170, 1000, 4280, 0, 30},
+{170, 1500, 4480, 0, 30},
+{170, 509, 4547, 1, 28},
+{164, 790, 3797, 1, 28},
+{174, 669, 4221, 1, 24},
+{158, 603, 4388, 0, 21},
+{163, 474, 4759, 0, 22},
+{160, 553, 4549, 1, 26},
+*/
+/*
+测试结果
+BFP SLM BWP BMC VFR PP SMM BMR BMI SBW MC WC FC age score
+5.0 45.3 62.9 2.2 1.0 27.7 26.0 1324 17.3 62.3 4.2 12.3 8.1 15 60
+33.0 64.8 50.2 2.3 20.5 14.5 34.8 1981 34.6 62.3 - 15.3 - 37.7 - 22.4 56 50
+42.7 84.2 46.0 1.7 41.5 10.1 43.5 2639 51.9 62.3 - 34.2 - 87.7 - 53.5 80 50
+15.3 40.4 55.6 1.9 1.0 25.3 23.6 1239 17.3 60.4 3.0 10.4 7.4 15 66
+45.0 51.0 42.6 4.0 13.5 8.4 32.3 1737 34.6 60.4 - 9.7 - 39.6 - 29.9 80 49
+45.0 78.5 38.3 4.0 26.5 14.0 41.1 2235 51.9 60.4 - 37.2 - 89.5 - 52.4 80 50
+6.1 44.7 61.4 3.1 1 26.5 24.9 1318 17.6 62.3 3.9 11.4 7.5 15 63
+27 55.7 53.5 1.9 12 17.1 30.7 1692 29.4 58 - 9.5 - 21 - 11.5 37 56
+16.6 53.1 57 2.7 5 22.4 29.9 1598 22.1 65.3 - 1.6 - 1.6 0 21 86
+32.4 38.2 48.8 2.6 4.5 14.5 21.7 1269 24.2 52.2 - 1.6 - 8.1 - 6.5 33 68
+18.4 36.3 54 2.3 1 22.6 19.5 1153 17.8 55.6 3 8.2 5.2 15 70
+*/
+
+public class CSBiasAPI {
+
+ public static final int CSBIAS_OK = 0;
+ public static final int CSBIAS_ERR_WEIGTH = -2;
+ public static final int CSBIAS_ERR_HEIGHT = -3;
+ public static final int CSBIAS_ERR_AGE = -4;
+ public static final int CSBIAS_ERR_SEX = -5;
+ public static final int CSBIAS_ERR_IMPEDANCE = -6;
+ public static final int CSBIAS_ERR_MODE = -7;
+ public static final int CSBIAS_ERR_VCODE = -8;
+
+ static {
+ System.loadLibrary("chipsea_bias_v235");
+ }
+
+ /*
+ 人体成分算法
+ - mode 模式,默认为0
+ - sex 性别, 1男, 0女
+ - age 年龄,取值在18 ~ 99岁之间
+ - height 身高, 取值在90 ~ 220之间,表示90 ~ 220厘米.
+ - weight 体重,取值在200 ~ 1500之间,表示20公斤~150公斤.
+ - impedance 阻抗值, 取值在2000 ~ 15000.
+ - vkeyCode 指纹验证中的验证码
+ */
+ public static native CSBiasV235Resp cs_bias_v235(int mode, int sex, int age, int height, int weight, int impedance, int vkeyCode);
+
+ /**
+ * Created by liangyc
+ * Time :2018/11/26
+ * Des:
+ */
+ public static class CSBiasDataV235 {
+ //体脂率
+ public double BFP;
+ //肌肉量
+ public double SLM;
+ //骨盐量
+ public double BMC;
+ //体水分率
+ public double BWP;
+ //蛋白质率
+ public double PP;
+ //骨骼肌量
+ public double SMM;
+ //内脏脂肪等级
+ public double VFR;
+ //身体质量指数
+ public double BMI;
+ //标准体重
+ public double SBW;
+ //肌肉控制
+ public double MC;
+ //体重控制
+ public double WC;
+ //脂肪控制
+ public double FC;
+ //基础代谢率
+ public int BMR;
+ //身体年龄
+ public int MA;
+ //身体得分
+ public int SBC;
+
+ }
+
+ /**
+ * Created by liangyc
+ * Time :2018/11/26
+ * Des:
+ */
+ public static class CSBiasV235Resp {
+ public int result;
+
+ public CSBiasDataV235 data;
+
+
+ }
+}
diff --git a/app/src/main/java/com/cureselect/weighingscale/MainActivity.java b/app/src/main/java/com/cureselect/weighingscale/MainActivity.java
new file mode 100644
index 0000000..12688ee
--- /dev/null
+++ b/app/src/main/java/com/cureselect/weighingscale/MainActivity.java
@@ -0,0 +1,453 @@
+package com.cureselect.weighingscale;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+import android.Manifest;
+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.ScanFilter;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.RadioButton;
+import android.widget.TextView;
+import android.widget.Toast;
+import com.cureselect.weighingscale.R;
+import chipsea.bias.v235.CSBiasAPI;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class MainActivity extends AppCompatActivity {
+ private static final String TAG = "MainActivity";
+ private static final int REQUEST_PERMISSIONS = 1;
+ private static final long SCAN_DURATION = 30000; // 30 seconds
+ private static final long RETRY_DELAY = 2000; // 2s delay on failure
+
+ private EditText txtHeight, txtAge, txtWeight, txtR;
+ private RadioButton radioMale;
+ private TextView txtTest;
+
+ // BLE
+ private BluetoothAdapter bluetoothAdapter;
+ private BluetoothLeScanner bluetoothLeScanner;
+ private ScanCallback scanCallback;
+ private Handler handler = new Handler(Looper.getMainLooper());
+ private Runnable stopScanRunnable;
+ private AtomicBoolean isScanning = new AtomicBoolean(false); // Thread-safe flag
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ // Init views
+ txtHeight = findViewById(R.id.txtHeight);
+ txtAge = findViewById(R.id.txtAge);
+ txtWeight = findViewById(R.id.txtWeight);
+ txtR = findViewById(R.id.txtR);
+ radioMale = findViewById(R.id.radioMale);
+ txtTest = findViewById(R.id.txtTest);
+
+ // Init BLE
+ initBluetooth();
+ }
+
+ private void initBluetooth() {
+ BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
+ bluetoothAdapter = bluetoothManager.getAdapter();
+ if (bluetoothAdapter == null) {
+ Toast.makeText(this, "Bluetooth not available.", Toast.LENGTH_LONG).show();
+ return;
+ }
+
+ bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
+ if (bluetoothLeScanner == null) {
+ Toast.makeText(this, "BLE Scanner not available.", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ if (!bluetoothAdapter.isEnabled()) {
+ Toast.makeText(this, "Bluetooth not enabled. Please enable it.", Toast.LENGTH_LONG).show();
+ Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
+ startActivity(enableBtIntent);
+ return;
+ }
+
+ // Delay 5s for Samsung stack to settle
+ handler.postDelayed(this::setupScanCallback, 5000);
+ }
+
+ private float lastDetectedWeight = -1f; // Track last weight to avoid spam
+
+ private void parseAAAScaleData(byte[] fullRecord, String deviceName) {
+ // AAA scale format analysis
+ // Looking for manufacturer data after 0F FF marker
+ for (int i = 0; i < fullRecord.length - 15; i++) {
+ // Find manufacturer data marker: 0x0F 0xFF
+ if (fullRecord[i] == 0x0F && fullRecord[i+1] == (byte)0xFF) {
+ Log.d(TAG, "Found manufacturer data at offset " + i);
+ // Extract manufacturer data (next 14 bytes typically)
+ int dataStart = i + 2;
+ if (dataStart + 14 <= fullRecord.length) {
+ byte[] mfgData = Arrays.copyOfRange(fullRecord, dataStart, dataStart + 14);
+ Log.d(TAG, "Manufacturer data: " + bytesToHex(mfgData));
+
+ float finalWeight = 0;
+ String detectionMethod = "";
+ float bestWeight = Float.MAX_VALUE; // NEW: Track "best" (lowest plausible) to avoid fixed values
+
+ // REORDER: Start offsets from END (likely weight position) to prioritize dynamic bytes
+ for (int offset = mfgData.length - 2; offset >= 0; offset--) { // Reverse order: end first
+ int rawBE = ((mfgData[offset] & 0xFF) << 8) | (mfgData[offset + 1] & 0xFF);
+ int rawLE = ((mfgData[offset + 1] & 0xFF) << 8) | (mfgData[offset] & 0xFF);
+
+ float[] divisors = {100.0f, 10.0f, 200.0f, 1.0f}; // Keep, but now later offsets first
+
+ for (float divisor : divisors) {
+ float testWeightBE = rawBE / divisor;
+ float testWeightLE = rawLE / divisor;
+
+ Log.d(TAG, String.format("Candidate: offset=%d BE/%.0f=%.3fkg (raw=%d), LE/%.0f=%.3fkg (raw=%d)",
+ offset, divisor, testWeightBE, rawBE, divisor, testWeightLE, rawLE)); // More decimals for precision
+
+ // CHANGED: Lower min to 0.1 kg (allows 12.5 kg), raise max to 200 kg
+ boolean isValidBE = (testWeightBE >= 0.1f && testWeightBE <= 200.0f);
+ boolean isValidLE = (testWeightLE >= 0.1f && testWeightLE <= 200.0f);
+
+ // NEW: Only consider if "better" than current (e.g., lower value, avoids fixed high like 88.3)
+ if (isValidBE && testWeightBE < bestWeight) {
+ bestWeight = testWeightBE;
+ detectionMethod = String.format("BE offset=%d divisor=%.0f raw=%d", offset, divisor, rawBE);
+ }
+ if (isValidLE && testWeightLE < bestWeight) { // Prioritize LE if tie
+ bestWeight = testWeightLE;
+ detectionMethod = String.format("LE offset=%d divisor=%.0f raw=%d", offset, divisor, rawLE);
+ }
+ }
+ }
+
+ if (bestWeight < Float.MAX_VALUE && bestWeight >= 0.1f) { // NEW: Use best instead of first
+ finalWeight = bestWeight;
+ Log.d(TAG, "✓ Best valid weight: " + finalWeight + "kg via " + detectionMethod);
+ } else {
+ Log.w(TAG, "No valid weight found—check format");
+ return;
+ }
+
+ if (finalWeight > 0) {
+ // Only update if significantly different from last (live updates without spam)
+ if (Math.abs(finalWeight - lastDetectedWeight) > 0.1f) {
+ lastDetectedWeight = finalWeight;
+ final float detectedWeight = finalWeight;
+ final String method = detectionMethod;
+ runOnUiThread(() -> {
+ txtWeight.setText(String.format("%.1f", detectedWeight));
+ txtR.setText("500"); // Default impedance
+ Toast.makeText(MainActivity.this,
+ String.format("Weight: %.1fkg (%s)", detectedWeight, method),
+ Toast.LENGTH_SHORT).show(); // Short toast for live updates
+ newClick(null); // Auto-calculate
+ });
+ }
+ // DO NOT stopScanning() - keep live updating during scan
+ return;
+ } else {
+ Log.w(TAG, "No valid weight found in manufacturer data");
+ }
+ }
+ }
+ }
+ }
+ private String bytesToHex(byte[] bytes) {
+ if (bytes == null) return "null";
+ StringBuilder sb = new StringBuilder();
+ for (byte b : bytes) {
+ sb.append(String.format("%02X ", b));
+ }
+ return sb.toString().trim();
+ }
+
+ private void setupScanCallback() {
+ scanCallback = new ScanCallback() {
+ @Override
+ public void onScanResult(int callbackType, ScanResult result) {
+ super.onScanResult(callbackType, result);
+ BluetoothDevice device = result.getDevice();
+ String deviceName = "Unnamed";
+ try {
+ if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED) {
+ deviceName = device.getName() != null ? device.getName() : "Unnamed";
+ }
+ } catch (SecurityException e) {
+ Log.e(TAG, "Permission error", e);
+ }
+ Log.d(TAG, "Device: " + deviceName + " | MAC: " + device.getAddress() + " | RSSI: " + result.getRssi());
+
+ // Check for AAA002 scale
+ if (deviceName != null && deviceName.startsWith("AAA")) {
+ Log.d(TAG, "🎯 Found AAA scale!");
+ if (result.getScanRecord() != null) {
+ byte[] fullRecord = result.getScanRecord().getBytes();
+ Log.d(TAG, "Full data: " + bytesToHex(fullRecord));
+ parseAAAScaleData(fullRecord, deviceName);
+ }
+ }
+ }
+
+ @Override
+ public void onScanFailed(int errorCode) {
+ super.onScanFailed(errorCode);
+ Log.e(TAG, "Scan failed: " + errorCode);
+ isScanning.set(false);
+ runOnUiThread(() -> {
+ String msg = "Scan failed (code " + errorCode + "). ";
+ if (errorCode == ScanCallback.SCAN_FAILED_ALREADY_STARTED) {
+ msg += "Already started—retrying in 2s.";
+ handler.postDelayed(MainActivity.this::startScanning, RETRY_DELAY); // Auto-retry
+ } else if (errorCode == ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED) {
+ msg += "App registration failed—restart app/BT.";
+ } else if (errorCode == ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED) {
+ msg += "BLE unsupported—check device.";
+ } else {
+ msg += "Try toggling Bluetooth/location.";
+ }
+ Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
+ });
+ }
+
+ @Override
+ public void onBatchScanResults(List results) {
+ super.onBatchScanResults(results);
+ Log.d(TAG, "Batch results: " + results.size() + " devices (batched delivery)");
+ // Process each as in onScanResult if needed
+ for (ScanResult result : results) {
+ onScanResult(0, result); // Reuse logic
+ }
+ }
+ };
+
+ stopScanRunnable = () -> {
+ stopScanning();
+ runOnUiThread(() -> Toast.makeText(this, "Scan stopped. No data found—try stepping on scale.", Toast.LENGTH_SHORT).show());
+ };
+ }
+
+ public void startScan(View view) {
+ // Permission check
+ String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT};
+ boolean allGranted = true;
+ for (String perm : permissions) {
+ if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
+ allGranted = false;
+ break;
+ }
+ }
+ if (!allGranted) {
+ ActivityCompat.requestPermissions(this, permissions, REQUEST_PERMISSIONS);
+ return;
+ }
+
+ if (isScanning.get()) {
+ Toast.makeText(this, "Scan already in progress—wait or toggle BT.", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ startScanning();
+ }
+
+ private void startScanning() {
+ if (isScanning.get() || bluetoothLeScanner == null) {
+ Log.w(TAG, "Scan blocked: already scanning or null scanner.");
+ return;
+ }
+
+ isScanning.set(true);
+ Log.d(TAG, "Starting scan... (unfiltered, low latency for testing)");
+
+ try {
+ ScanSettings settings = new ScanSettings.Builder()
+ .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // More aggressive detection
+ .setReportDelay(0) // No batching—immediate callbacks
+ .build();
+
+ // Optional loose filter for AAA to reduce noise (uncomment if needed)
+ // List filters = Collections.singletonList(
+ // new ScanFilter.Builder().setDeviceName("AAA").build()
+ // );
+ // bluetoothLeScanner.startScan(filters, settings, scanCallback);
+
+ bluetoothLeScanner.startScan(null, settings, scanCallback); // Unfiltered for now
+ Log.d(TAG, "Scan started successfully—no errors.");
+ } catch (SecurityException e) {
+ Log.e(TAG, "Security error starting scan: " + e.getMessage());
+ isScanning.set(false);
+ runOnUiThread(() -> Toast.makeText(this, "Scan error: Check permissions/location.", Toast.LENGTH_SHORT).show());
+ } catch (Exception e) {
+ Log.e(TAG, "Unexpected error starting scan: " + e.getMessage());
+ isScanning.set(false);
+ }
+
+ handler.postDelayed(stopScanRunnable, SCAN_DURATION);
+ runOnUiThread(() -> Toast.makeText(this, "Scanning (low latency mode)... Step on the scale!", Toast.LENGTH_LONG).show());
+ }
+
+ private void stopScanning() {
+ if (!isScanning.get() || bluetoothLeScanner == null) {
+ return;
+ }
+
+ isScanning.set(false);
+ Log.d(TAG, "Stopping scan...");
+ try {
+ bluetoothLeScanner.stopScan(scanCallback);
+ } catch (Exception e) {
+ Log.e(TAG, "Error stopping scan: " + e.getMessage());
+ }
+ handler.removeCallbacks(stopScanRunnable);
+ }
+
+ private void parseChipseaData(byte[] data) {
+ Log.d(TAG, "Raw data: " + Arrays.toString(data));
+
+ // OKOK V1.1 Broadcast: CA 11 0F [cmd 00/01] 01 [wt high] [wt low] [product 4B] [properties] [reserved 6B] [checksum]
+ if (data.length != 19 || data[0] != (byte) 0xCA || data[1] != (byte) 0x11 || data[2] != (byte) 0x0F || data[4] != (byte) 0x01) {
+ Log.d(TAG, "No OKOK match—header mismatch or wrong length.");
+ return;
+ }
+
+ // Verify checksum: XOR bytes 0-17 == data[18]
+ byte checksum = 0;
+ for (int i = 0; i < 18; i++) {
+ checksum ^= data[i];
+ }
+ if (checksum != data[18]) {
+ Log.w(TAG, "Checksum mismatch: expected " + checksum + ", got " + data[18]);
+ return; // Invalid packet
+ }
+
+ // Weight: big-endian uint16 (data[5]<<8 | data[6]), scaled by decimals
+ int weightRaw = ((data[5] & 0xFF) << 8) | (data[6] & 0xFF);
+ byte properties = data[11];
+ int decPlaces = (properties >> 4) & 0x03; // Bits 5-4
+
+ double scaleFactor;
+ switch (decPlaces) {
+ case 0: scaleFactor = 10.0; break; // 1 decimal
+ case 1: scaleFactor = 1.0; break; // 0 decimals
+ case 2: scaleFactor = 100.0; break; // 2 decimals
+ default: scaleFactor = 10.0; // Default
+ }
+
+ final float weight = (float) (weightRaw / scaleFactor);
+
+ // Unit: Bits 7-6 (assume KG=00; log if other)
+ int unit = (properties >> 6) & 0x03;
+ String unitStr = (unit == 0) ? "kg" : (unit == 1) ? "Jin" : (unit == 2) ? "lb" : "st:lb";
+ if (unit != 0) {
+ Log.w(TAG, "Non-KG unit detected: " + unitStr + " - convert if needed.");
+ // Optional: Convert to kg (e.g., lb to kg: weight * 0.453592)
+ }
+
+ // R not in broadcast—manual/default
+ final float defaultR = 500.0f; // From your samples
+
+ runOnUiThread(() -> {
+ txtWeight.setText(String.format("%.1f", weight));
+ txtR.setText(String.format("%.1f", defaultR)); // Manual R for calc
+ newClick(null); // Auto-compute
+ Toast.makeText(MainActivity.this, String.format("Fetched: %.1f %s (R manual: %.1fΩ)", weight, unitStr, defaultR), Toast.LENGTH_SHORT).show();
+ });
+
+ stopScanning();
+ Log.d(TAG, "Parsed: Weight=" + weight + " " + unitStr + " (decimals=" + decPlaces + "), R=manual");
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (requestCode == REQUEST_PERMISSIONS && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ startScanning();
+ } else {
+ Toast.makeText(this, "Permissions denied. Cannot scan.", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ public void newClick(View view) {
+ try {
+ float height = Float.parseFloat(txtHeight.getText().toString().trim());
+ int age = Integer.parseInt(txtAge.getText().toString().trim());
+ float weight = Float.parseFloat(txtWeight.getText().toString().trim());
+ float r = Float.parseFloat(txtR.getText().toString().trim());
+
+ if (height <= 0 || age <= 0 || weight <= 0 || r <= 0) {
+ txtTest.setText("Error: All inputs must be positive numbers.");
+ return;
+ }
+
+ byte sex = radioMale.isChecked() ? (byte) 1 : (byte) 0;
+ CSBiasAPI.CSBiasV235Resp resp = CSBiasAPI.cs_bias_v235(0, sex, age, (int) height, (int) (weight * 10), (int) (r * 10), 2018);
+
+ StringBuilder sb = new StringBuilder();
+ if (resp.result == CSBiasAPI.CSBIAS_OK) {
+ sb.append("Input\n");
+ sb.append("Gender:" + sex + " Height:" + height + " Age:" + age + " Resistance:" + r + " Weight:" + weight + "\n");
+ sb.append("**************************************\n");
+ sb.append("Body Fat %:" + resp.data.BFP + "\n");
+ sb.append("Muscle Mass kg:" + resp.data.SLM + "\n");
+ sb.append("Water %:" + resp.data.BWP + "\n");
+ sb.append("Bone Mass:" + resp.data.BMC + "\n");
+ sb.append("Visceral Fat:" + resp.data.VFR + "\n");
+ sb.append("Protein %:" + resp.data.PP + "\n");
+ sb.append("Skeletal Muscle kg:" + resp.data.SMM + "\n");
+ sb.append("BMR:" + resp.data.BMR + "\n");
+ sb.append("BMI:" + resp.data.BMI + "\n");
+ sb.append("Standard Weight kg:" + resp.data.SBW + "\n");
+ sb.append("Muscle Control:" + (resp.data.MC != 0 ? resp.data.MC : "-") + "\n");
+ sb.append("Weight Control:" + (resp.data.WC != 0 ? resp.data.WC : "-") + "\n");
+ sb.append("Fat Control:" + (resp.data.FC != 0 ? resp.data.FC : "-") + "\n");
+ sb.append("Body Age:" + resp.data.MA + "\n");
+ sb.append("Score:" + resp.data.SBC + "\n");
+ sb.append("**************************************\n");
+ } else {
+ sb.append("Error: " + resp.result);
+ }
+ txtTest.setText(sb.toString());
+ } catch (NumberFormatException e) {
+ txtTest.setText("Error: Please enter valid numbers.");
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ initBluetooth(); // Re-init for Samsung stability
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ stopScanning();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ stopScanning();
+ handler.removeCallbacksAndMessages(null);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cureselect/weighingscale/MainActivity.java.backup b/app/src/main/java/com/cureselect/weighingscale/MainActivity.java.backup
new file mode 100644
index 0000000..7408644
--- /dev/null
+++ b/app/src/main/java/com/cureselect/weighingscale/MainActivity.java.backup
@@ -0,0 +1,377 @@
+package com.cureselect.weighingscale;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import android.Manifest;
+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.ScanFilter;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.RadioButton;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.cureselect.weighingscale.R;
+
+import chipsea.bias.v235.CSBiasAPI;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class MainActivity extends AppCompatActivity {
+ private static final String TAG = "MainActivity";
+ private static final int REQUEST_PERMISSIONS = 1;
+ private static final long SCAN_DURATION = 30000; // 30 seconds
+ private static final long RETRY_DELAY = 2000; // 2s delay on failure
+
+ private EditText txtHeight, txtAge, txtWeight, txtR;
+ private RadioButton radioMale;
+ private TextView txtTest;
+
+ // BLE
+ private BluetoothAdapter bluetoothAdapter;
+ private BluetoothLeScanner bluetoothLeScanner;
+ private ScanCallback scanCallback;
+ private Handler handler = new Handler(Looper.getMainLooper());
+ private Runnable stopScanRunnable;
+ private AtomicBoolean isScanning = new AtomicBoolean(false); // Thread-safe flag
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ // Init views
+ txtHeight = findViewById(R.id.txtHeight);
+ txtAge = findViewById(R.id.txtAge);
+ txtWeight = findViewById(R.id.txtWeight);
+ txtR = findViewById(R.id.txtR);
+ radioMale = findViewById(R.id.radioMale);
+ txtTest = findViewById(R.id.txtTest);
+
+ // Init BLE
+ initBluetooth();
+ }
+
+ private void initBluetooth() {
+ BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
+ bluetoothAdapter = bluetoothManager.getAdapter();
+
+ if (bluetoothAdapter == null) {
+ Toast.makeText(this, "Bluetooth not available.", Toast.LENGTH_LONG).show();
+ return;
+ }
+
+ bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
+
+ if (bluetoothLeScanner == null) {
+ Toast.makeText(this, "BLE Scanner not available.", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ if (!bluetoothAdapter.isEnabled()) {
+ Toast.makeText(this, "Bluetooth not enabled. Please enable it.", Toast.LENGTH_LONG).show();
+ Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
+ startActivity(enableBtIntent);
+ return;
+ }
+
+ // Delay 5s for Samsung stack to settle
+ handler.postDelayed(this::setupScanCallback, 5000);
+ }
+
+ private void setupScanCallback() {
+ scanCallback = new ScanCallback() {
+ @Override
+ public void onScanResult(int callbackType, ScanResult result) {
+ super.onScanResult(callbackType, result);
+ BluetoothDevice device = result.getDevice();
+ Log.d(TAG, "Device found: " + (device.getName() != null ? device.getName() : "Unnamed") +
+ " | MAC: " + device.getAddress() + " | RSSI: " + result.getRssi() + " dBm");
+
+ // Log full scan record for debugging (even non-matches)
+ byte[] fullRecord = result.getScanRecord().getBytes();
+ if (fullRecord != null) {
+ Log.d(TAG, "Full scan record bytes: " + Arrays.toString(fullRecord));
+ }
+
+ byte[] manufacturerData = result.getScanRecord().getManufacturerSpecificData(76); // Chipsea ID: 0x004C
+ if (manufacturerData == null || manufacturerData.length != 19) {
+ // Log non-matching data too—helps spot similar scales
+ Log.d(TAG, "Non-matching mfg data (len=" + (manufacturerData != null ? manufacturerData.length : 0) + ")");
+ byte[] fullData = result.getScanRecord().getBytes();
+ if (fullData != null) {
+ Log.d(TAG, "Full scan record: " + Arrays.toString(fullData));
+ parseChipseaData(fullData); // Fallback, but unlikely
+ }
+ return;
+ }
+ parseChipseaData(manufacturerData);
+ }
+
+ @Override
+ public void onScanFailed(int errorCode) {
+ super.onScanFailed(errorCode);
+ Log.e(TAG, "Scan failed: " + errorCode);
+ isScanning.set(false);
+
+ runOnUiThread(() -> {
+ String msg = "Scan failed (code " + errorCode + "). ";
+ if (errorCode == ScanCallback.SCAN_FAILED_ALREADY_STARTED) {
+ msg += "Already started—retrying in 2s.";
+ handler.postDelayed(MainActivity.this::startScanning, RETRY_DELAY); // Auto-retry
+ } else if (errorCode == ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED) {
+ msg += "App registration failed—restart app/BT.";
+ } else if (errorCode == ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED) {
+ msg += "BLE unsupported—check device.";
+ } else {
+ msg += "Try toggling Bluetooth/location.";
+ }
+ Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
+ });
+ }
+
+ @Override
+ public void onBatchScanResults(List results) {
+ super.onBatchScanResults(results);
+ Log.d(TAG, "Batch results: " + results.size() + " devices (batched delivery)");
+ // Process each as in onScanResult if needed
+ for (ScanResult result : results) {
+ onScanResult(0, result); // Reuse logic
+ }
+ }
+ };
+
+ stopScanRunnable = () -> {
+ stopScanning();
+ runOnUiThread(() -> Toast.makeText(this, "Scan stopped. No data found—try stepping on scale.", Toast.LENGTH_SHORT).show());
+ };
+ }
+
+ public void startScan(View view) {
+ // Permission check
+ String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT};
+ boolean allGranted = true;
+ for (String perm : permissions) {
+ if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
+ allGranted = false;
+ break;
+ }
+ }
+
+ if (!allGranted) {
+ ActivityCompat.requestPermissions(this, permissions, REQUEST_PERMISSIONS);
+ return;
+ }
+
+ if (isScanning.get()) {
+ Toast.makeText(this, "Scan already in progress—wait or toggle BT.", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ startScanning();
+ }
+
+ private void startScanning() {
+ if (isScanning.get() || bluetoothLeScanner == null) {
+ Log.w(TAG, "Scan blocked: already scanning or null scanner.");
+ return;
+ }
+
+ isScanning.set(true);
+ Log.d(TAG, "Starting scan... (unfiltered, low latency for testing)");
+
+ try {
+ ScanSettings settings = new ScanSettings.Builder()
+ .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // More aggressive detection
+ .setReportDelay(0) // No batching—immediate callbacks
+ .build();
+
+ // Optional: Add loose filter for Chipsea to reduce noise but still catch it
+ // List filters = Collections.singletonList(
+ // new ScanFilter.Builder().setManufacturerData(76, null).build() // Null data = any payload
+ // );
+ // bluetoothLeScanner.startScan(filters, settings, scanCallback);
+
+ bluetoothLeScanner.startScan(null, settings, scanCallback); // Unfiltered for now
+
+ Log.d(TAG, "Scan started successfully—no errors.");
+ } catch (SecurityException e) {
+ Log.e(TAG, "Security error starting scan: " + e.getMessage()); // e.g., missing perms
+ isScanning.set(false);
+ runOnUiThread(() -> Toast.makeText(this, "Scan error: Check permissions/location.", Toast.LENGTH_SHORT).show());
+ } catch (Exception e) {
+ Log.e(TAG, "Unexpected error starting scan: " + e.getMessage());
+ isScanning.set(false);
+ }
+
+ handler.postDelayed(stopScanRunnable, SCAN_DURATION);
+ runOnUiThread(() -> Toast.makeText(this, "Scanning (low latency mode)... Step on the scale!", Toast.LENGTH_LONG).show());
+ }
+
+ private void stopScanning() {
+ if (!isScanning.get() || bluetoothLeScanner == null) {
+ return;
+ }
+
+ isScanning.set(false);
+ Log.d(TAG, "Stopping scan...");
+ try {
+ bluetoothLeScanner.stopScan(scanCallback);
+ } catch (Exception e) {
+ Log.e(TAG, "Error stopping scan: " + e.getMessage());
+ }
+ handler.removeCallbacks(stopScanRunnable);
+ }
+
+ private void parseChipseaData(byte[] data) {
+ Log.d(TAG, "Raw data: " + Arrays.toString(data));
+
+ // OKOK V1.1 Broadcast: CA 11 0F [cmd 00/01] 01 [wt high] [wt low] [product 4B] [properties] [reserved 6B] [checksum]
+ if (data.length != 19 || data[0] != (byte) 0xCA || data[1] != (byte) 0x11 || data[2] != (byte) 0x0F || data[4] != (byte) 0x01) {
+ Log.d(TAG, "No OKOK match—header mismatch or wrong length.");
+ return;
+ }
+
+ // Verify checksum: XOR bytes 0-17 == data[18]
+ byte checksum = 0;
+ for (int i = 0; i < 18; i++) {
+ checksum ^= data[i];
+ }
+ if (checksum != data[18]) {
+ Log.w(TAG, "Checksum mismatch: expected " + checksum + ", got " + data[18]);
+ return; // Invalid packet
+ }
+
+ // Weight: big-endian uint16 (data[5]<<8 | data[6]), scaled by decimals
+ int weightRaw = ((data[5] & 0xFF) << 8) | (data[6] & 0xFF);
+ byte properties = data[11];
+ int decPlaces = (properties >> 4) & 0x03; // Bits 5-4
+
+ double scaleFactor;
+ switch (decPlaces) {
+ case 0:
+ scaleFactor = 10.0; break; // 1 decimal
+ case 1:
+ scaleFactor = 1.0; break; // 0 decimals
+ case 2:
+ scaleFactor = 100.0; break; // 2 decimals
+ default:
+ scaleFactor = 10.0; // Default
+ }
+
+ final float weight = (float) (weightRaw / scaleFactor);
+
+ // Unit: Bits 7-6 (assume KG=00; log if other)
+ int unit = (properties >> 6) & 0x03;
+ String unitStr = (unit == 0) ? "kg" : (unit == 1) ? "Jin" : (unit == 2) ? "lb" : "st:lb";
+ if (unit != 0) {
+ Log.w(TAG, "Non-KG unit detected: " + unitStr + " - convert if needed.");
+ // Optional: Convert to kg (e.g., lb to kg: weight * 0.453592)
+ }
+
+ // R not in broadcast—manual/default
+ final float defaultR = 500.0f; // From your samples
+
+ runOnUiThread(() -> {
+ txtWeight.setText(String.format("%.1f", weight));
+ txtR.setText(String.format("%.1f", defaultR)); // Manual R for calc
+ newClick(null); // Auto-compute
+ Toast.makeText(MainActivity.this, String.format("Fetched: %.1f %s (R manual: %.1fΩ)", weight, unitStr, defaultR), Toast.LENGTH_SHORT).show();
+ });
+
+ stopScanning();
+ Log.d(TAG, "Parsed: Weight=" + weight + " " + unitStr + " (decimals=" + decPlaces + "), R=manual");
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (requestCode == REQUEST_PERMISSIONS && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ startScanning();
+ } else {
+ Toast.makeText(this, "Permissions denied. Cannot scan.", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ public void newClick(View view) {
+ try {
+ float height = Float.parseFloat(txtHeight.getText().toString().trim());
+ int age = Integer.parseInt(txtAge.getText().toString().trim());
+ float weight = Float.parseFloat(txtWeight.getText().toString().trim());
+ float r = Float.parseFloat(txtR.getText().toString().trim());
+
+ if (height <= 0 || age <= 0 || weight <= 0 || r <= 0) {
+ txtTest.setText("Error: All inputs must be positive numbers.");
+ return;
+ }
+
+ byte sex = radioMale.isChecked() ? (byte) 1 : (byte) 0;
+ CSBiasAPI.CSBiasV235Resp resp = CSBiasAPI.cs_bias_v235(0, sex, age, (int) height, (int) (weight * 10), (int) (r * 10), 2018);
+
+ StringBuilder sb = new StringBuilder();
+ if (resp.result == CSBiasAPI.CSBIAS_OK) {
+ sb.append("Input\n");
+ sb.append("Gender:" + sex + " Height:" + height + " Age:" + age + " Resistance:" + r + " Weight:" + weight + "\n");
+ sb.append("**************************************\n");
+ sb.append("Body Fat %:" + resp.data.BFP + "\n");
+ sb.append("Muscle Mass kg:" + resp.data.SLM + "\n");
+ sb.append("Water %:" + resp.data.BWP + "\n");
+ sb.append("Bone Mass:" + resp.data.BMC + "\n");
+ sb.append("Visceral Fat:" + resp.data.VFR + "\n");
+ sb.append("Protein %:" + resp.data.PP + "\n");
+ sb.append("Skeletal Muscle kg:" + resp.data.SMM + "\n");
+ sb.append("BMR:" + resp.data.BMR + "\n");
+ sb.append("BMI:" + resp.data.BMI + "\n");
+ sb.append("Standard Weight kg:" + resp.data.SBW + "\n");
+ sb.append("Muscle Control:" + (resp.data.MC != 0 ? resp.data.MC : "-") + "\n");
+ sb.append("Weight Control:" + (resp.data.WC != 0 ? resp.data.WC : "-") + "\n");
+ sb.append("Fat Control:" + (resp.data.FC != 0 ? resp.data.FC : "-") + "\n");
+ sb.append("Body Age:" + resp.data.MA + "\n");
+ sb.append("Score:" + resp.data.SBC + "\n");
+ sb.append("**************************************\n");
+ } else {
+ sb.append("Error: " + resp.result);
+ }
+ txtTest.setText(sb.toString());
+ } catch (NumberFormatException e) {
+ txtTest.setText("Error: Please enter valid numbers.");
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ initBluetooth(); // Re-init for Samsung stability
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ stopScanning();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ stopScanning();
+ handler.removeCallbacksAndMessages(null);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/cureselect/weighingscale/MyApplication.java b/app/src/main/java/com/cureselect/weighingscale/MyApplication.java
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/app/src/main/java/com/cureselect/weighingscale/MyApplication.java
@@ -0,0 +1,2 @@
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..640e8a6
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,187 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..c1b849e
--- /dev/null
+++ b/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..c8524cd
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+
+
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..40177fc
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ WeighingScale
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..1b27a80
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..4df9255
--- /dev/null
+++ b/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/test/java/com/cureselect/weighingscale/ExampleUnitTest.java b/app/src/test/java/com/cureselect/weighingscale/ExampleUnitTest.java
new file mode 100644
index 0000000..518806d
--- /dev/null
+++ b/app/src/test/java/com/cureselect/weighingscale/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.cureselect.weighingscale;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals ( 4 , 2 + 2 );
+ }
+}
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 0000000..3756278
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,4 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ alias(libs.plugins.android.application) apply false
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..4b29016
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,22 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
+android.enableJetifier=true
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
new file mode 100644
index 0000000..65c3dc2
--- /dev/null
+++ b/gradle/libs.versions.toml
@@ -0,0 +1,22 @@
+[versions]
+agp = "8.13.1"
+junit = "4.13.2"
+junitVersion = "1.1.5"
+espressoCore = "3.5.1"
+appcompat = "1.6.1"
+material = "1.10.0"
+activity = "1.8.0"
+constraintlayout = "2.1.4"
+
+[libraries]
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "agp" }
+
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..95ab4b8
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Dec 08 11:19:54 IST 2025
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..4f906e0
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 0000000..b030cea
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1,23 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name="WeighingScale"
+include(":app")