Compare commits

..

15 Commits

Author SHA1 Message Date
chandrashekhar reddy
a72bd3d59e app version 130.2, default remote config values updated 2025-01-13 16:49:21 +05:30
chandrashekhar reddy
54be3a1037 app version 130.1, without borderline classification and buffer limit 2024-12-31 15:10:53 +05:30
chandrashekhar reddy
69055b5498 app version 130, without borderline classification 2024-12-30 12:00:39 +05:30
chandrashekhar reddy
7dde6bf976 app version 130, without borderline classification 2024-12-30 11:42:04 +05:30
chandrashekhar reddy
ee0f1d748a Merge remote-tracking branch 'origin/dev-server-2.1.130' into dev-server-2.1.130 2024-12-30 11:36:57 +05:30
chandrashekhar reddy
d32e7b6cbb app version 130, without borderline classification 2024-12-30 11:36:08 +05:30
Chandrashekhar Reddy
d306d0b9fa Update .gitlab-ci.yml file 2024-10-16 09:23:33 +00:00
chandrashekhar reddy
8e074e01c9 rename of the branch 2024-10-15 15:56:03 +05:30
chandrashekhar reddy
6b0c81213e rename of the branch 2024-10-15 15:04:39 +05:30
sathwikcs
51480393da optimised the unnecessary code in json
added sever info in home fragment
removed basic data test
2024-10-09 16:55:44 +05:30
chandrashekhar reddy
d9221a3bb6 Submit button check in HemoCubeFragment 2024-10-09 15:06:05 +05:30
sathwikcs
569155d193 Server switching is implemented
pipeline fixed
version 2.1.128
2024-10-08 17:19:38 +05:30
sathwikcs
ad029e4cce Server switching is implemented
version 2.1.128
2024-10-08 17:03:32 +05:30
sathwikcs
31654be3bb Server switching is implemented
version 2.1.128
2024-10-08 16:53:44 +05:30
sathwikcs
738375afc5 Server switching is implemented
version 2.1.128
2024-10-08 16:44:43 +05:30
34 changed files with 696 additions and 356 deletions

View File

@@ -1,63 +1,31 @@
# This file is a template, and might need editing before it works on your project.
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Android.gitlab-ci.yml
# Read more about this script on this blog post https://about.gitlab.com/2018/10/24/setting-up-gitlab-ci-for-android-projects/, by Jason Lenny
# If you are interested in using Android with FastLane for publishing take a look at the Android-Fastlane template.
image: eclipse-temurin:17-jdk-jammy image: eclipse-temurin:17-jdk-jammy
variables: variables:
# ANDROID_COMPILE_SDK is the version of Android you're compiling with.
# It should match compileSdkVersion.
ANDROID_COMPILE_SDK: "34" ANDROID_COMPILE_SDK: "34"
# ANDROID_BUILD_TOOLS is the version of the Android build tools you are using.
# It should match buildToolsVersion.
ANDROID_BUILD_TOOLS: "33.0.2" ANDROID_BUILD_TOOLS: "33.0.2"
# It's what version of the command line tools we're going to download from the official site.
# Official Site-> https://developer.android.com/studio/index.html
# There, look down below at the cli tools only, sdk tools package is of format:
# commandlinetools-os_type-ANDROID_SDK_TOOLS_latest.zip
# when the script was last modified for latest compileSdkVersion, it was which is written down below
ANDROID_SDK_TOOLS: "9477386" ANDROID_SDK_TOOLS: "9477386"
# Packages installation before running script # Keystore credentials stored as GitLab CI/CD variables
KEYSTORE_PASSWORD: $KS_PASSWORD
KEY_ALIAS: $KS_ALIAS
KEY_PASSWORD: $KS_KEY_PASSWORD
before_script: before_script:
- apt-get --quiet update --yes - apt-get --quiet update --yes
- apt-get --quiet install --yes wget unzip - apt-get --quiet install --yes wget unzip
# Setup path as android_home for moving/exporting the downloaded sdk into it
- export ANDROID_HOME="${PWD}/android-sdk-root" - export ANDROID_HOME="${PWD}/android-sdk-root"
# Create a new directory at specified location
- install -d $ANDROID_HOME - install -d $ANDROID_HOME
# Here we are installing androidSDK tools from official source,
# (the key thing here is the url from where you are downloading these sdk tool for command line, so please do note this url pattern there and here as well)
# after that unzipping those tools and
# then running a series of SDK manager commands to install necessary android SDK packages that'll allow the app to build
- wget --no-verbose --output-document=$ANDROID_HOME/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS}_latest.zip - wget --no-verbose --output-document=$ANDROID_HOME/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS}_latest.zip
- unzip -q -d "$ANDROID_HOME/cmdline-tools" "$ANDROID_HOME/cmdline-tools.zip" - unzip -q -d "$ANDROID_HOME/cmdline-tools" "$ANDROID_HOME/cmdline-tools.zip"
- mv -T "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/tools" - mv -T "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/tools"
- export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/cmdline-tools/tools/bin - export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/cmdline-tools/tools/bin
# Nothing fancy here, just checking sdkManager version
- sdkmanager --version - sdkmanager --version
# use yes to accept all licenses
- yes | sdkmanager --licenses > /dev/null || true - yes | sdkmanager --licenses > /dev/null || true
- sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}" - sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}"
- sdkmanager "platform-tools" - sdkmanager "platform-tools"
- sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}" - sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}"
# Not necessary, but just for surity
- chmod +x ./gradlew - chmod +x ./gradlew
# Basic android and gradle stuff
# Check linting
lintDebug: lintDebug:
interruptible: true interruptible: true
stage: build stage: build
@@ -69,7 +37,6 @@ lintDebug:
expose_as: "lint-report" expose_as: "lint-report"
when: always when: always
# Make Project
assembleDebug: assembleDebug:
interruptible: true interruptible: true
stage: build stage: build
@@ -79,7 +46,67 @@ assembleDebug:
paths: paths:
- app/build/outputs/ - app/build/outputs/
# Run all tests, if any fails, interrupt the pipeline(fail it) # Job for building signed release APK for tags containing "release" on any branch
assembleRelease:
stage: build
script:
- |
if [[ "$CI_COMMIT_TAG" =~ release ]]; then
echo "Decoding keystore file from Base64"
# Debug: Print the first few characters of BASE64_KEYSTORE
echo "First 20 characters of BASE64_KEYSTORE: ${BASE64_KEYSTORE:0:20}..."
# Check if BASE64_KEYSTORE is a file path
if [[ "$BASE64_KEYSTORE" == /* ]] && [[ -f "$BASE64_KEYSTORE" ]]; then
echo "BASE64_KEYSTORE appears to be a file path. Reading content..."
BASE64_CONTENT=$(cat "$BASE64_KEYSTORE")
else
echo "BASE64_KEYSTORE is not a file path. Using as-is."
BASE64_CONTENT="$BASE64_KEYSTORE"
fi
# Remove any potential whitespace or newline characters
CLEANED_KEYSTORE=$(echo "$BASE64_CONTENT" | tr -d '[:space:]')
# Attempt to decode and save to a file
if echo "$CLEANED_KEYSTORE" | base64 -d > "$CI_PROJECT_DIR/app/keystore.jks" 2>/tmp/base64_error; then
echo "Keystore file decoded successfully"
else
echo "Error decoding keystore file:"
cat /tmp/base64_error
echo "First 20 characters of cleaned content: ${CLEANED_KEYSTORE:0:20}..."
exit 1
fi
# Check if the keystore file was created and has content
if [ -s "$CI_PROJECT_DIR/app/keystore.jks" ]; then
echo "Keystore file created successfully"
# Print file size for verification
ls -l "$CI_PROJECT_DIR/app/keystore.jks"
else
echo "Error: Keystore file is empty or not created"
exit 1
fi
echo "Building signed release APK"
./gradlew assembleRelease \
-Pandroid.injected.signing.store.file="$CI_PROJECT_DIR/app/keystore.jks" \
-Pandroid.injected.signing.store.password="$KEYSTORE_PASSWORD" \
-Pandroid.injected.signing.key.alias="$KEY_ALIAS" \
-Pandroid.injected.signing.key.password="$KEY_PASSWORD"
else
echo "Tag '$CI_COMMIT_TAG' does not contain 'release'. Skipping release build."
fi
artifacts:
paths:
- app/build/outputs/
expire_in: never
rules:
- if: $CI_COMMIT_TAG =~ /release/
when: always
- when: never
debugTests: debugTests:
needs: [lintDebug, assembleDebug] needs: [lintDebug, assembleDebug]
interruptible: true interruptible: true

View File

@@ -2,3 +2,4 @@
### Release key ### Release key
key0: prime24 key0: prime24

View File

@@ -15,13 +15,13 @@ android {
namespace 'in.sminnovations.hpostesting' namespace 'in.sminnovations.hpostesting'
// dev -> development, quality -> qc, uat -> User Acceptance Testing, preprod -> preproduction, prod -> production, iocl -> iocl-iisc production // dev -> development, quality -> qc, uat -> User Acceptance Testing, preprod -> preproduction, prod -> production, iocl -> iocl-iisc production
// server -> for server switching for internal test
defaultConfig { defaultConfig {
applicationId "in.sminnovations.hpostesting.dev" applicationId "in.sminnovations.hpostesting.server"
minSdk 21 minSdk 21
targetSdk 34 targetSdk 34
versionCode 128 versionCode 132
versionName "2.1.128" versionName "2.1.130.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -124,7 +124,6 @@ dependencies {
implementation 'com.github.mik3y:usb-serial-for-android:3.8.0' implementation 'com.github.mik3y:usb-serial-for-android:3.8.0'
implementation "androidx.fragment:fragment-ktx:1.6.2" implementation "androidx.fragment:fragment-ktx:1.6.2"
// CSV read, write // CSV read, write
implementation 'com.opencsv:opencsv:5.9' implementation 'com.opencsv:opencsv:5.9'

View File

@@ -7,178 +7,9 @@
"client": [ "client": [
{ {
"client_info": { "client_info": {
"mobilesdk_app_id": "1:650071678820:android:f1435a1c07f710036c6471", "mobilesdk_app_id": "1:650071678820:android:f6fd45e2f6a63aef6c6471",
"android_client_info": { "android_client_info": {
"package_name": "com.example.hposconsentform" "package_name": "in.sminnovations.hpostesting.server"
}
},
"oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:7865bef608cdee6f6c6471",
"android_client_info": {
"package_name": "com.smi.counselling"
}
},
"oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:2925e9ce3417d2386c6471",
"android_client_info": {
"package_name": "in.sminnovations.hemocube"
}
},
"oauth_client": [
{
"client_id": "650071678820-srhm9spm9hjn4frcd3r6o02gdhdbtd15.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "in.sminnovations.hemocube",
"certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a"
}
},
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:7569c1cad4fc99916c6471",
"android_client_info": {
"package_name": "in.sminnovations.hposregistration"
}
},
"oauth_client": [
{
"client_id": "650071678820-70kp5jvjda4r5diqch2kn4lc40p4f42g.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "in.sminnovations.hposregistration",
"certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a"
}
},
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:f96be19e5d43102b6c6471",
"android_client_info": {
"package_name": "in.sminnovations.hpostesting"
}
},
"oauth_client": [
{
"client_id": "650071678820-l87dnr0bdj95get0khgnvfv2an1k6ogq.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "in.sminnovations.hpostesting",
"certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a"
}
},
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:a53292637abb7c0d6c6471",
"android_client_info": {
"package_name": "in.sminnovations.hpostesting.dev"
} }
}, },
"oauth_client": [ "oauth_client": [

View File

@@ -11,8 +11,8 @@
"type": "SINGLE", "type": "SINGLE",
"filters": [], "filters": [],
"attributes": [], "attributes": [],
"versionCode": 128, "versionCode": 127,
"versionName": "2.1.128", "versionName": "2.1.127",
"outputFile": "app-release.apk" "outputFile": "app-release.apk"
} }
], ],

View File

@@ -25,6 +25,12 @@
<uses-permission android:name="android.permission.USB_PERMISSION" /> <uses-permission android:name="android.permission.USB_PERMISSION" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.ACCOUNT_MANAGER"
tools:ignore="ProtectedPermissions" />
<application <application
android:name="com.example.hpostesting.HPOSTestingApplication" android:name="com.example.hpostesting.HPOSTestingApplication"
android:allowBackup="true" android:allowBackup="true"
@@ -84,7 +90,7 @@
android:theme="@style/Theme.HPOS.NoActionBar" /> android:theme="@style/Theme.HPOS.NoActionBar" />
<activity <activity
android:name="com.example.hpostesting.presentation.jig.JigActivity" android:name="com.example.hpostesting.presentation.jig.JigActivity"
android:exported="false" android:exported="true"
android:theme="@style/Theme.HPOS.NoActionBar" /> android:theme="@style/Theme.HPOS.NoActionBar" />
<activity <activity
android:name="com.example.hpostesting.presentation.deviceprovision.DeviceProvisionActivity" android:name="com.example.hpostesting.presentation.deviceprovision.DeviceProvisionActivity"
@@ -128,7 +134,7 @@
android:theme="@style/Theme.HPOS.NoActionBar" /> android:theme="@style/Theme.HPOS.NoActionBar" />
<activity <activity
android:name="com.example.hpostesting.presentation.dashboard.DashboardActivity" android:name="com.example.hpostesting.presentation.dashboard.DashboardActivity"
android:exported="false" android:exported="true"
android:label="@string/title_activity_dashboard" android:label="@string/title_activity_dashboard"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/Theme.HPOS.NoActionBar" android:theme="@style/Theme.HPOS.NoActionBar"
@@ -170,7 +176,7 @@
</activity> </activity>
<activity <activity
android:name="com.example.hpostesting.presentation.testRight.TestRightActivity" android:name="com.example.hpostesting.presentation.testRight.TestRightActivity"
android:exported="false" android:exported="true"
android:noHistory="true" android:noHistory="true"
android:parentActivityName="com.example.hpostesting.presentation.MainActivity" android:parentActivityName="com.example.hpostesting.presentation.MainActivity"
android:theme="@style/Theme.HPOS.NoActionBar" android:theme="@style/Theme.HPOS.NoActionBar"

View File

@@ -14,25 +14,29 @@
package com.example.hpostesting package com.example.hpostesting
import android.app.Application import android.app.Application
import com.example.hpostesting.firebase.FirebaseManager
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.FirebaseFirestoreSettings import com.google.firebase.firestore.FirebaseFirestoreSettings
import dagger.hilt.android.HiltAndroidApp import dagger.hilt.android.HiltAndroidApp
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import javax.inject.Inject
@HiltAndroidApp @HiltAndroidApp
class HPOSTestingApplication : Application() { class HPOSTestingApplication : Application() {
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) @Inject
lateinit var firebaseManager: FirebaseManager
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
// You can now use firebaseManager here after Hilt injects it
val firestoreSettings = FirebaseFirestoreSettings.Builder() val firestoreSettings = FirebaseFirestoreSettings.Builder()
.setPersistenceEnabled(true) // Enable offline persistence if needed .setPersistenceEnabled(true) // Enable offline persistence if needed
.build() .build()
val firestore = FirebaseFirestore.getInstance() val firestore = firebaseManager.getCurrentFirestore()
firestore.firestoreSettings = firestoreSettings firestore.firestoreSettings = firestoreSettings
} }
} }

View File

@@ -14,6 +14,9 @@
package com.example.hpostesting.data.repository package com.example.hpostesting.data.repository
import android.net.Uri import android.net.Uri
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.example.hpostesting.util.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.api.MolbioAuthApi import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi import com.example.hpostesting.data.api.MolbioResultApi
@@ -37,17 +40,18 @@ import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.updates.CheckUpdateRequest import com.example.hpostesting.data.model.updates.CheckUpdateRequest
import com.example.hpostesting.data.model.updates.CheckUpdateResponse import com.example.hpostesting.data.model.updates.CheckUpdateResponse
import com.example.hpostesting.data.model.updates.DeviceUpdateRequest import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import com.example.hpostesting.firebase.FirebaseManager
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import com.google.firebase.storage.ktx.storage import com.google.firebase.storage.FirebaseStorage
import kotlinx.coroutines.tasks.await import kotlinx.coroutines.tasks.await
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.ResponseBody import okhttp3.ResponseBody
import java.io.File import java.io.File
import java.net.ConnectException import java.net.ConnectException
import java.net.SocketTimeoutException import java.net.SocketTimeoutException
import java.time.LocalTime
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Named import javax.inject.Named
@@ -55,11 +59,30 @@ class NetworkException(message: String, cause: Throwable) : Exception(message, c
class DatabaseRepository @Inject constructor( class DatabaseRepository @Inject constructor(
@Named("Auth") private val molbioAuthApi: MolbioAuthApi, @Named("Auth") private val molbioAuthApi: MolbioAuthApi,
private val molbioResultApi: MolbioResultApi, private val molbioResultApi: MolbioResultApi,
private val firebaseManager: FirebaseManager,
) : Repository { ) : Repository {
private val db: FirebaseFirestore = Firebase.firestore private val localdb: FirebaseFirestore
private val storage = Firebase.storage get() = firebaseManager.getCurrentFirestore()
private val localStg: FirebaseStorage
get() = firebaseManager.getCurrentStorage()
// // Example function to add data to Firestore , like the basic data as test data
// @RequiresApi(Build.VERSION_CODES.O)
// fun addtodb(data: String) {
// val date = LocalTime.now()
// localdb.collection("BasicData")
// .add(mapOf("data $date" to data))
// .addOnSuccessListener {
// Log.d("UPLOAD", "Data uploaded successfully ${localdb.app.name}")
// }
// .addOnFailureListener { exception ->
// Log.d("UPLOAD", "Failed to upload data: ${exception.message} ${localdb.app.name}")
// }
// }
private suspend fun <T : Any> safeApiCall(apiCall: suspend () -> T): Result<T> { private suspend fun <T : Any> safeApiCall(apiCall: suspend () -> T): Result<T> {
return try { return try {
val response = apiCall.invoke() val response = apiCall.invoke()
@@ -108,13 +131,13 @@ class DatabaseRepository @Inject constructor(
override suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String> { override suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String> {
return try { return try {
val userdata = val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await() localdb.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) { if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach { userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true) localdb.collection("patientData").document(it.id).update("testStatus", true)
} }
} }
db.collection("testData").add(data).await() localdb.collection("testData").add(data).await()
Response.Success(data._id) Response.Success(data._id)
} catch (e: Exception) { } catch (e: Exception) {
Response.Error(e) Response.Error(e)
@@ -123,7 +146,7 @@ class DatabaseRepository @Inject constructor(
override suspend fun addQcTestToDatabase(data: HemoCubeTestData?): Response<String> { override suspend fun addQcTestToDatabase(data: HemoCubeTestData?): Response<String> {
return try { return try {
db.collection("qcData").add(data!!).await() localdb.collection("qcData").add(data!!).await()
Response.Success(data._id) Response.Success(data._id)
} catch (e: Exception) { } catch (e: Exception) {
@@ -137,7 +160,7 @@ class DatabaseRepository @Inject constructor(
override suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response<String> { override suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response<String> {
return try { return try {
db.collection("buffers").add(data!!).await() localdb.collection("buffers").add(data!!).await()
Response.Success(data.kitno) Response.Success(data.kitno)
} catch (e: Exception) { } catch (e: Exception) {
Firebase.crashlytics.recordException(e) Firebase.crashlytics.recordException(e)
@@ -147,7 +170,7 @@ class DatabaseRepository @Inject constructor(
override suspend fun addDiagnostics(data: DiagnosticsData?): Response<String> { override suspend fun addDiagnostics(data: DiagnosticsData?): Response<String> {
return try { return try {
db.collection("diagnostics").add(data!!).await() localdb.collection("diagnostics").add(data!!).await()
Response.Success(data.deviceId) Response.Success(data.deviceId)
} catch (e: Exception) { } catch (e: Exception) {
Firebase.crashlytics.recordException(e) Firebase.crashlytics.recordException(e)
@@ -158,7 +181,7 @@ class DatabaseRepository @Inject constructor(
override suspend fun addTestJigData(data: JigData?): Response<String> { override suspend fun addTestJigData(data: JigData?): Response<String> {
return try { return try {
db.collection("jigs").add(data!!).await() localdb.collection("jigs").add(data!!).await()
Response.Success(data.deviceId) Response.Success(data.deviceId)
} catch (e: Exception) { } catch (e: Exception) {
Firebase.crashlytics.recordException(e) Firebase.crashlytics.recordException(e)
@@ -172,7 +195,7 @@ class DatabaseRepository @Inject constructor(
try { try {
val file = Uri.fromFile(File(filePath)) val file = Uri.fromFile(File(filePath))
val riversRef = storage.reference.child("$patientID/${file.lastPathSegment}") val riversRef = localStg.reference.child("$patientID/${file.lastPathSegment}")
riversRef.putFile(file).await() riversRef.putFile(file).await()
return Response.Success(true) return Response.Success(true)
} catch (e: Exception) { } catch (e: Exception) {
@@ -183,7 +206,7 @@ class DatabaseRepository @Inject constructor(
suspend fun addToPendingQueue(pendingUploads: PendingUploads): Response<Boolean> { suspend fun addToPendingQueue(pendingUploads: PendingUploads): Response<Boolean> {
return try { return try {
db.collection("pendingUploads").document(pendingUploads.pendingId).set(pendingUploads) localdb.collection("pendingUploads").document(pendingUploads.pendingId).set(pendingUploads)
.await() .await()
Response.Success(true) Response.Success(true)
@@ -196,7 +219,7 @@ class DatabaseRepository @Inject constructor(
suspend fun getAllFromPendingQueue(): List<PendingUploads> { suspend fun getAllFromPendingQueue(): List<PendingUploads> {
val pendingList = mutableListOf<PendingUploads>() val pendingList = mutableListOf<PendingUploads>()
return try { return try {
val querySnapshot = db.collection("pendingUploads").orderBy("timeAdded").get().await() val querySnapshot = localdb.collection("pendingUploads").orderBy("timeAdded").get().await()
for (doc in querySnapshot.documents) { for (doc in querySnapshot.documents) {
val pendingFile = doc.toObject(PendingUploads::class.java) val pendingFile = doc.toObject(PendingUploads::class.java)
@@ -214,7 +237,7 @@ class DatabaseRepository @Inject constructor(
suspend fun removeFromPendingQueue(fileName: String): Response<Boolean> { suspend fun removeFromPendingQueue(fileName: String): Response<Boolean> {
return try { return try {
db.collection("pendingUploads").document(fileName).delete().await() localdb.collection("pendingUploads").document(fileName).delete().await()
Response.Success(true) Response.Success(true)
} catch (e: Exception) { } catch (e: Exception) {
@@ -224,11 +247,11 @@ class DatabaseRepository @Inject constructor(
} }
suspend fun getDeviceData(): List<DeviceData> { suspend fun getDeviceData(): List<DeviceData> {
return db.collection("devices").get().await().toObjects(DeviceData::class.java) return localdb.collection("devices").get().await().toObjects(DeviceData::class.java)
} }
override suspend fun getDeviceDataById(deviceId: String): DeviceData? { override suspend fun getDeviceDataById(deviceId: String): DeviceData? {
val querySnapshot = db.collection("devices").get().await() val querySnapshot = localdb.collection("devices").get().await()
val allDeviceDataList = querySnapshot.toObjects(DeviceData::class.java) val allDeviceDataList = querySnapshot.toObjects(DeviceData::class.java)
// Find the DeviceData object with the specified deviceId // Find the DeviceData object with the specified deviceId
@@ -237,7 +260,7 @@ class DatabaseRepository @Inject constructor(
override suspend fun getDeviceResponse(data: DeviceData?): Response<String> { override suspend fun getDeviceResponse(data: DeviceData?): Response<String> {
return try { return try {
db.collection("devices").add(data!!).await() localdb.collection("devices").add(data!!).await()
Response.Success(data.deviceProvisionResponse) Response.Success(data.deviceProvisionResponse)
} catch (e: Exception) { } catch (e: Exception) {
Firebase.crashlytics.recordException(e) Firebase.crashlytics.recordException(e)
@@ -247,7 +270,7 @@ class DatabaseRepository @Inject constructor(
override suspend fun uploadDeviceId(data: DeviceData): Response<String>? { override suspend fun uploadDeviceId(data: DeviceData): Response<String>? {
return try { return try {
db.collection("devices").add(data!!).await() localdb.collection("devices").add(data!!).await()
Response.Success(data.deviceId) Response.Success(data.deviceId)
} catch (e: Exception) { } catch (e: Exception) {
Firebase.crashlytics.recordException(e) Firebase.crashlytics.recordException(e)
@@ -262,13 +285,13 @@ class DatabaseRepository @Inject constructor(
override suspend fun addTestToDatabasefornew(data: HemoCubeTestData?): Response<String> { override suspend fun addTestToDatabasefornew(data: HemoCubeTestData?): Response<String> {
return try { return try {
val userdata = val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await() localdb.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) { if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach { userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true) localdb.collection("patientData").document(it.id).update("testStatus", true)
} }
} }
db.collection("testData").add(data).await() localdb.collection("testData").add(data).await()
Response.Success(data._id) Response.Success(data._id)
} catch (e: Exception) { } catch (e: Exception) {
Firebase.crashlytics.recordException(e) Firebase.crashlytics.recordException(e)

View File

@@ -21,7 +21,6 @@ import androidx.room.Room
import com.example.hpostesting.data.api.MolbioAuthApi import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi import com.example.hpostesting.data.api.MolbioResultApi
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.util.PropertyProvider
import com.example.hpostesting.data.dao.HemoCubeBufferDao import com.example.hpostesting.data.dao.HemoCubeBufferDao
import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.dao.MyDatabase import com.example.hpostesting.data.dao.MyDatabase
@@ -36,9 +35,13 @@ import com.example.hpostesting.domain.LogFileManager
import com.example.hpostesting.domain.LogFileManagerImpl import com.example.hpostesting.domain.LogFileManagerImpl
import com.example.hpostesting.domain.SaveRawData import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.firebase.FirebaseManager
import com.example.hpostesting.presentation.utils.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListenerImpl import com.example.hpostesting.presentation.utils.UsbServiceListenerImpl
import com.example.hpostesting.util.PropertyProvider
import com.example.hpostesting.util.PropertyProviderImpl import com.example.hpostesting.util.PropertyProviderImpl
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.storage.FirebaseStorage
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
@@ -107,22 +110,52 @@ object AppModule {
return SaveRawDataTest(repository) return SaveRawDataTest(repository)
} }
@Provides
@Singleton
fun provideFirebaseFirestore(): FirebaseFirestore {
return FirebaseFirestore.getInstance()
}
@Provides
@Singleton
fun provideFirebaseStorage(): FirebaseStorage {
return FirebaseStorage.getInstance()
}
@Provides
@Singleton
fun provideFirebaseManager(
@ApplicationContext context: Context,
): FirebaseManager {
return FirebaseManager(context)
}
@Provides @Provides
@Singleton @Singleton
fun provideDatabaseRepository( fun provideDatabaseRepository(
firebaseManager: FirebaseManager,
@Named("Auth") molbioAuthApi: MolbioAuthApi, @Named("Auth") molbioAuthApi: MolbioAuthApi,
molbioResultApi: MolbioResultApi molbioResultApi: MolbioResultApi
): DatabaseRepository { ): DatabaseRepository {
return DatabaseRepository(molbioAuthApi = molbioAuthApi, molbioResultApi = molbioResultApi) return DatabaseRepository(
firebaseManager = firebaseManager,
molbioAuthApi = molbioAuthApi,
molbioResultApi = molbioResultApi
)
} }
@Provides @Provides
@Singleton @Singleton
fun provideRepository( fun provideRepository(
firebaseManager: FirebaseManager,
@Named("Auth") molbioAuthApi: MolbioAuthApi, @Named("Auth") molbioAuthApi: MolbioAuthApi,
molbioResultApi: MolbioResultApi molbioResultApi: MolbioResultApi
): Repository { ): Repository {
return DatabaseRepository(molbioAuthApi, molbioResultApi) return DatabaseRepository(
firebaseManager = firebaseManager,
molbioAuthApi = molbioAuthApi,
molbioResultApi = molbioResultApi
)
} }
@Provides @Provides
@@ -206,4 +239,9 @@ object AppModule {
fun provideUsbServiceListener(context: Context): UsbServiceListener { fun provideUsbServiceListener(context: Context): UsbServiceListener {
return UsbServiceListenerImpl(context) return UsbServiceListenerImpl(context)
} }
} }

View File

@@ -0,0 +1,153 @@
package com.example.hpostesting.firebase
/*
* // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
* // Notice: All information contained herein is, and remains
* // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
* // if any. The intellectual and technical concepts contained
* // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
* // and its suppliers and may be covered by Indian and Foreign Patents,
* // patents in process, and are protected by trade secret or copyright law.
* // Dissemination of this information or reproduction of this material
* // is strictly forbidden unless prior written permission is obtained
* // from ShanMukha Innovations Pvt. Ltd.
*/
import android.content.Context
import android.content.Intent
import android.os.Process
import com.google.firebase.FirebaseApp
import com.google.firebase.FirebaseOptions
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.storage.FirebaseStorage
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import javax.inject.Inject
class FirebaseManager @Inject constructor(private val context: Context) {
private val sharedPreferences =
context.getSharedPreferences("FirebaseConfigPrefs", Context.MODE_PRIVATE)
private var currentFirestore: FirebaseFirestore = FirebaseFirestore.getInstance()
private var currentStorage: FirebaseStorage = FirebaseStorage.getInstance()
var updateStatus = false
private val defaultServers = listOf(
// i have it in different place look down
firebaseConfig1, firebaseConfig2, firebaseConfig3,
)
init {
val lastSelectedServer = getLastSelectedServer()
switchServer(lastSelectedServer)
}
fun getCurrentFirestore(): FirebaseFirestore = currentFirestore
fun getCurrentStorage(): FirebaseStorage = currentStorage
fun switchServer(firebaseConfig: FirebaseConfig) {
saveSelectedServer(firebaseConfig)
val firebaseApp = getOrInitializeFirebaseApp(firebaseConfig)
currentFirestore = FirebaseFirestore.getInstance(firebaseApp)
currentStorage = FirebaseStorage.getInstance(firebaseApp)
updateStatus = true
}
private fun getOrInitializeFirebaseApp(firebaseConfig: FirebaseConfig): FirebaseApp {
val existingApp = FirebaseApp.getApps(context).find { it.name == firebaseConfig.serverName }
return if (existingApp != null) {
existingApp
} else {
val options = FirebaseOptions.Builder().setProjectId(firebaseConfig.projectId)
.setApplicationId(firebaseConfig.appId).setApiKey(firebaseConfig.apiKey)
.setStorageBucket(firebaseConfig.storageBucket).build()
FirebaseApp.initializeApp(context, options, firebaseConfig.serverName)
}
}
private fun saveSelectedServer(firebaseConfig: FirebaseConfig) {
with(sharedPreferences.edit()) {
putString("selectedServerName", firebaseConfig.serverName)
putString("projectId", firebaseConfig.projectId)
putString("appId", firebaseConfig.appId)
putString("apiKey", firebaseConfig.apiKey)
putString("storageBucket", firebaseConfig.storageBucket)
apply()
}
}
fun restartApp() {
if (updateStatus) {
updateStatus = false
delayedRestart(context)
}
}
fun getLastSelectedServer(): FirebaseConfig {
val selectedServerName =
sharedPreferences.getString("selectedServerName", defaultServers.first().serverName)
val projectId = sharedPreferences.getString("projectId", defaultServers.first().projectId)
val appId = sharedPreferences.getString("appId", defaultServers.first().appId)
val apiKey = sharedPreferences.getString("apiKey", defaultServers.first().apiKey)
val storageBucket =
sharedPreferences.getString("storageBucket", defaultServers.first().storageBucket)
return FirebaseConfig(
serverName = selectedServerName ?: defaultServers.first().serverName,
projectId = projectId ?: defaultServers.first().projectId,
appId = appId ?: defaultServers.first().appId,
apiKey = apiKey ?: defaultServers.first().apiKey,
storageBucket = storageBucket ?: defaultServers.first().storageBucket
)
}
fun getAvailableServers(): List<FirebaseConfig> {
return defaultServers
}
}
fun restartApp(context: Context) {
val intent = context.packageManager.getLaunchIntentForPackage(context.packageName)
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
Process.killProcess(Process.myPid())
}
@OptIn(DelicateCoroutinesApi::class)
fun delayedRestart(context: Context) {
GlobalScope.launch(Dispatchers.Main) {
delay(5000L)
restartApp(context)
}
}
private val firebaseConfig1 = FirebaseConfig(
serverName = "dev",
apiKey = "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I",
appId = "1:650071678820:android:a53292637abb7c0d6c6471",
projectId = "hpos-af3cc",
storageBucket = "hpos-af3cc.appspot.com"
)
private val firebaseConfig2 = FirebaseConfig(
serverName = "qc-qa",
apiKey = "AIzaSyC4d4GhWHr_NMJAeBvnztQ_yQ3Qe9MAnLs",
appId = "1:1004619739289:android:3dbcefb10ea99654e5c808",
projectId = "hpos-qa",
storageBucket = "hpos-qa.appspot.com"
)
private val firebaseConfig3 = FirebaseConfig(
serverName = "prod",
apiKey = "AIzaSyDYySi27LioZGNisP1NfnNU5inJX_0FT38",
appId = "1:121176529204:android:a7bc0842f61e5095bbed61",
projectId = "hpos-preprod",
storageBucket = "hpos-preprod.appspot.com"
)

View File

@@ -0,0 +1,21 @@
package com.example.hpostesting.firebase
/*
* // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
* // Notice: All information contained herein is, and remains
* // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
* // if any. The intellectual and technical concepts contained
* // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
* // and its suppliers and may be covered by Indian and Foreign Patents,
* // patents in process, and are protected by trade secret or copyright law.
* // Dissemination of this information or reproduction of this material
* // is strictly forbidden unless prior written permission is obtained
* // from ShanMukha Innovations Pvt. Ltd.
*/
data class FirebaseConfig(
val serverName: String,
val apiKey: String,
val appId: String,
val projectId: String,
val storageBucket: String
)

View File

@@ -145,19 +145,22 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
val time = timeDifference(sharedPreference.getString(Constants.KIT_TIME, "").toString()) val time = timeDifference(sharedPreference.getString(Constants.KIT_TIME, "").toString())
val kitNum = sharedPreference.getString(Constants.KIT_NUMBER, "").toString() val kitNum = sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
// Toast.makeText(this@KitScanActivity,"Test MAx time"+ time+"-Test count-"+kitNum,Toast.LENGTH_SHORT).show() // Toast.makeText(this@KitScanActivity,"Test MAx time"+ time+"-Test count-"+kitNum,Toast.LENGTH_SHORT).show()
if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") {
if (DataHolder.sampleReadCounter <= maxTest && kitNum != "" && time < Constants.MAX_KIT_TIME) {
moveToNext() moveToNext()
} else { }else{
Toast.makeText(this@KitScanActivity, "Limit Reached, Use New KIT for testing", Toast.LENGTH_SHORT).show() if (DataHolder.sampleReadCounter <= maxTest && kitNum != "" && time < Constants.MAX_KIT_TIME) {
DataHolder.sampleReadCounter = 0 moveToNext()
DataHolder.kitSerial = "" } else {
Toast.makeText(this@KitScanActivity, "Limit Reached, Use New KIT for testing", Toast.LENGTH_SHORT).show()
DataHolder.sampleReadCounter = 0
DataHolder.kitSerial = ""
with(sharedPreference.edit()) { with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "") putString(Constants.KIT_NUMBER, "")
putString(Constants.BUFFER_VALUE_1, "") putString(Constants.BUFFER_VALUE_1, "")
putString(Constants.BUFFER_VALUE_2, "") putString(Constants.BUFFER_VALUE_2, "")
apply() apply()
}
} }
} }

View File

@@ -18,6 +18,7 @@ import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.content.SharedPreferences
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.hardware.usb.UsbManager import android.hardware.usb.UsbManager
import android.location.Location import android.location.Location
@@ -30,10 +31,9 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.test.TestType import com.example.hpostesting.data.model.test.TestType
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.FusedLocationProviderClient
@@ -48,12 +48,12 @@ import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityMainBinding import `in`.sminnovations.hpostesting.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
private var myMenu: Menu? = null private var myMenu: Menu? = null
private val TAG = "MainActivity" private val TAG = "MainActivity"
private lateinit var fusedLocationClient: FusedLocationProviderClient private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var locationCallback: LocationCallback private lateinit var locationCallback: LocationCallback
private lateinit var sharedPreference: SharedPreferences
private val usbReceiver = object : BroadcastReceiver() { private val usbReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent) { override fun onReceive(context: Context?, intent: Intent) {
@@ -73,14 +73,21 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
sharedPreference = getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
binding.myToolbar.title = "Test Type" binding.myToolbar.title = "Test Type"
setSupportActionBar(binding.myToolbar) setSupportActionBar(binding.myToolbar)
if ((sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN")) {
binding.cvItem3.visibility = View.VISIBLE
}else{
binding.cvItem3.visibility = View.GONE
}
setupListeners() setupListeners()
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
getLocation() getLocation()
locationCallback = object : LocationCallback() { locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) { override fun onLocationResult(locationResult: LocationResult) {
locationResult.lastLocation?.let { location -> locationResult.lastLocation?.let { location ->
@@ -92,7 +99,6 @@ class MainActivity : AppCompatActivity() {
} }
} }
} }
val usbFilter = IntentFilter().apply { val usbFilter = IntentFilter().apply {
addAction(UsbManager.ACTION_USB_DEVICE_DETACHED) addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED) addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
@@ -117,6 +123,7 @@ class MainActivity : AppCompatActivity() {
// } // }
} }
private fun checkAndUpdateUsbConnection() { private fun checkAndUpdateUsbConnection() {
val availableDrivers = UsbSerialProber.getDefaultProber() val availableDrivers = UsbSerialProber.getDefaultProber()
.findAllDrivers(getSystemService(Context.USB_SERVICE) as UsbManager) .findAllDrivers(getSystemService(Context.USB_SERVICE) as UsbManager)

View File

@@ -14,25 +14,17 @@
package com.example.hpostesting.presentation.dashboard package com.example.hpostesting.presentation.dashboard
import android.content.Context import android.content.Context
import android.content.SharedPreferences
import android.os.BatteryManager import android.os.BatteryManager
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.presentation.adapter.OfflineUserListAdapter import com.example.hpostesting.presentation.adapter.OfflineUserListAdapter
import com.example.hpostesting.presentation.adapter.UserListAdapter
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentActivitiesBinding import `in`.sminnovations.hpostesting.databinding.FragmentActivitiesBinding
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
@@ -58,7 +50,7 @@ class ActivitiesFragment : Fragment() {
if (userData.isNotEmpty()) { if (userData.isNotEmpty()) {
userData.forEach { user -> userData.forEach { user ->
if((isBetween15And30Minutes(user.incubationTime) > 30 || isBetween15And30Minutes(user.incubationTime) < 0) && user.testStatus == false){ if((isBetween15And30Minutes(user.incubationTime) > 30 || isBetween15And30Minutes(user.incubationTime) < 0 ) && user.testStatus == false){
hemoCubeViewModel.deleteByStatus() hemoCubeViewModel.deleteByStatus()
} }
} }

View File

@@ -0,0 +1,18 @@
package com.example.hpostesting.presentation.dashboard
class AppVersionTapManager {
private var tapCount = 0
private val maxTapCount = 5
fun registerTap(onMaxTapsReached: () -> Unit) {
tapCount++
if (tapCount >= maxTapCount) {
onMaxTapsReached()
reset()
}
}
private fun reset() {
tapCount = 0
}
}

View File

@@ -33,19 +33,15 @@ import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.login.LoginRequest
import com.example.hpostesting.data.model.updates.DeviceUpdateRequest import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import com.example.hpostesting.presentation.utils.NatsManager import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.firebase.FirebaseManager
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.jig.JigActivity import com.example.hpostesting.presentation.jig.JigActivity
import com.example.hpostesting.presentation.utils.NatsManager
import com.google.android.material.navigation.NavigationView import com.google.android.material.navigation.NavigationView
import com.google.firebase.appdistribution.FirebaseAppDistribution
import com.google.firebase.appdistribution.FirebaseAppDistributionException
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import com.google.firebase.remoteconfig.FirebaseRemoteConfig import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.remoteconfig.ktx.remoteConfig import com.google.firebase.remoteconfig.ktx.remoteConfig
@@ -56,6 +52,7 @@ import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
import java.io.File import java.io.File
import java.security.MessageDigest import java.security.MessageDigest
import javax.inject.Inject
interface NatsMessageCallback { interface NatsMessageCallback {
fun onMessageReceived(topic: String, message: String) fun onMessageReceived(topic: String, message: String)
@@ -68,6 +65,8 @@ open interface IDataCollector: NatsMessageCallback {
@AndroidEntryPoint @AndroidEntryPoint
class DashboardActivity : AppCompatActivity(), IDataCollector { class DashboardActivity : AppCompatActivity(), IDataCollector {
@Inject
lateinit var databaseRepository: DatabaseRepository
private val remoteConfig: FirebaseRemoteConfig = Firebase.remoteConfig private val remoteConfig: FirebaseRemoteConfig = Firebase.remoteConfig
val TAG = "DashboardActivity" val TAG = "DashboardActivity"
private var isRegistered = false private var isRegistered = false
@@ -76,6 +75,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
lateinit var sharedPreferences: SharedPreferences lateinit var sharedPreferences: SharedPreferences
var responses: String = "" var responses: String = ""
lateinit var nats: NatsManager lateinit var nats: NatsManager
private var downloadId: Long = 0 private var downloadId: Long = 0
// TODO: Remove hemocube viewmodel // TODO: Remove hemocube viewmodel
private val hemocubeViewModel: HemoCubeViewModel by viewModels() private val hemocubeViewModel: HemoCubeViewModel by viewModels()
@@ -86,6 +86,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
super.attachBaseContext(newBase) super.attachBaseContext(newBase)
} }
override fun onMessageReceived(topic: String, message: String) { override fun onMessageReceived(topic: String, message: String) {
// Handle incoming messages from NATS // Handle incoming messages from NATS
@@ -95,11 +96,15 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
@SuppressLint("SetWorldReadable") @SuppressLint("SetWorldReadable")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val firebaseManager = FirebaseManager(this)
binding = ActivityDashboardBinding.inflate(layoutInflater) binding = ActivityDashboardBinding.inflate(layoutInflater)
sharedPreferences = this.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) sharedPreferences = this.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
setContentView(binding.root) setContentView(binding.root)
setSupportActionBar(binding.appBarDashboard.toolbar) setSupportActionBar(binding.appBarDashboard.toolbar)
nats = NatsManager(this) nats = NatsManager(this)
val currentServer = firebaseManager.getLastSelectedServer().serverName
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
nats.connect() nats.connect()
} }
@@ -108,7 +113,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
Log.d("DashboardActivity", "Saved Kit Serial: $savedKitSerial") Log.d("DashboardActivity", "Saved Kit Serial: $savedKitSerial")
// Toast.makeText(this, "Saved Kit Serial: $savedKitSerial", Toast.LENGTH_SHORT).show() // Toast.makeText(this, "Saved Kit Serial: $savedKitSerial", Toast.LENGTH_SHORT).show()
val versionName = getAppVersion(this@DashboardActivity) + " [ " + getAppEnvironment(this@DashboardActivity) + " ]" val versionName = getAppVersion(this@DashboardActivity) + " [ " + getAppEnvironment(this@DashboardActivity) +"->"+currentServer+"]"
binding.appBarDashboard.versionName.text = versionName binding.appBarDashboard.versionName.text = versionName
@@ -250,6 +255,12 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
// fun sendData(data:String){ this was used to send the basic data for server validation
// databaseRepository.addtodb(data)
// Toast.makeText(this, "data uploaded", Toast.LENGTH_SHORT).show()
// }
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present. // Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.dashboard, menu) menuInflater.inflate(R.menu.dashboard, menu)
@@ -375,6 +386,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
return try { return try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0) val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
pInfo.versionName pInfo.versionName
} catch (e: PackageManager.NameNotFoundException) { } catch (e: PackageManager.NameNotFoundException) {
"N/A" "N/A"
} }

View File

@@ -864,6 +864,7 @@ class HomeFragment : Fragment() {
binding.userId.setText("") binding.userId.setText("")
binding.age.setText("") binding.age.setText("")
binding.etBloodGroup.setText("") binding.etBloodGroup.setText("")
// val userData = UserData(_id = userId) // val userData = UserData(_id = userId)
// DataHolder.selectedTest = userData // DataHolder.selectedTest = userData
// findNavController().navigate(R.id.action_nav_home_to_mainActivity) // findNavController().navigate(R.id.action_nav_home_to_mainActivity)

View File

@@ -13,6 +13,7 @@
package com.example.hpostesting.presentation.dashboard package com.example.hpostesting.presentation.dashboard
import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.pm.PackageManager import android.content.pm.PackageManager
@@ -23,7 +24,7 @@ import android.view.ViewGroup
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.Preference import androidx.preference.Preference
@@ -31,127 +32,231 @@ import androidx.preference.PreferenceFragmentCompat
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.TestState import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.data.model.patient.toHemoCubeTestData import com.example.hpostesting.firebase.FirebaseConfig
import com.example.hpostesting.firebase.FirebaseManager
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding
private var isLanguageChanged = false private var isLanguageChanged = false
class SlideshowFragment : Fragment(){ class SlideshowFragment : Fragment() {
private var selectedItem = "10mm" private var selectedItem = "10mm"
private val values = arrayOf("10mm", "2mm") private val values = arrayOf("10mm", "2mm")
private lateinit var binding: FragmentSlideshowBinding private lateinit var binding: FragmentSlideshowBinding
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View { ): View {
binding = FragmentSlideshowBinding.inflate(inflater, container, false) binding = FragmentSlideshowBinding.inflate(inflater, container, false)
sharedPreferences = sharedPreferences = requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
return binding.root return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
binding.nameEditText.setText(sharedPreferences.getString(Constants.LABNAME,"")) binding.nameEditText.setText(sharedPreferences.getString(Constants.LABNAME, ""))
selectedItem = sharedPreferences.getString(Constants.CUVETTE_SIZE,"10mm").toString() selectedItem = sharedPreferences.getString(Constants.CUVETTE_SIZE, "10mm").toString()
val time = sharedPreferences.getString(Constants.LAST_UPDATED,"NA").toString() val time = sharedPreferences.getString(Constants.LAST_UPDATED, "NA").toString()
binding.lastUpdated.text = "Last updated config: $time" binding.lastUpdated.text = "Last updated config: $time"
binding.btnGo.setOnClickListener { binding.btnGo.setOnClickListener {
var labname = binding.nameEditText.text.toString() var labname = binding.nameEditText.text.toString()
DataHolder.hemoCubeTestData?.apply { DataHolder.hemoCubeTestData?.apply {
this.labName = labname this.labName = labname
} }
with(sharedPreferences.edit()) { with(sharedPreferences.edit()) {
putString(Constants.LABNAME, labname) putString(Constants.LABNAME, labname)
apply() apply()
} }
Toast.makeText( Toast.makeText(
requireContext(), requireContext(), "Lab Name is Added successfully.", Toast.LENGTH_SHORT
"Lab Name is Added successfully.",
Toast.LENGTH_SHORT
).show() ).show()
} }
val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, values) val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, values)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
val pos: Int val pos: Int
if(selectedItem == "10mm"){ if (selectedItem == "10mm") {
pos = 0 pos = 0
}else{ } else {
pos = 1 pos = 1
} }
binding.spinnerCuvette.adapter = adapter binding.spinnerCuvette.adapter = adapter
binding.spinnerCuvette.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { binding.spinnerCuvette.onItemSelectedListener =
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { object : AdapterView.OnItemSelectedListener {
// Handle item selection here override fun onItemSelected(
selectedItem = values[position] parent: AdapterView<*>?, view: View?, position: Int, id: Long
} ) {
// Handle item selection here
selectedItem = values[position]
}
override fun onNothingSelected(parent: AdapterView<*>?) { override fun onNothingSelected(parent: AdapterView<*>?) {
// Do nothing here // Do nothing here
}
} }
}
binding.spinnerCuvette.setSelection(pos) binding.spinnerCuvette.setSelection(pos)
binding.btnAddSize.setOnClickListener { binding.btnAddSize.setOnClickListener {
with(sharedPreferences.edit()) { with(sharedPreferences.edit()) {
putString(Constants.CUVETTE_SIZE, selectedItem) putString(Constants.CUVETTE_SIZE, selectedItem)
apply() apply()
} }
Toast.makeText(requireContext(), "Selected cuvette size: $selectedItem", Toast.LENGTH_SHORT).show() Toast.makeText(
requireContext(), "Selected cuvette size: $selectedItem", Toast.LENGTH_SHORT
).show()
} }
childFragmentManager.beginTransaction().replace(binding.container.id,PrefsFragment()).commit() childFragmentManager.beginTransaction().replace(binding.container.id, PrefsFragment())
.commit()
} }
} }
class PrefsFragment: PreferenceFragmentCompat(){
class PrefsFragment : PreferenceFragmentCompat(){
private lateinit var tapManager: AppVersionTapManager
private var isServerSelectionVisible = false
private lateinit var serverPreference: Preference
private lateinit var currentServerPreference: Preference
lateinit var firebaseManager: FirebaseManager
lateinit var databaseRepository: DatabaseRepository
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
firebaseManager = FirebaseManager(requireContext())
databaseRepository = (activity as DashboardActivity).databaseRepository
tapManager = AppVersionTapManager()
val sharedPreference =
requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
val preferenceScreen = preferenceManager.createPreferenceScreen(requireContext()) val preferenceScreen = preferenceManager.createPreferenceScreen(requireContext())
val currentServer = firebaseManager.getLastSelectedServer().serverName
val languagePreference = ListPreference(requireContext()) // Language Preference
languagePreference.key = "language_preference" val languagePreference = ListPreference(requireContext()).apply {
languagePreference.title = getString(R.string.app_language) key = "language_preference"
languagePreference.summary = getString(R.string.select_language) title = getString(R.string.app_language)
languagePreference.entries = arrayOf("English", "Kannada", "Hindi") summary = getString(R.string.select_language)
languagePreference.entryValues = arrayOf("en", "kn", "hi") entries = arrayOf("English", "Kannada", "Hindi")
languagePreference.setDefaultValue("en") entryValues = arrayOf("en", "kn", "hi")
setDefaultValue("en")
icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_translate_24)
languagePreference.onPreferenceChangeListener = onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
Preference.OnPreferenceChangeListener { _, newValue ->
val languageCode = newValue as String val languageCode = newValue as String
updateLanguage(requireContext(), languageCode) updateLanguage(requireContext(), languageCode)
true true
} }
}
preferenceScreen.addPreference(languagePreference) preferenceScreen.addPreference(languagePreference)
setPreferenceScreen(preferenceScreen)
// App Version Preference val appVersionPreference = Preference(requireContext()).apply {
val appVersionPreference = Preference(requireContext()) title = "App Version"
appVersionPreference.title = "App Version" summary =
appVersionPreference.summary = getAppVersion(requireContext()) + " [ " + getAppEnvironment(requireContext()) +"->"+currentServer+"]"
getAppVersion(requireContext()) + " [ " + getAppEnvironment(requireContext()) + " ]" icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_info_24)
preferenceScreen.addPreference(languagePreference) setOnPreferenceClickListener {
if ((sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN")) {
tapManager.registerTap {
if (!isServerSelectionVisible) {
showServerSelection()
}
}
} else {
}
true
}
}
preferenceScreen.addPreference(appVersionPreference) preferenceScreen.addPreference(appVersionPreference)
currentServerPreference = Preference(requireContext()).apply {
key = "current_server_preference"
title = "Current Server"
summary = "No server selected"
isVisible = false
icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_cloud_done_24)
setOnPreferenceClickListener {
// (activity as? DashboardActivity)?.sendData("hello test data")
// Toast.makeText(context, "data sent", Toast.LENGTH_SHORT).show() this was used to send the basic data as test data
true
}
}
preferenceScreen.addPreference(currentServerPreference)
setPreferenceScreen(preferenceScreen) setPreferenceScreen(preferenceScreen)
if (isLanguageChanged) { if (isLanguageChanged) {
Toast.makeText(requireContext(), R.string.language_update, Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), R.string.language_update, Toast.LENGTH_SHORT).show()
} }
}
private fun showServerSelection() {
val currentServer = firebaseManager.getLastSelectedServer().serverName
serverPreference = Preference(requireContext()).apply {
title = "Select Server"
summary = "Choose your server"
icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_cloud_sync_24)
setOnPreferenceClickListener {
showServerSelectionDialog()
true
}
}
preferenceScreen.addPreference(serverPreference)
currentServerPreference.isVisible = true
currentServerPreference.summary = "Current Server: $currentServer"
Toast.makeText(requireContext(), "Server selection now available", Toast.LENGTH_SHORT).show()
}
private fun showServerSelectionDialog() {
val servers = firebaseManager.getAvailableServers()
val serverNames = servers.map { it.serverName }.toTypedArray()
val builder = AlertDialog.Builder(requireContext())
builder.setTitle("Select Server")
.setItems(serverNames) { _, which ->
val selectedServer = servers[which]
switchFirebaseServer(selectedServer)
}
.setNegativeButton("Cancel", null)
.show()
}
private fun switchFirebaseServer(firebaseConfig: FirebaseConfig) {
firebaseManager.switchServer(firebaseConfig)
Toast.makeText(requireContext(), "Switched to ${firebaseConfig.serverName}, Please wait for few seconds", Toast.LENGTH_SHORT).show()
Toast.makeText(requireContext(), "Restart needed restarting the app", Toast.LENGTH_SHORT).show()
firebaseManager.restartApp()
currentServerPreference.summary = "Current Server: ${firebaseConfig.serverName}"
} }
private fun switchCurrentServer(serverCode: String) {
Toast.makeText(requireContext(), "Switched to server: $serverCode", Toast.LENGTH_SHORT)
.show()
currentServerPreference.summary = "Current Server: $serverCode"
}
private fun updateLanguage(context: Context, languageCode: String) { private fun updateLanguage(context: Context, languageCode: String) {
LanguageManager.persistLanguagePreference(context, languageCode) LanguageManager.persistLanguagePreference(context, languageCode)
LanguageManager.setLocale(context, languageCode) LanguageManager.setLocale(context, languageCode)
requireActivity().recreate() // Recreate activity to apply language changes requireActivity().recreate()
isLanguageChanged = true isLanguageChanged = true
} }
private fun getAppVersion(context: Context): String { private fun getAppVersion(context: Context): String {
return try { return try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0) val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
@@ -170,3 +275,5 @@ class PrefsFragment: PreferenceFragmentCompat(){
} }
} }
} }

View File

@@ -33,19 +33,24 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.firebase.FirebaseManager
import com.example.hpostesting.util.UsbService import com.example.hpostesting.util.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber import com.hoho.android.usbserial.driver.UsbSerialProber
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityAutoDacBinding
import `in`.sminnovations.hpostesting.databinding.ActivityHbTestBinding import `in`.sminnovations.hpostesting.databinding.ActivityHbTestBinding
import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class HBTestActivity : AppCompatActivity() { class HBTestActivity : AppCompatActivity() {
@Inject
lateinit var databaseRepository: DatabaseRepository
private lateinit var binding: ActivityHbTestBinding private lateinit var binding: ActivityHbTestBinding
val viewModel: HBTestViewModel by viewModels() val viewModel: HBTestViewModel by viewModels()
private var myMenu: Menu? = null private var myMenu: Menu? = null
@@ -97,6 +102,10 @@ class HBTestActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val firebaseManager = FirebaseManager(this)
val lastSelectedServer = firebaseManager.getLastSelectedServer()
// switchFirebaseServer(lastSelectedServer)
Log.d("CURRENT SERVR......","server : ${lastSelectedServer.serverName}")
binding = ActivityHbTestBinding.inflate(layoutInflater) binding = ActivityHbTestBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
// setSupportActionBar(binding.myToolbar) // setSupportActionBar(binding.myToolbar)
@@ -105,7 +114,11 @@ class HBTestActivity : AppCompatActivity() {
connectUsb(false) connectUsb(false)
} }
// private fun switchFirebaseServer(config: FirebaseConfig) {
// val (newFirestore, newStorage) = firebaseManager.switchFirestoreServer(config)
// databaseRepository.switchServer(newFirestore, newStorage)
//// Toast.makeText(this, "server switched", Toast.LENGTH_SHORT).show()// Update repository with new Firestore and Storage
// }
private fun setupListener() { private fun setupListener() {
DataHolder.usbConnected.observe(this) { DataHolder.usbConnected.observe(this) {
Log.d("USB OBSERVE", "HemoCube called -> $it") Log.d("USB OBSERVE", "HemoCube called -> $it")

View File

@@ -117,7 +117,6 @@ class HBTestFragment : Fragment() {
testDetails.testTime = SimpleDateFormat( testDetails.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
//Toast.makeText(requireContext(), "deviceID"+deviceId, Toast.LENGTH_LONG).show()
hBTestViewModel.uploadFirebaseQc(testDetails) hBTestViewModel.uploadFirebaseQc(testDetails)
} }
binding.btnBuffer.setOnClickListener { binding.btnBuffer.setOnClickListener {
@@ -177,6 +176,7 @@ class HBTestFragment : Fragment() {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
data?.let { data?.let {
val stringData = String(it) val stringData = String(it)
//deviceId = stringData
hBTestViewModel.messages.postValue(stringData) hBTestViewModel.messages.postValue(stringData)
binding.tvSubtitle4.text = stringData binding.tvSubtitle4.text = stringData
} }
@@ -232,6 +232,7 @@ class HBTestFragment : Fragment() {
return matchResult?.groups?.get(1)?.value return matchResult?.groups?.get(1)?.value
} }
private fun listenToHemoCube() { private fun listenToHemoCube() {
val fullReadOutput = StringBuilder() val fullReadOutput = StringBuilder()
@@ -250,6 +251,7 @@ class HBTestFragment : Fragment() {
if (stringData.contains("SNE")) { if (stringData.contains("SNE")) {
val slData = stringData.split(" ") val slData = stringData.split(" ")
if (slData.size > 1) { if (slData.size > 1) {
val hardwareId = slData[1].trim()
deviceId = extractV2HardwareId(resultData).toString() deviceId = extractV2HardwareId(resultData).toString()
hBTestViewModel.messages.postValue("Place buffer and click below button to start test") hBTestViewModel.messages.postValue("Place buffer and click below button to start test")
// with(sharedPreferences.edit()) { // with(sharedPreferences.edit()) {

View File

@@ -184,6 +184,20 @@ class HemoCubeFragment : Fragment() {
binding.tvSubtitle4.movementMethod = ScrollingMovementMethod() binding.tvSubtitle4.movementMethod = ScrollingMovementMethod()
binding.tvDeviceMessages.movementMethod = ScrollingMovementMethod() binding.tvDeviceMessages.movementMethod = ScrollingMovementMethod()
binding.btnSubmit.setOnClickListener { binding.btnSubmit.setOnClickListener {
// with(sharedPreferences.edit()) {
// putBoolean(Constants.QUICK_CAPTURE, false)
// apply()
// }
// if(DataHolder.hemoCubeTestData!!.classificationResult != "Invalid"){
// DataHolder.sampleReadCounter++
// }
// binding.btnSubmit.isEnabled = false
// binding.btnSubmit.isClickable = false
// activity?.runOnUiThread {
// Log.d("HemoCubeFragment","Test Process completed, result saved")
// binding.progressBar.visibility = View.VISIBLE
// binding.btnSubmit.visibility = View.GONE
// }
submitClick = true submitClick = true
if(checkSubmit){ if(checkSubmit){
with(sharedPreferences.edit()) { with(sharedPreferences.edit()) {
@@ -208,7 +222,6 @@ class HemoCubeFragment : Fragment() {
binding.btnSubmit.isEnabled = true binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true binding.btnSubmit.isClickable = true
} }
} }
binding.tvTitle2.visibility = View.GONE binding.tvTitle2.visibility = View.GONE
@@ -689,6 +702,7 @@ class HemoCubeFragment : Fragment() {
binding.testing.visibility = View.GONE binding.testing.visibility = View.GONE
} }
} }
resultData.contains("#BS") && this.testStatusCode < TestStatus.BUFFER_STARTED.code -> { resultData.contains("#BS") && this.testStatusCode < TestStatus.BUFFER_STARTED.code -> {
hemoCubeViewModel.messages.postValue(getString(R.string.buffer_started)) hemoCubeViewModel.messages.postValue(getString(R.string.buffer_started))
this.testStatusCode = TestStatus.BUFFER_STARTED.code this.testStatusCode = TestStatus.BUFFER_STARTED.code
@@ -760,7 +774,6 @@ class HemoCubeFragment : Fragment() {
} }
} }
(resultData.contains("#SC") || resultData.contains("#SC1")) && this.testStatusCode < TestStatus.SAMPLE_COMPLETED.code -> { (resultData.contains("#SC") || resultData.contains("#SC1")) && this.testStatusCode < TestStatus.SAMPLE_COMPLETED.code -> {
this.testStatusCode = TestStatus.SAMPLE_COMPLETED.code this.testStatusCode = TestStatus.SAMPLE_COMPLETED.code
activity?.runOnUiThread { activity?.runOnUiThread {
@@ -774,7 +787,6 @@ class HemoCubeFragment : Fragment() {
fetchResult() fetchResult()
} }
resultData.contains("ovf") -> { resultData.contains("ovf") -> {
activity?.runOnUiThread { activity?.runOnUiThread {
binding.testing.visibility = View.GONE binding.testing.visibility = View.GONE
@@ -1381,7 +1393,7 @@ class HemoCubeFragment : Fragment() {
"%.3f".format( "%.3f".format(
borderlineMetric borderlineMetric
) )
} \n Remove Cuvette & Click Submit" }"
) )
if (DataHolder.hemoCubeTestData?.testType == "HB") if (DataHolder.hemoCubeTestData?.testType == "HB")
hemoCubeViewModel.messages.postValue("Hb: $calculatedHb4") hemoCubeViewModel.messages.postValue("Hb: $calculatedHb4")
@@ -1456,21 +1468,21 @@ class HemoCubeFragment : Fragment() {
if (deviceRatio != null && borderlineMetric != null) { if (deviceRatio != null && borderlineMetric != null) {
if(cuvetteSize == "10mm"){ if(cuvetteSize == "10mm"){
if (deviceRatioClass == "Negative Borderline") { if (deviceRatioClass == "Negative Borderline") {
if (borderlineMetric < negativeBoderLine10mm1){//1.34 if (borderlineMetric < negativeBoderLine10mm1){//2.0
return "Sickle Cell Trait" return "Sickle Cell Trait"
}else if(borderlineMetric > negativeBoderLine10mm1){ }else if(borderlineMetric > negativeBoderLine10mm1){
return "Normal" return "Normal"
}else if(borderlineMetric == negativeBoderLine10mm1){ }else if(borderlineMetric == negativeBoderLine10mm1){//borderlineMetric > negativeBoderLine10mm1 && borderlineMetric < negativeBoderLine10mm2
return "Sickle Cell Trait" return "Sickle Cell Trait"//"Negative borderline. Confirm with HPLC"
} }
} }
if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") { if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") {
if (borderlineMetric < positiveBoderLine10mm1){//1.34 if (borderlineMetric < positiveBoderLine10mm1){//1.3
return "Sickle Cell Disease" return "Sickle Cell Disease"
}else if(borderlineMetric > positiveBoderLine10mm1){ }else if(borderlineMetric > positiveBoderLine10mm1){
return "Sickle Cell Trait" return "Sickle Cell Trait"
}else if(borderlineMetric == positiveBoderLine10mm1){ }else if(borderlineMetric == positiveBoderLine10mm1){//borderlineMetric > positiveBoderLine10mm1 && borderlineMetric < positiveBoderLine10mm2
return "Sickle Cell Disease" return "Sickle Cell Disease"//"Positive for Sickle Cell. Confirm with HPLC"
} }
} }
}else if(cuvetteSize == "2mm"){ }else if(cuvetteSize == "2mm"){

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM10,17l-3.5,-3.5 1.41,-1.41L10,14.17 15.18,9l1.41,1.41L10,17z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M21.5,14.98c-0.02,0 -0.03,0 -0.05,0.01C21.2,13.3 19.76,12 18,12c-1.4,0 -2.6,0.83 -3.16,2.02C13.26,14.1 12,15.4 12,17c0,1.66 1.34,3 3,3l6.5,-0.02c1.38,0 2.5,-1.12 2.5,-2.5S22.88,14.98 21.5,14.98zM10,4.26v2.09C7.67,7.18 6,9.39 6,12c0,1.77 0.78,3.34 2,4.44V14h2v6H4v-2h2.73C5.06,16.54 4,14.4 4,12C4,8.27 6.55,5.15 10,4.26zM20,6h-2.73c1.43,1.26 2.41,3.01 2.66,5l-2.02,0C17.68,9.64 16.98,8.45 16,7.56V10h-2V4h6V6z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z"/>
</vector>

View File

@@ -45,6 +45,7 @@
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/scan_qr_code_of_the_kit" android:text="@string/scan_qr_code_of_the_kit"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/app_bar_layout" /> app:layout_constraintTop_toBottomOf="@id/app_bar_layout" />
@@ -58,6 +59,7 @@
android:textColor="@color/black" android:textColor="@color/black"
app:backgroundTint="@color/blue_app_light" app:backgroundTint="@color/blue_app_light"
app:cornerRadius="100dp" app:cornerRadius="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" /> app:layout_constraintTop_toBottomOf="@+id/tv_title" />

View File

@@ -76,6 +76,7 @@
android:textColor="@color/black" android:textColor="@color/black"
app:backgroundTint="@color/blue_app_light" app:backgroundTint="@color/blue_app_light"
app:cornerRadius="100dp" app:cornerRadius="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" /> app:layout_constraintTop_toBottomOf="@+id/tv_title" />
@@ -103,9 +104,9 @@
android:clickable="false" android:clickable="false"
android:gravity="center" android:gravity="center"
android:text="Refresh" android:text="Refresh"
android:visibility="visible"
android:textColor="@color/white" android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="@id/btn_scan_now" android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_scan_now" /> app:layout_constraintTop_toBottomOf="@id/btn_scan_now" />

View File

@@ -53,6 +53,7 @@
android:textColor="@color/black" android:textColor="@color/black"
app:backgroundTint="@color/blue_app_light" app:backgroundTint="@color/blue_app_light"
app:cornerRadius="100dp" app:cornerRadius="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title2" /> app:layout_constraintTop_toBottomOf="@+id/tv_title2" />

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- RadioGroup to select servers -->
<RadioGroup
android:id="@+id/radioGroupServers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:orientation="vertical">
<!-- Radio Buttons for each server option -->
<RadioButton
android:id="@+id/radioButtonInternal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Internal" />
<RadioButton
android:id="@+id/radioButtonClinical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clinical" />
<RadioButton
android:id="@+id/radioButtonCustomer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Customer" />
</RadioGroup>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -289,8 +289,6 @@
<string name="check_cuvette">Checking cuvette presence</string> <string name="check_cuvette">Checking cuvette presence</string>
<string name="cuvette_present">Cuvette present</string> <string name="cuvette_present">Cuvette present</string>
<string name="cuvette_absent">Cuvette absent</string> <string name="cuvette_absent">Cuvette absent</string>
<string name="cuvette_presentt">Cuvette Present , Please Remove Cuvette And Try Again</string>
<string name="cuvette_absentt">Cuvette Absent,Now You Can Submit</string>
<string name="retry">Retry</string> <string name="retry">Retry</string>
<string name="Firefox">Firefox</string> <string name="Firefox">Firefox</string>
<string name="Files">Files</string> <string name="Files">Files</string>
@@ -307,4 +305,7 @@
<string name="quick_capture">Quick Capture</string> <string name="quick_capture">Quick Capture</string>
<string name="reset_password_for_this_device">Reset password for this device</string> <string name="reset_password_for_this_device">Reset password for this device</string>
<string name="calibrate_device">Calibrate the device</string> <string name="calibrate_device">Calibrate the device</string>
<string name="cuvette_presentt">Cuvette Present , Please Remove Cuvette And Try Again</string>
<string name="cuvette_absentt">Cuvette Absent,Now You Can Submit</string>
</resources> </resources>

View File

@@ -288,8 +288,6 @@
<string name="check_cuvette">ಕುವೆಟ್ ಇರುವಿಕೆಯನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ</string> <string name="check_cuvette">ಕುವೆಟ್ ಇರುವಿಕೆಯನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ</string>
<string name="cuvette_present">ಕುವೆಟ್ಟೆ ಇರುತ್ತದೆ</string> <string name="cuvette_present">ಕುವೆಟ್ಟೆ ಇರುತ್ತದೆ</string>
<string name="cuvette_absent">ಕುವೆಟ್ಟೆ ಇರುವುದಿಲ್ಲ </string> <string name="cuvette_absent">ಕುವೆಟ್ಟೆ ಇರುವುದಿಲ್ಲ </string>
<string name="cuvette_presentt">Cuvette Present , Please Remove Cuvette And Try Again</string>
<string name="cuvette_absentt">Cuvette Absent,Now You Can Submit</string>
<string name="retry">ಮರುಪ್ರಯತ್ನಿಸಿ</string> <string name="retry">ಮರುಪ್ರಯತ್ನಿಸಿ</string>
<string name="Firefox">ಫೈರ್‌ಫಾಕ್ಸ್</string> <string name="Firefox">ಫೈರ್‌ಫಾಕ್ಸ್</string>
<string name="Files">ಫೈಲ್</string> <string name="Files">ಫೈಲ್</string>
@@ -306,6 +304,9 @@
<string name="quick_capture">ತ್ವರಿತ ಕ್ಯಾಪ್ಚರ್</string> <string name="quick_capture">ತ್ವರಿತ ಕ್ಯಾಪ್ಚರ್</string>
<string name="reset_password_for_this_device">ಈ ಸಾಧನಕ್ಕಾಗಿ ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ಮರುಹೊಂದಿಸಿ</string> <string name="reset_password_for_this_device">ಈ ಸಾಧನಕ್ಕಾಗಿ ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ಮರುಹೊಂದಿಸಿ</string>
<string name="calibrate_device">ಸಾಧನವನ್ನು ಮಾಪನಾಂಕ ಮಾಡಿ</string> <string name="calibrate_device">ಸಾಧನವನ್ನು ಮಾಪನಾಂಕ ಮಾಡಿ</string>
<string name="cuvette_presentt">Cuvette Present , Please Remove Cuvette And Try Again</string>
<string name="cuvette_absentt">Cuvette Absent,Now You Can Submit</string>
<!-- Add translations for other strings --> <!-- Add translations for other strings -->
</resources> </resources>

View File

@@ -291,8 +291,6 @@
<string name="check_cuvette">Checking cuvette presence</string> <string name="check_cuvette">Checking cuvette presence</string>
<string name="cuvette_present">Cuvette present , you can start the test</string> <string name="cuvette_present">Cuvette present , you can start the test</string>
<string name="cuvette_absent">Cuvette is absent , please place the cuvette and retry again</string> <string name="cuvette_absent">Cuvette is absent , please place the cuvette and retry again</string>
<string name="cuvette_presentt">Cuvette Present , Please Remove Cuvette And Try Again</string>
<string name="cuvette_absentt">Cuvette Absent,Now You Can Submit</string>
<string name="retry">Retry again</string> <string name="retry">Retry again</string>
<string name="usb_terminal">Usb Terminal</string> <string name="usb_terminal">Usb Terminal</string>
<string name="menu_about">About</string> <string name="menu_about">About</string>
@@ -307,4 +305,7 @@
<string name="quick_capture">Quick Capture</string> <string name="quick_capture">Quick Capture</string>
<string name="reset_password_for_this_device">Reset password for this device</string> <string name="reset_password_for_this_device">Reset password for this device</string>
<string name="calibrate_device">Calibrate Device</string> <string name="calibrate_device">Calibrate Device</string>
<string name="cuvette_presentt">Cuvette Present , Please Remove Cuvette And Try Again</string>
<string name="cuvette_absentt">Cuvette Absent,Now You Can Submit</string>
</resources> </resources>

View File

@@ -33,7 +33,7 @@
</entry> </entry>
<entry> <entry>
<key>normalMin10mm</key> <key>normalMin10mm</key>
<value>0.1</value> <value>0.07</value>
</entry> </entry>
<entry> <entry>
<key>normalMax10mm</key> <key>normalMax10mm</key>
@@ -45,11 +45,11 @@
</entry> </entry>
<entry> <entry>
<key>negativeBorderlineMax10mm</key> <key>negativeBorderlineMax10mm</key>
<value>0.25</value> <value>0.27</value>
</entry> </entry>
<entry> <entry>
<key>sickleCellTraitMin10mm</key> <key>sickleCellTraitMin10mm</key>
<value>0.25</value> <value>0.27</value>
</entry> </entry>
<entry> <entry>
<key>sickleCellTraitMax10mm</key> <key>sickleCellTraitMax10mm</key>
@@ -61,11 +61,11 @@
</entry> </entry>
<entry> <entry>
<key>positiveForSickleCellMax10mm</key> <key>positiveForSickleCellMax10mm</key>
<value>0.43</value> <value>0.39</value>
</entry> </entry>
<entry> <entry>
<key>sickleCellDiseaseMin10mm</key> <key>sickleCellDiseaseMin10mm</key>
<value>0.43</value> <value>0.39</value>
</entry> </entry>
<entry> <entry>
<key>sickleCellDiseaseMax10mm</key> <key>sickleCellDiseaseMax10mm</key>