Compare commits

..

15 Commits

Author SHA1 Message Date
sathwik
c3acb41590 updated the uto sumbit 2025-07-15 14:57:19 +05:30
sathwik
2ee6b65ca5 implementing the secure storage using ndk 2025-07-08 11:25:04 +05:30
sathwik
28b8409207 implementing the secure storage using ndk 2025-07-01 16:27:55 +05:30
sathwik
5c56ef7630 implementing the secure storage using ndk 2025-07-01 16:27:30 +05:30
sathwik
2fbc280b4a implementing the secure storage 2025-06-19 11:58:47 +05:30
sathwikcs
e9c8a9a887 R&D app 2025-05-15 19:04:23 +05:30
sathwikcs
e7ecf7eedf R&D app 2025-05-15 12:57:53 +05:30
sathwikcs
e3435f2182 131-STABLE-super-server 2025-03-13 15:50:04 +05:30
sathwikcs
f6cdd64ef6 131-STABLE-super-server 2025-03-13 15:49:25 +05:30
sathwikcs
7ad21ea5a9 131-STABLE-super-server 2025-03-13 15:23:15 +05:30
sathwikcs
6c89efeb5e 131-STABLE-smi... 2025-03-13 14:08:04 +05:30
sathwikcs
63eaf1cadc Merge remote-tracking branch 'origin/dev-server-2.1.131-stable-smi' into dev-server-2.1.131-stable-smi 2025-03-13 12:45:23 +05:30
sathwikcs
c180f7be31 131-STABLE-smi... 2025-03-13 12:45:04 +05:30
sathwikcs
c243ec6c8f 131-STABLE-smi... 2025-03-13 12:37:23 +05:30
sathwikcs
7c9238591b 131-STABLE-molbio 2025-03-04 13:36:33 +05:30
23 changed files with 392 additions and 141 deletions

View File

@@ -4,4 +4,10 @@
### Release key ### Release key
key0: prime24 key0: prime24
### Version 133.3
Printer not added yet
//update it when it is completed

View File

@@ -20,9 +20,14 @@ android {
applicationId "in.sminnovations.hpostesting.server" applicationId "in.sminnovations.hpostesting.server"
minSdk 30 minSdk 30
targetSdk 34 targetSdk 34
versionCode 134 versionCode 138
versionName "2.1.131" versionName "2.1.133.3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ''
}
}
} }
@@ -54,6 +59,12 @@ android {
packagingOptions { packagingOptions {
exclude 'mockito-extensions/org.mockito.plugins.MockMaker' exclude 'mockito-extensions/org.mockito.plugins.MockMaker'
} }
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
version '3.22.1'
}
}
// testOptions { // testOptions {
// unitTests { // unitTests {
// includeAndroidResources = true // includeAndroidResources = true

View File

@@ -1,37 +0,0 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "in.sminnovations.hpostesting.dev",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 127,
"versionName": "2.1.127",
"outputFile": "app-release.apk"
}
],
"elementType": "File",
"baselineProfiles": [
{
"minApi": 28,
"maxApi": 30,
"baselineProfiles": [
"baselineProfiles/1/app-release.dm"
]
},
{
"minApi": 31,
"maxApi": 2147483647,
"baselineProfiles": [
"baselineProfiles/0/app-release.dm"
]
}
],
"minSdkVersionForDexing": 21
}

View File

@@ -24,13 +24,12 @@
<uses-feature android:name="android.hardware.usb.host" /> <uses-feature android:name="android.hardware.usb.host" />
<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.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.ACCOUNT_MANAGER" <uses-permission
android:name="android.permission.ACCOUNT_MANAGER"
tools:ignore="ProtectedPermissions" /> tools:ignore="ProtectedPermissions" />
<application <application
android:name="com.example.hpostesting.HPOSTestingApplication" android:name="com.example.hpostesting.HPOSTestingApplication"
android:allowBackup="true" android:allowBackup="true"
@@ -46,7 +45,7 @@
<activity <activity
android:name="com.example.hpostesting.presentation.main_base.UpdateValuesActivity" android:name="com.example.hpostesting.presentation.main_base.UpdateValuesActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"/> android:screenOrientation="portrait" />
<service <service
android:name="com.example.hpostesting.util.MyAuthenticatorService" android:name="com.example.hpostesting.util.MyAuthenticatorService"
@@ -219,5 +218,4 @@
android:resource="@xml/file_paths" /> android:resource="@xml/file_paths" />
</provider> </provider>
</application> </application>
</manifest> </manifest>

View File

@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.18.1)
project("native-server")
# Create the shared library from server.cpp
add_library(
native-server
SHARED
server.cpp
)
# Find Android logging library
find_library(
log-lib
log
)
# Link logging library to our native lib
target_link_libraries(
native-server
${log-lib}
)

View File

@@ -0,0 +1,53 @@
#include <jni.h>
#include <string>
#include <unordered_map>
std::vector<std::pair<int, std::pair<std::string, std::unordered_map<std::string, std::string>>>> firebaseDataOrdered = {
{0, {"dev", {{"apiKey", "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"}, {"appId", "1:650071678820:android:a53292637abb7c0d6c6471"}, {"projectId", "hpos-af3cc"}, {"storageBucket", "hpos-af3cc.appspot.com"}}}},
{1, {"qc-qa", {{"apiKey", "AIzaSyC4d4GhWHr_NMJAeBvnztQ_yQ3Qe9MAnLs"}, {"appId", "1:1004619739289:android:3dbcefb10ea99654e5c808"}, {"projectId", "hpos-qa"}, {"storageBucket", "hpos-qa.appspot.com"}}}},
{2, {"prod", {{"apiKey", "AIzaSyA_O0oZGzy3Kiw9fiLQ3OFPME-xQJP88vs"}, {"appId", "1:1012719870714:android:d8d7c962d96f4097de5f43"}, {"projectId", "hpos-prod"}, {"storageBucket", "hpos-prod.appspot.com"}}}},
{3, {"pre prod", {{"apiKey", "AIzaSyDYySi27LioZGNisP1NfnNU5inJX_0FT38"}, {"appId", "1:121176529204:android:e6841fdac57bdc95bbed61"}, {"projectId", "hpos-preprod"}, {"storageBucket", "hpos-preprod.appspot.com"}}}},
{4, {"SMI R&D", {{"apiKey", "AIzaSyAVxpilbB804iRCCpMBDjjmdZhQguctGHM"}, {"appId", "1:327771387914:android:a3b4ed2e42ea6e38dc87f3"}, {"projectId", "hposrandd"}, {"storageBucket", "hposrandd.firebasestorage.app"}}}},
{5, {"molbio", {{"apiKey", "molbio"}, {"appId", "molbio"}, {"projectId", "molbio"}, {"storageBucket", "molbio"}}}}
};
extern "C"
JNIEXPORT jobject JNICALL
Java_com_example_hpostesting_firebase_FirebaseManager_getFirebaseDataMap(JNIEnv *env,jobject thiz) {
jclass mapClass = env->FindClass("java/util/LinkedHashMap");
jmethodID init = env->GetMethodID(mapClass, "<init>", "()V");
jmethodID put = env->GetMethodID(mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
jobject outerMap = env->NewObject(mapClass, init);
for (const auto &entry : firebaseDataOrdered) {
int order = entry.first;
const std::string &outerKeyStr = entry.second.first;
const auto &innerMapData = entry.second.second;
jobject innerMap = env->NewObject(mapClass, init);
// "int" field for order
jstring intKey = env->NewStringUTF("int");
jstring intValue = env->NewStringUTF(std::to_string(order).c_str());
env->CallObjectMethod(innerMap, put, intKey, intValue);
env->DeleteLocalRef(intKey);
env->DeleteLocalRef(intValue);
// actual firebase config keys
for (const auto &innerPair : innerMapData) {
jstring key = env->NewStringUTF(innerPair.first.c_str());
jstring value = env->NewStringUTF(innerPair.second.c_str());
env->CallObjectMethod(innerMap, put, key, value);
env->DeleteLocalRef(key);
env->DeleteLocalRef(value);
}
jstring outerKey = env->NewStringUTF(outerKeyStr.c_str());
env->CallObjectMethod(outerMap, put, outerKey, innerMap);
env->DeleteLocalRef(outerKey);
env->DeleteLocalRef(innerMap);
}
return outerMap;
}

View File

@@ -15,7 +15,6 @@ package com.example.hpostesting
import android.app.Application import android.app.Application
import com.example.hpostesting.firebase.FirebaseManager import com.example.hpostesting.firebase.FirebaseManager
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
@@ -23,8 +22,16 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import javax.inject.Inject import javax.inject.Inject
@HiltAndroidApp @HiltAndroidApp
class HPOSTestingApplication : Application() { class HPOSTestingApplication : Application() {
companion object {
init {
System.loadLibrary("native-server")
}
}
@Inject @Inject
lateinit var firebaseManager: FirebaseManager lateinit var firebaseManager: FirebaseManager
override fun onCreate() { override fun onCreate() {
@@ -39,4 +46,5 @@ class HPOSTestingApplication : Application() {
val firestore = firebaseManager.getCurrentFirestore() val firestore = firebaseManager.getCurrentFirestore()
firestore.firestoreSettings = firestoreSettings firestore.firestoreSettings = firestoreSettings
} }
} }

View File

@@ -32,7 +32,6 @@ import retrofit2.http.PUT
import retrofit2.http.Part import retrofit2.http.Part
interface MolbioResultApi { interface MolbioResultApi {
@PUT("deviceService/results/HPOS") @PUT("deviceService/results/HPOS")
suspend fun uploadResults( suspend fun uploadResults(
@Body molbioV2ResultRequest: MolbioV2ResultRequest, @Body molbioV2ResultRequest: MolbioV2ResultRequest,
@@ -47,6 +46,7 @@ interface MolbioResultApi {
// suspend fun deviceUpdate( // suspend fun deviceUpdate(
// @Body deviceUpdateRequest: DeviceUpdateRequest, // @Body deviceUpdateRequest: DeviceUpdateRequest,
// ): ResponseBody // ): ResponseBody
@POST("deviceService/device/getUpdate") @POST("deviceService/device/getUpdate")
suspend fun deviceUpdate( suspend fun deviceUpdate(
@Body deviceUpdateRequest: DeviceUpdateRequest, @Body deviceUpdateRequest: DeviceUpdateRequest,
@@ -62,7 +62,6 @@ interface MolbioResultApi {
@Part logFile: MultipartBody.Part, @Part logFile: MultipartBody.Part,
): UploadLogsResponse ): UploadLogsResponse
@PUT("deviceService/device/uploadDeviceDiagnostics") @PUT("deviceService/device/uploadDeviceDiagnostics")
suspend fun deviceDiagnostics( suspend fun deviceDiagnostics(
@Body deviceDiagnosticsRequest: DeviceDiagnosticsRequest @Body deviceDiagnosticsRequest: DeviceDiagnosticsRequest

View File

@@ -28,8 +28,8 @@ object Constants {
const val DOCUMENT_ID_FOR_UPDATE ="2o71vBKLqdgEKYtFG8Lb" const val DOCUMENT_ID_FOR_UPDATE ="2o71vBKLqdgEKYtFG8Lb"
const val ABHA_APP_PACKAGE = "in.ndhm.phr" const val ABHA_APP_PACKAGE = "in.ndhm.phr"
const val MOLBIO_INTEGRATION = false var MOLBIO_INTEGRATION = true
const val FIREBASE_INTEGRATION = true var FIREBASE_INTEGRATION = false
const val deviceProvisionEmail = "HPOS_provisioner@bigtec.co.in" const val deviceProvisionEmail = "HPOS_provisioner@bigtec.co.in"
const val deviceProvisionPassword = "f2ab0e7f9d69" const val deviceProvisionPassword = "f2ab0e7f9d69"
const val DEVICE_ID_API = "deviceIDAPI" const val DEVICE_ID_API = "deviceIDAPI"
@@ -44,9 +44,9 @@ object Constants {
const val DELAY_BETWEEN_COMMANDS: Long = 1000 const val DELAY_BETWEEN_COMMANDS: Long = 1000
const val TEST_RIGHT_TOTAL_PIXEL = 3694 const val TEST_RIGHT_TOTAL_PIXEL = 3694
const val MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE = 34 const val MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE = 34
const val MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM = 9 const val MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM = 9
const val MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM_RANDD= 129
const val RANGE_IN_RESULT_CALCULATIONS = 10 const val RANGE_IN_RESULT_CALCULATIONS = 10

View File

@@ -243,9 +243,10 @@ object AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideNetworkMonitor(@ApplicationContext context: Context): NetworkMonitor { fun provideNetworkMonitor(
return NetworkMonitor(context) @ApplicationContext context: Context
): NetworkMonitor {
return NetworkMonitor(context).apply { startMonitoring() }
} }
} }

View File

@@ -14,7 +14,9 @@ package com.example.hpostesting.firebase
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Process import android.os.Process
import android.util.Log
import androidx.core.content.edit import androidx.core.content.edit
import com.example.hpostesting.data.constant.Constants
import com.google.firebase.FirebaseApp import com.google.firebase.FirebaseApp
import com.google.firebase.FirebaseOptions import com.google.firebase.FirebaseOptions
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
@@ -27,20 +29,52 @@ import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
class FirebaseManager @Inject constructor(private val context: Context) { class FirebaseManager @Inject constructor(private val context: Context) {
private var defaultServers = mutableListOf<FirebaseConfig>()
external fun getFirebaseDataMap(): Map<String, Map<String, String>>
private val map: Map<String, Map<String, String>> = getFirebaseDataMap()
companion object {
init {
System.loadLibrary("native-server") //use NDK ro secure somethings
}
}
private val sharedPreferencesServerConfig = context.getSharedPreferences("FirebaseConfigPrefs", Context.MODE_PRIVATE) private val sharedPreferencesServerConfig = context.getSharedPreferences("FirebaseConfigPrefs", Context.MODE_PRIVATE)
private val sharedPreferencesDev = context.getSharedPreferences("DevMode",Context.MODE_PRIVATE) private val sharedPreferencesDev = context.getSharedPreferences("DevMode",Context.MODE_PRIVATE)
private var currentFirestore: FirebaseFirestore = FirebaseFirestore.getInstance() private var currentFirestore: FirebaseFirestore = FirebaseFirestore.getInstance()
private var currentStorage: FirebaseStorage = FirebaseStorage.getInstance() private var currentStorage: FirebaseStorage = FirebaseStorage.getInstance()
var updateStatus = false private var updateStatus = false
private fun Map<String, String>.toFirebaseConfig(server: String): FirebaseConfig? {
val apiKey = this["apiKey"] ?: return null
val appId = this["appId"] ?: return null
val projectId = this["projectId"] ?: return null
val storageBucket = this["storageBucket"] ?: return null
return FirebaseConfig(
serverName = server,
projectId = projectId,
appId = appId,
apiKey = apiKey,
storageBucket = storageBucket
)
}
fun populate() {
defaultServers.clear()
map.forEach { (server, config) ->
config.toFirebaseConfig(server)?.let {
defaultServers.add(it)
} ?: Log.w("Firebase", "Skipping $server due to missing keys")
}
}
private val defaultServers = listOf(
// i have it in different place look down
firebaseConfigProd, firebaseConfigDev , firebaseConfigQaQc, firebaseConfigPreProd
)
init { init {
populate()
val lastSelectedServer = getLastSelectedServer() val lastSelectedServer = getLastSelectedServer()
switchServer(lastSelectedServer) switchServer(lastSelectedServer)
} }
@@ -61,11 +95,17 @@ class FirebaseManager @Inject constructor(private val context: Context) {
fun getCurrentStorage(): FirebaseStorage = currentStorage fun getCurrentStorage(): FirebaseStorage = currentStorage
fun switchServer(firebaseConfig: FirebaseConfig) { fun switchServer(firebaseConfig: FirebaseConfig) {
saveSelectedServer(firebaseConfig) if (firebaseConfig.serverName =="molbio" ||firebaseConfig.apiKey == "molbio"){
val firebaseApp = getOrInitializeFirebaseApp(firebaseConfig) saveSelectedServer(firebaseConfig)
currentFirestore = FirebaseFirestore.getInstance(firebaseApp) makeMolbioAsBackEnd()
currentStorage = FirebaseStorage.getInstance(firebaseApp) }else {
updateStatus = true makeSMIBackEnd()
saveSelectedServer(firebaseConfig)
val firebaseApp = getOrInitializeFirebaseApp(firebaseConfig)
currentFirestore = FirebaseFirestore.getInstance(firebaseApp)
currentStorage = FirebaseStorage.getInstance(firebaseApp)
updateStatus = true
}
} }
@@ -73,7 +113,6 @@ class FirebaseManager @Inject constructor(private val context: Context) {
val existingApp = FirebaseApp.getApps(context).find { it.name == firebaseConfig.serverName } val existingApp = FirebaseApp.getApps(context).find { it.name == firebaseConfig.serverName }
return if (existingApp != null) { return if (existingApp != null) {
existingApp existingApp
} else { } else {
@@ -125,6 +164,16 @@ class FirebaseManager @Inject constructor(private val context: Context) {
fun getAvailableServers(): List<FirebaseConfig> { fun getAvailableServers(): List<FirebaseConfig> {
return defaultServers return defaultServers
} }
private fun makeMolbioAsBackEnd(){
Constants.FIREBASE_INTEGRATION = false
Constants.MOLBIO_INTEGRATION = true
restartApp()
}
private fun makeSMIBackEnd(){
Constants.FIREBASE_INTEGRATION = true
Constants.MOLBIO_INTEGRATION = false
}
} }
fun restartApp(context: Context) { fun restartApp(context: Context) {
@@ -141,34 +190,51 @@ fun delayedRestart(context: Context) {
} }
} }
private val firebaseConfigDev = FirebaseConfig( //
serverName = "dev", //
apiKey = "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I", //private val firebaseConfigDev = FirebaseConfig(
appId = "1:650071678820:android:a53292637abb7c0d6c6471", // serverName = "dev",
projectId = "hpos-af3cc", // apiKey = "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I",
storageBucket = "hpos-af3cc.appspot.com" // appId = "1:650071678820:android:a53292637abb7c0d6c6471",
) // projectId = "hpos-af3cc",
// storageBucket = "hpos-af3cc.appspot.com"
private val firebaseConfigQaQc = FirebaseConfig( //)
serverName = "qc-qa", //private val firebaseConfigQaQc = FirebaseConfig(
apiKey = "AIzaSyC4d4GhWHr_NMJAeBvnztQ_yQ3Qe9MAnLs", // serverName = "qc-qa",
appId = "1:1004619739289:android:3dbcefb10ea99654e5c808", // apiKey = "AIzaSyC4d4GhWHr_NMJAeBvnztQ_yQ3Qe9MAnLs",
projectId = "hpos-qa", // appId = "1:1004619739289:android:3dbcefb10ea99654e5c808",
storageBucket = "hpos-qa.appspot.com" // projectId = "hpos-qa",
) // storageBucket = "hpos-qa.appspot.com"
//)
private val firebaseConfigProd = FirebaseConfig( //
serverName = "prod", //private val firebaseConfigProd = FirebaseConfig(
apiKey = "AIzaSyA_O0oZGzy3Kiw9fiLQ3OFPME-xQJP88vs", // serverName = "prod",
appId = "1:1012719870714:android:d8d7c962d96f4097de5f43", // apiKey = "AIzaSyA_O0oZGzy3Kiw9fiLQ3OFPME-xQJP88vs",
projectId = "hpos-prod", // appId = "1:1012719870714:android:d8d7c962d96f4097de5f43",
storageBucket = "hpos-prod.appspot.com" // projectId = "hpos-prod",
) // storageBucket = "hpos-prod.appspot.com"
//)
private val firebaseConfigPreProd = FirebaseConfig( //
serverName = "pre prod", //private val firebaseConfigPreProd = FirebaseConfig(
apiKey = "AIzaSyDYySi27LioZGNisP1NfnNU5inJX_0FT38", // serverName = "pre prod",
appId = "1:121176529204:android:e6841fdac57bdc95bbed61", // apiKey = "AIzaSyDYySi27LioZGNisP1NfnNU5inJX_0FT38",
projectId = "hpos-preprod", // appId = "1:121176529204:android:e6841fdac57bdc95bbed61",
storageBucket = "hpos-preprod.appspot.com" // projectId = "hpos-preprod",
) // storageBucket = "hpos-preprod.appspot.com"
//)
//
//private val firebaseConfigSmiRandD= FirebaseConfig(
// serverName = "SMI R&D",
// apiKey = "AIzaSyAVxpilbB804iRCCpMBDjjmdZhQguctGHM",
// appId = "1:327771387914:android:a3b4ed2e42ea6e38dc87f3",
// projectId = "hposrandd",
// storageBucket = "hposrandd.firebasestorage.app"
//)
//
//private val configMolbio = FirebaseConfig(
// serverName = "molbio",
// apiKey = "molbio",
// appId = "molbio",
// projectId = "molbio",
// storageBucket = "molbio"
//)

View File

@@ -22,10 +22,12 @@ import android.util.Log
import android.widget.EditText import android.widget.EditText
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContentProviderCompat.requireContext
import com.example.hpostesting.data.constant.DataHolder 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.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.test.TestType import com.example.hpostesting.data.model.test.TestType
import com.example.hpostesting.firebase.FirebaseManager
import com.example.hpostesting.presentation.main_base.DashboardActivity import com.example.hpostesting.presentation.main_base.DashboardActivity
import com.example.hpostesting.presentation.hb_test.HBTestActivity import com.example.hpostesting.presentation.hb_test.HBTestActivity
import com.example.hpostesting.presentation.trueheme_test.TrueHemeTestActivity import com.example.hpostesting.presentation.trueheme_test.TrueHemeTestActivity
@@ -52,7 +54,7 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
private var fromWhere = "Home" private var fromWhere = "Home"
private val TAG = "KitScanActivity" private val TAG = "KitScanActivity"
private lateinit var binding: ActivityKitScanBinding private lateinit var binding: ActivityKitScanBinding
private lateinit var firebaseManager: FirebaseManager
private lateinit var sharedPreference: SharedPreferences private lateinit var sharedPreference: SharedPreferences
var sdkHandler: SDKHandler? = null var sdkHandler: SDKHandler? = null
@@ -71,21 +73,21 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
} }
private fun processScannedData(contents: String) {//edited auto selection of cuvette size private fun processScannedData(contents: String) {//edited auto selection of cuvette size
if(contents.contains("SMI/SC/")){ if (contents.contains("SMI/SC/")) {
with(sharedPreference.edit()) { with(sharedPreference.edit()) {
putString(Constants.CUVETTE_SIZE, "2mm") putString(Constants.CUVETTE_SIZE, "2mm")
apply() apply()
} }
Toast.makeText(this, "Selected cuvette size: 2mm", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Selected cuvette size: 2mm", Toast.LENGTH_SHORT).show()
binding.nameEditText.setText(contents) binding.nameEditText.setText(contents)
}else if(contents.contains("SMI/SC-2-D10/")){ } else if (contents.contains("SMI/SC-2-D10/")) {
with(sharedPreference.edit()) { with(sharedPreference.edit()) {
putString(Constants.CUVETTE_SIZE, "10mm") putString(Constants.CUVETTE_SIZE, "10mm")
apply() apply()
} }
Toast.makeText(this, "Selected cuvette size: 10mm", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Selected cuvette size: 10mm", Toast.LENGTH_SHORT).show()
binding.nameEditText.setText(contents) binding.nameEditText.setText(contents)
}else{ } else {
Toast.makeText(this, R.string.invalid_kit, Toast.LENGTH_LONG).show() Toast.makeText(this, R.string.invalid_kit, Toast.LENGTH_LONG).show()
} }
} }
@@ -127,30 +129,42 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
firebaseManager = FirebaseManager(this)
val currentServer = firebaseManager.getLastSelectedServer().serverName
binding = ActivityKitScanBinding.inflate(layoutInflater) binding = ActivityKitScanBinding.inflate(layoutInflater)
sharedPreference = this.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) sharedPreference = this.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
setContentView(binding.root) setContentView(binding.root)
binding.toolbar.title = "Kit Serial Number" binding.toolbar.title = "Kit Serial Number"
fromWhere = intent.getStringExtra("fromWhere").toString() fromWhere = intent.getStringExtra("fromWhere").toString()
val maxTest = if(sharedPreference.getString(Constants.CUVETTE_SIZE, "10mm").toString() == "2mm"){
Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE val maxTest = if (currentServer == "SMI R&D"){
}else{ Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM_RANDD
Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM
Log.d(TAG, "onCreate RandD mode")
}else {
if (sharedPreference.getString(Constants.CUVETTE_SIZE, "10mm").toString() == "2mm") {
Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE
} else {
Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM
}
} }
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 (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") {
// moveToNext() // moveToNext()
// }else{ // }else{
if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") { if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") {
moveToNext() moveToNext()
}else{ } else {
if (DataHolder.sampleReadCounter <= maxTest && kitNum != "" && time < Constants.MAX_KIT_TIME) { 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() Toast.makeText(
this@KitScanActivity,
"Limit Reached, Use New KIT for testing",
Toast.LENGTH_SHORT
).show()
DataHolder.sampleReadCounter = 0 DataHolder.sampleReadCounter = 0
DataHolder.kitSerial = "" DataHolder.kitSerial = ""
@@ -212,13 +226,13 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
binding.btnGo.setOnClickListener { binding.btnGo.setOnClickListener {
val serialNumber = binding.nameEditText.text.toString().trim() val serialNumber = binding.nameEditText.text.toString().trim()
if (serialNumber.isNotEmpty() && isSerialValid(serialNumber)) { if (serialNumber.isNotEmpty() && isSerialValid(serialNumber)) {
if(serialNumber.contains("SMI/SC/")){ if (serialNumber.contains("SMI/SC/")) {
with(sharedPreference.edit()) { with(sharedPreference.edit()) {
putString(Constants.CUVETTE_SIZE, "2mm") putString(Constants.CUVETTE_SIZE, "2mm")
apply() apply()
} }
Toast.makeText(this, "Selected cuvette size: 2mm", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Selected cuvette size: 2mm", Toast.LENGTH_SHORT).show()
}else if(serialNumber.contains("SMI/SC-2-D10/")){ } else if (serialNumber.contains("SMI/SC-2-D10/")) {
with(sharedPreference.edit()) { with(sharedPreference.edit()) {
putString(Constants.CUVETTE_SIZE, "10mm") putString(Constants.CUVETTE_SIZE, "10mm")
apply() apply()
@@ -301,7 +315,8 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
if (mScannerInfoList.isNotEmpty()) { if (mScannerInfoList.isNotEmpty()) {
sdkHandler!!.dcssdkEstablishCommunicationSession(mScannerInfoList[0].scannerID) sdkHandler!!.dcssdkEstablishCommunicationSession(mScannerInfoList[0].scannerID)
} else { } else {
Toast.makeText(this,"Scanner Is not available In this device", Toast.LENGTH_LONG).show() Toast.makeText(this, "Scanner Is not available In this device", Toast.LENGTH_LONG)
.show()
} }
} }
@@ -339,7 +354,7 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
runOnUiThread { runOnUiThread {
val editableResult: Editable = Editable.Factory.getInstance().newEditable(result) val editableResult: Editable = Editable.Factory.getInstance().newEditable(result)
processScannedData(result) processScannedData(result)
// binding.nameEditText.text = editableResult // binding.nameEditText.text = editableResult
} }
} }
@@ -352,27 +367,29 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
private fun isSerialValid(s: String): Boolean { private fun isSerialValid(s: String): Boolean {
if (s.contains("SMI/SC/")) { if (s.contains("SMI/SC/")) {
if(s.length != 17){ if (s.length != 17) {
binding.nameEditText.error = "Invalid Kit Serial Number, correct example SMI/SC/000/00/000" binding.nameEditText.error =
"Invalid Kit Serial Number, correct example SMI/SC/000/00/000"
return false return false
} }
}else if(s.contains("SMI/SC-2-D10/")){ } else if (s.contains("SMI/SC-2-D10/")) {
if(s.length != 27){ if (s.length != 27) {
binding.nameEditText.error = "Invalid Kit Serial Number, correct example SMI/SC-2-D10/000000/000/000" binding.nameEditText.error =
"Invalid Kit Serial Number, correct example SMI/SC-2-D10/000000/000/000"
return false return false
} }
}else{ } else {
return false return false
} }
return true return true
} }
private fun moveToNext() { private fun moveToNext() {
if(fromWhere == "Main"){ if (fromWhere == "Main") {
if(DataHolder.selectedTestType == TestType.HB_EST){ if (DataHolder.selectedTestType == TestType.HB_EST) {
val i = Intent(applicationContext, HBTestActivity::class.java) val i = Intent(applicationContext, HBTestActivity::class.java)
startActivity(i) startActivity(i)
}else{ } else {
DataHolder.deviceType.observe(this) { deviceType -> DataHolder.deviceType.observe(this) { deviceType ->
when (deviceType) { when (deviceType) {
Constants.DEVICE_TYPE_HEMOCUBE -> { Constants.DEVICE_TYPE_HEMOCUBE -> {
@@ -425,6 +442,7 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
true true
} }
} }
private fun timeDifference(createdAt: String): Long { private fun timeDifference(createdAt: String): Long {
val currentTime = Calendar.getInstance().time val currentTime = Calendar.getInstance().time
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())

View File

@@ -14,6 +14,7 @@
package com.example.hpostesting.presentation package com.example.hpostesting.presentation
import android.Manifest import android.Manifest
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
@@ -33,6 +34,7 @@ import com.example.hpostesting.util.MyUtils
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivitySplashBinding import `in`.sminnovations.hpostesting.databinding.ActivitySplashBinding
@SuppressLint("CustomSplashScreen")
class SplashActivity : AppCompatActivity() { class SplashActivity : AppCompatActivity() {
private lateinit var binding: ActivitySplashBinding private lateinit var binding: ActivitySplashBinding

View File

@@ -37,6 +37,7 @@ import com.example.hpostesting.presentation.main_base.DashboardActivity
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDeviceProvisionBinding import `in`.sminnovations.hpostesting.databinding.FragmentDeviceProvisionBinding
import okio.ByteString.Companion.decodeBase64
import java.io.File import java.io.File
class DeviceProvisionFragment : Fragment() { class DeviceProvisionFragment : Fragment() {
@@ -147,17 +148,18 @@ class DeviceProvisionFragment : Fragment() {
DashboardActivity::class.java DashboardActivity::class.java
) )
) )
} else { } else {
Toast.makeText( Toast.makeText(
activity, activity,
"An error in device provision: ${response.data.message}", "An error in device provision: ${response.data.message}",
Toast.LENGTH_LONG Toast.LENGTH_LONG
).show() ).show()
Log.d("Error in hpos network", "observeViewModel:${response.data.message} ")
binding.btnSubmit.visibility = View.VISIBLE binding.btnSubmit.visibility = View.VISIBLE
} }
} }
is Result.Error -> { is Result.Error -> {
response.exception.let { message -> response.exception.let { message ->
Toast.makeText( Toast.makeText(
@@ -165,7 +167,9 @@ class DeviceProvisionFragment : Fragment() {
"An error occurred in device provision: $message", "An error occurred in device provision: $message",
Toast.LENGTH_LONG Toast.LENGTH_LONG
).show() ).show()
Log.d("Error in hpos network 2", "observeViewModel:$message} ")
} }
Log.d("Error in hpos network 3", "observeViewModel: $response} ")
} }
is Result.Loading -> { is Result.Loading -> {

View File

@@ -1,16 +1,21 @@
package com.example.hpostesting.presentation.main_base package com.example.hpostesting.presentation.main_base
import com.example.hpostesting.data.constant.Constants.FIREBASE_INTEGRATION
import com.example.hpostesting.data.constant.Constants.MOLBIO_INTEGRATION
class AppVersionTapManager { class AppVersionTapManager {
private var tapCount = 0 private var tapCount = 0
private val maxTapCount = 5 private val maxTapCount = 5
val shouldEnable = FIREBASE_INTEGRATION && !MOLBIO_INTEGRATION
val notEnable = MOLBIO_INTEGRATION && !FIREBASE_INTEGRATION
fun registerTap(onMaxTapsReached: () -> Unit) { fun registerTap(onMaxTapsReached: () -> Unit) {
tapCount++ tapCount++
if (tapCount >= maxTapCount) { if (tapCount >= maxTapCount && shouldEnable) {
onMaxTapsReached() onMaxTapsReached()
reset() reset()
} }
} }
private fun reset() { private fun reset() {
tapCount = 0 tapCount = 0

View File

@@ -89,6 +89,7 @@ class PanelFragment : Fragment() {
binding.btnDeviceInfo.visibility = View.VISIBLE binding.btnDeviceInfo.visibility = View.VISIBLE
binding.btnResetPassword.visibility = View.VISIBLE binding.btnResetPassword.visibility = View.VISIBLE
binding.btnUpdateValues.visibility = View.VISIBLE binding.btnUpdateValues.visibility = View.VISIBLE
binding.btnRnd.visibility = View.GONE
}else{ }else{
binding.btnResetPassword.visibility = View.GONE binding.btnResetPassword.visibility = View.GONE
binding.btnDeviceProvision.visibility = View.GONE binding.btnDeviceProvision.visibility = View.GONE
@@ -102,6 +103,7 @@ class PanelFragment : Fragment() {
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
binding.btnDeviceInfo.visibility = View.VISIBLE binding.btnDeviceInfo.visibility = View.VISIBLE
binding.btnUpdateValues.visibility = View.GONE binding.btnUpdateValues.visibility = View.GONE
binding.btnRnd.visibility = View.GONE
} }
binding.btnResetPassword.setOnClickListener{ binding.btnResetPassword.setOnClickListener{
@@ -142,6 +144,7 @@ class PanelFragment : Fragment() {
startActivity(intent) startActivity(intent)
} }
binding.btnFiles.setOnClickListener { binding.btnFiles.setOnClickListener {
val intent = Intent(Intent.ACTION_GET_CONTENT) val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "file/*" intent.type = "file/*"

View File

@@ -28,7 +28,6 @@ import androidx.fragment.app.Fragment
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import androidx.preference.SwitchPreferenceCompat import androidx.preference.SwitchPreferenceCompat
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
@@ -201,7 +200,6 @@ class PrefsFragment : PreferenceFragmentCompat() {
} }
} }
val appVersionPreference = Preference(requireContext()).apply { val appVersionPreference = Preference(requireContext()).apply {
title = "App Version" title = "App Version"
summary = summary =
@@ -212,11 +210,10 @@ class PrefsFragment : PreferenceFragmentCompat() {
tapManager.registerTap { tapManager.registerTap {
firebaseManager.setDevModeOn(true) firebaseManager.setDevModeOn(true)
val devConfig = servers.find { it.serverName == "dev" }
if (firebaseManager.getDevMode() && currentServer != "dev") { if (firebaseManager.getDevMode() && currentServer != "dev") {
Toast.makeText(requireContext(), "Now you are a Developer", Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), "Now you are a Developer", Toast.LENGTH_SHORT).show()
Toast.makeText(requireContext(), "Setting Up developer Environmnet", Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), "Setting Up developer Environmnet", Toast.LENGTH_SHORT).show()
switchFirebaseServer(devConfig!!)
} }
if (preferenceScreen.findPreference<SwitchPreferenceCompat>("developer_options") == null) { if (preferenceScreen.findPreference<SwitchPreferenceCompat>("developer_options") == null) {

View File

@@ -593,7 +593,7 @@ class TrueHemeFragment : Fragment() {
binding.btnSubmit.visibility = View.VISIBLE binding.btnSubmit.visibility = View.VISIBLE
binding.btnSubmit.isEnabled = true binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true binding.btnSubmit.isClickable = true
// binding.clParent.setBackgroundColor(Color.parseColor("#edfffd")) // binding.clParent.setBackgroundColor(Color.parseColor("#edfffd"))
binding.ivCheck.visibility = View.VISIBLE binding.ivCheck.visibility = View.VISIBLE
} }
} else { } else {
@@ -736,7 +736,7 @@ class TrueHemeFragment : Fragment() {
} }
} }
private fun processResult() { private fun processResult(){
try { try {
hemoCubeViewModel.messages.postValue(getString(R.string.processing_result)) hemoCubeViewModel.messages.postValue(getString(R.string.processing_result))
val deviceLog = resultData val deviceLog = resultData

View File

@@ -29,6 +29,8 @@ import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
import androidx.transition.Visibility
import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
@@ -45,6 +47,9 @@ import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.log10 import kotlin.math.log10
import kotlin.random.Random import kotlin.random.Random
@@ -142,6 +147,7 @@ class TrueHemeTestFragment : Fragment() {
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)
initViews() initViews()
@@ -150,10 +156,52 @@ class TrueHemeTestFragment : Fragment() {
observeViewModel() observeViewModel()
} }
private fun autoSmbt(ignoreCuvette : Boolean = true){
submitClick = true
checkSubmit = true
lifecycleScope.launch {
delay(100)
}
activity?.runOnUiThread {
if (checkSubmit) {
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
}
trueHemeTestViewModel.uploadHemoCubeResultToDatabase(
isOnline,
true,
sharedPreferences.getString(Constants.KIT_NUMBER, ""),
quickCapture
)
Toast.makeText(requireContext(), "Auto Sumbitted", Toast.LENGTH_SHORT).show()
} else {
checkCuvettePresence()
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
Toast.makeText(requireContext(), "Auto Sumbit Failed ", Toast.LENGTH_SHORT).show()
binding.btnSubmit.visibility = View.VISIBLE
}
}
}
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun initViews() { private fun initViews() {
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()) { // with(sharedPreferences.edit()) {
// putBoolean(Constants.QUICK_CAPTURE, false) // putBoolean(Constants.QUICK_CAPTURE, false)
@@ -451,7 +499,7 @@ class TrueHemeTestFragment : Fragment() {
} }
} }
private fun showBufferAlertDialog() { private fun showBufferAlertDialog(){
val title = "WARNING" val title = "WARNING"
val message = getString(R.string.do_exist) val message = getString(R.string.do_exist)
val negativeText = getString(R.string.no) val negativeText = getString(R.string.no)
@@ -658,6 +706,8 @@ class TrueHemeTestFragment : Fragment() {
} }
showRetryButtonForCuvette() showRetryButtonForCuvette()
} }
//need to change where check submit
resultData.contains("#CIN") && this.submitClick && this.testStatusCode < TestStatus.CUVETTE_PRESENTT.code -> { resultData.contains("#CIN") && this.submitClick && this.testStatusCode < TestStatus.CUVETTE_PRESENTT.code -> {
trueHemeTestViewModel.messages.postValue(getString(R.string.cuvette_presentt)) trueHemeTestViewModel.messages.postValue(getString(R.string.cuvette_presentt))
this.testStatusCode = TestStatus.CUVETTE_PRESENTT.code this.testStatusCode = TestStatus.CUVETTE_PRESENTT.code
@@ -665,6 +715,8 @@ class TrueHemeTestFragment : Fragment() {
binding.testing.visibility = View.GONE binding.testing.visibility = View.GONE
} }
} }
resultData.contains("#AIN") && this.submitClick && this.testStatusCode <= TestStatus.CUVETTE_ABSENTT.code -> { resultData.contains("#AIN") && this.submitClick && this.testStatusCode <= TestStatus.CUVETTE_ABSENTT.code -> {
trueHemeTestViewModel.messages.postValue(getString(R.string.cuvette_absentt)) trueHemeTestViewModel.messages.postValue(getString(R.string.cuvette_absentt))
this.testStatusCode = TestStatus.CUVETTE_ABSENTT.code this.testStatusCode = TestStatus.CUVETTE_ABSENTT.code
@@ -957,11 +1009,15 @@ class TrueHemeTestFragment : Fragment() {
if (readingsPerSample == 1) { if (readingsPerSample == 1) {
activity?.runOnUiThread { activity?.runOnUiThread {
binding.btnSubmit.visibility = View.VISIBLE
binding.btnSubmit.isEnabled = true //changing to invisible
binding.btnSubmit.isClickable = true binding.btnSubmit.visibility = View.GONE
// binding.btnSubmit.isEnabled = true
// binding.btnSubmit.isClickable = true
// binding.clParent.setBackgroundColor(Color.parseColor("#edfffd")) // binding.clParent.setBackgroundColor(Color.parseColor("#edfffd"))
autoSmbt(true)
binding.ivCheck.visibility = View.VISIBLE binding.ivCheck.visibility = View.VISIBLE
} }
} else { } else {
trueHemeTestViewModel.uploadHemoCubeResultToDatabase( trueHemeTestViewModel.uploadHemoCubeResultToDatabase(
@@ -1769,4 +1825,7 @@ class TrueHemeTestFragment : Fragment() {
private fun generateTwoDigitRandomNumber(): Int { private fun generateTwoDigitRandomNumber(): Int {
return Random.nextInt(10, 100) return Random.nextInt(10, 100)
} }
} }

View File

@@ -1,5 +1,6 @@
package com.example.hpostesting.util package com.example.hpostesting.util
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.Network import android.net.Network
@@ -12,6 +13,8 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.URL import java.net.URL
@@ -23,7 +26,7 @@ import javax.inject.Singleton
class NetworkMonitor @Inject constructor( class NetworkMonitor @Inject constructor(
@ApplicationContext private val context: Context @ApplicationContext private val context: Context
) { ) {
private var isMonitoringStarted = false
private val connectivityManager = private val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
@@ -49,7 +52,10 @@ class NetworkMonitor @Inject constructor(
} }
} }
@SuppressLint("NewApi")
fun startMonitoring() { fun startMonitoring() {
if (isMonitoringStarted) return // Already started, do nothing.
isMonitoringStarted = true
// Check initial connectivity status // Check initial connectivity status
val network = connectivityManager.activeNetwork val network = connectivityManager.activeNetwork
val capabilities = connectivityManager.getNetworkCapabilities(network) val capabilities = connectivityManager.getNetworkCapabilities(network)
@@ -66,6 +72,8 @@ class NetworkMonitor @Inject constructor(
.build() .build()
connectivityManager.registerNetworkCallback(networkRequest, networkCallback) connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
// Start periodic checks:
startPeriodicPingCheck()
} }
fun stopMonitoring() { // never needed to call fun stopMonitoring() { // never needed to call
@@ -96,4 +104,14 @@ class NetworkMonitor @Inject constructor(
} }
} }
} }
private fun startPeriodicPingCheck(intervalMillis: Long = 1 * 60_000L) {
networkScope.launch {
while (isActive) {
performPingCheck()
delay(intervalMillis)
}
}
}
} }

View File

@@ -55,7 +55,21 @@
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" /> app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />
<Button <Button
android:id="@+id/btn_rnd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="R and D"
android:textColor="@color/white"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_submit" />
<Button
android:id="@+id/btn_diagnostics" android:id="@+id/btn_diagnostics"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -67,7 +81,7 @@
app:cornerRadius="16dp" app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_submit" /> app:layout_constraintTop_toBottomOf="@id/btn_rnd" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/btn_auto_dac" android:id="@+id/btn_auto_dac"
@@ -153,6 +167,7 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_deviceProvision" /> app:layout_constraintTop_toBottomOf="@id/btn_deviceProvision" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/btn_update_values" android:id="@+id/btn_update_values"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -160,12 +175,13 @@
android:layout_marginHorizontal="16dp" android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:clickable="false" android:clickable="false"
android:text="Update values" android:text="Update valueLs"
android:textColor="@color/white" android:textColor="@color/white"
app:cornerRadius="16dp" app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_reset_password" /> app:layout_constraintTop_toBottomOf="@id/btn_reset_password" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/btn_firefox" android:id="@+id/btn_firefox"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -25,6 +25,7 @@
<item>ka</item> <item>ka</item>
<!-- Use language codes (e.g., en, kn) as values --> <!-- Use language codes (e.g., en, kn) as values -->
</string-array> </string-array>
<string-array name="district"> <string-array name="district">
<item>Mysuru</item> <item>Mysuru</item>
<item>Kodagu</item> <item>Kodagu</item>

View File

@@ -25,4 +25,3 @@ plugins {
task clean(type: Delete) { task clean(type: Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }