Compare commits

...

33 Commits

Author SHA1 Message Date
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
sathwikcs
5c843ca232 131-STABLE 2025-03-03 14:55:41 +05:30
sathwikcs
736dff2b11 Fixed the issue where dialogue is showing wrong 2025-02-20 18:23:10 +05:30
sathwikcs
20dd1e41eb Fixed the issue where app wil crash when switched to pre pod 2025-02-19 18:41:11 +05:30
sathwikcs
ad6670a1e8 Merge remote-tracking branch 'origin/dev-server-2.1.132' into dev-server-2.1.132 2025-02-19 15:42:43 +05:30
sathwikcs
e6f8ab69e9 Fixed the issue where app wil crash when switched to pre pod 2025-02-19 15:42:23 +05:30
Sathwik C S
ccd2138f66 Update file README.md 2025-02-18 09:31:30 +00:00
sathwikcs
d54436996d added dev icon 2025-02-18 14:53:36 +05:30
sathwikcs
52a555a63a Changes in josn - default : prod 2025-02-18 14:53:14 +05:30
sathwikcs
8e80cfe525 SettingsFragment.kt 2025-02-18 14:52:02 +05:30
sathwikcs
f26f54e51d Added the developer shared pref 2025-02-18 14:51:31 +05:30
sathwikcs
1d029b8ff8 removed the selector drop down 2025-02-18 14:50:40 +05:30
sathwikcs
c88efd148b App version Tap manager 2025-02-18 14:50:08 +05:30
sathwikcs
cb27983d21 NetworkStatusLiveData.kt has been removed 2025-02-17 12:38:11 +05:30
Sathwik C S
0b268dda47 Edit README.md 2025-01-29 11:02:47 +00:00
Sathwik C S
d9777edf02 Edit README.md 2025-01-29 11:01:52 +00:00
sathwikcs
238424ad89 NetworkStatusLiveData.kt has been removed 2025-01-29 15:39:47 +05:30
sathwikcs
c1f02c878c updated the NetworkChecker.kt 2025-01-29 15:39:29 +05:30
sathwikcs
b344dbcb69 updated the test case 2025-01-28 17:12:06 +05:30
sathwikcs
af7b426416 Merge remote-tracking branch 'origin/dev-server-2.1.131-network' into dev-server-2.1.131-network 2025-01-28 16:12:21 +05:30
sathwikcs
07abfcce6c updated build.gradle to make the api 31 as the min sdk from 21 -> 30 as device targets api 31 2025-01-28 16:12:00 +05:30
sathwikcs
2c62cc11ba updated build.gradle to make the api 31 as the min sdk from 21 -> 30 as device targets api 31 2025-01-28 16:11:42 +05:30
sathwikcs
312e2da79a TrueHemeViewmodel to fit new network Checker 2025-01-28 16:10:40 +05:30
sathwikcs
9768a0a835 updated TrueHeme TestViewmodel.kt NetworkChecker.kt 2025-01-28 16:08:29 +05:30
sathwikcs
db7aba4549 updated NetworkChecker.kt 2025-01-28 16:07:27 +05:30
sathwikcs
302239d191 Network Checker updated in TestRightViewModel 2025-01-28 12:50:14 +05:30
sathwikcs
cc1ae1ff82 Network Checker updated in NetworkStatusLiveData.kt 2025-01-28 12:49:06 +05:30
sathwikcs
d420a42fcc Network Checker 2025-01-28 12:47:39 +05:30
sathwikcs
21b3960ca9 Merge remote-tracking branch 'origin/dev-server-2.1.130-review-retryUsb' into dev-server-2.1.130-review-retryUsb 2025-01-22 15:00:55 +05:30
19 changed files with 419 additions and 305 deletions

View File

@@ -1,3 +1,5 @@
# Latest hpos app version
## current version : 2.1.132
### Release key ### Release key

View File

@@ -18,9 +18,9 @@ android {
// server -> for server switching for internal test // server -> for server switching for internal test
defaultConfig { defaultConfig {
applicationId "in.sminnovations.hpostesting.server" applicationId "in.sminnovations.hpostesting.server"
minSdk 21 minSdk 30
targetSdk 34 targetSdk 34
versionCode 133 versionCode 134
versionName "2.1.131" versionName "2.1.131"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -30,6 +30,7 @@ android {
release { release {
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
} }
} }
compileOptions { compileOptions {

View File

@@ -1,33 +1,33 @@
{ {
"project_info": { "project_info": {
"project_number": "650071678820", "project_number": "1012719870714",
"project_id": "hpos-af3cc", "project_id": "hpos-prod",
"storage_bucket": "hpos-af3cc.appspot.com" "storage_bucket": "hpos-prod.appspot.com"
}, },
"client": [ "client": [
{ {
"client_info": { "client_info": {
"mobilesdk_app_id": "1:650071678820:android:f6fd45e2f6a63aef6c6471", "mobilesdk_app_id": "1:1012719870714:android:d8d7c962d96f4097de5f43",
"android_client_info": { "android_client_info": {
"package_name": "in.sminnovations.hpostesting.server" "package_name": "in.sminnovations.hpostesting.server"
} }
}, },
"oauth_client": [ "oauth_client": [
{ {
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", "client_id": "1012719870714-uli6cdjea3lfnnueh6e4r15i10ei1vlj.apps.googleusercontent.com",
"client_type": 3 "client_type": 3
} }
], ],
"api_key": [ "api_key": [
{ {
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I" "current_key": "AIzaSyA_O0oZGzy3Kiw9fiLQ3OFPME-xQJP88vs"
} }
], ],
"services": { "services": {
"appinvite_service": { "appinvite_service": {
"other_platform_oauth_client": [ "other_platform_oauth_client": [
{ {
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com", "client_id": "1012719870714-uli6cdjea3lfnnueh6e4r15i10ei1vlj.apps.googleusercontent.com",
"client_type": 3 "client_type": 3
} }
] ]

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 const val MOLBIO_INTEGRATION = true
const val FIREBASE_INTEGRATION = true const val 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"

View File

@@ -38,6 +38,7 @@ import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.firebase.FirebaseManager 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.NetworkMonitor
import com.example.hpostesting.util.PropertyProvider 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.firestore.FirebaseFirestore
@@ -240,8 +241,12 @@ object AppModule {
return UsbServiceListenerImpl(context) return UsbServiceListenerImpl(context)
} }
@Provides
@Singleton
fun provideNetworkMonitor(
@ApplicationContext context: Context
): NetworkMonitor {
return NetworkMonitor(context).apply { startMonitoring() }
}
} }

View File

@@ -14,6 +14,7 @@ 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 androidx.core.content.edit
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,8 +28,8 @@ import javax.inject.Inject
class FirebaseManager @Inject constructor(private val context: Context) { class FirebaseManager @Inject constructor(private val context: Context) {
private val sharedPreferences = private val sharedPreferencesServerConfig = context.getSharedPreferences("FirebaseConfigPrefs", Context.MODE_PRIVATE)
context.getSharedPreferences("FirebaseConfigPrefs", 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()
@@ -36,7 +37,7 @@ class FirebaseManager @Inject constructor(private val context: Context) {
private val defaultServers = listOf( private val defaultServers = listOf(
// i have it in different place look down // i have it in different place look down
firebaseConfig1, firebaseConfig2, firebaseConfig3, firebaseConfigProd, firebaseConfigDev , firebaseConfigQaQc, firebaseConfigPreProd
) )
init { init {
@@ -44,6 +45,18 @@ class FirebaseManager @Inject constructor(private val context: Context) {
switchServer(lastSelectedServer) switchServer(lastSelectedServer)
} }
fun setDevModeOn(state : Boolean){
sharedPreferencesDev.edit {
putBoolean( "isDevModeOn",state )
}
}
fun getDevMode(): Boolean {
return sharedPreferencesDev.getBoolean("isDevModeOn",false)
}
fun getCurrentFirestore(): FirebaseFirestore = currentFirestore fun getCurrentFirestore(): FirebaseFirestore = currentFirestore
fun getCurrentStorage(): FirebaseStorage = currentStorage fun getCurrentStorage(): FirebaseStorage = currentStorage
@@ -73,7 +86,7 @@ class FirebaseManager @Inject constructor(private val context: Context) {
} }
private fun saveSelectedServer(firebaseConfig: FirebaseConfig) { private fun saveSelectedServer(firebaseConfig: FirebaseConfig) {
with(sharedPreferences.edit()) { with(sharedPreferencesServerConfig.edit()) {
putString("selectedServerName", firebaseConfig.serverName) putString("selectedServerName", firebaseConfig.serverName)
putString("projectId", firebaseConfig.projectId) putString("projectId", firebaseConfig.projectId)
putString("appId", firebaseConfig.appId) putString("appId", firebaseConfig.appId)
@@ -93,12 +106,12 @@ class FirebaseManager @Inject constructor(private val context: Context) {
fun getLastSelectedServer(): FirebaseConfig { fun getLastSelectedServer(): FirebaseConfig {
val selectedServerName = val selectedServerName =
sharedPreferences.getString("selectedServerName", defaultServers.first().serverName) sharedPreferencesServerConfig.getString("selectedServerName", defaultServers.first().serverName)
val projectId = sharedPreferences.getString("projectId", defaultServers.first().projectId) val projectId = sharedPreferencesServerConfig.getString("projectId", defaultServers.first().projectId)
val appId = sharedPreferences.getString("appId", defaultServers.first().appId) val appId = sharedPreferencesServerConfig.getString("appId", defaultServers.first().appId)
val apiKey = sharedPreferences.getString("apiKey", defaultServers.first().apiKey) val apiKey = sharedPreferencesServerConfig.getString("apiKey", defaultServers.first().apiKey)
val storageBucket = val storageBucket =
sharedPreferences.getString("storageBucket", defaultServers.first().storageBucket) sharedPreferencesServerConfig.getString("storageBucket", defaultServers.first().storageBucket)
return FirebaseConfig( return FirebaseConfig(
serverName = selectedServerName ?: defaultServers.first().serverName, serverName = selectedServerName ?: defaultServers.first().serverName,
@@ -128,7 +141,7 @@ fun delayedRestart(context: Context) {
} }
} }
private val firebaseConfig1 = FirebaseConfig( private val firebaseConfigDev = FirebaseConfig(
serverName = "dev", serverName = "dev",
apiKey = "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I", apiKey = "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I",
appId = "1:650071678820:android:a53292637abb7c0d6c6471", appId = "1:650071678820:android:a53292637abb7c0d6c6471",
@@ -136,7 +149,7 @@ private val firebaseConfig1 = FirebaseConfig(
storageBucket = "hpos-af3cc.appspot.com" storageBucket = "hpos-af3cc.appspot.com"
) )
private val firebaseConfig2 = FirebaseConfig( private val firebaseConfigQaQc = FirebaseConfig(
serverName = "qc-qa", serverName = "qc-qa",
apiKey = "AIzaSyC4d4GhWHr_NMJAeBvnztQ_yQ3Qe9MAnLs", apiKey = "AIzaSyC4d4GhWHr_NMJAeBvnztQ_yQ3Qe9MAnLs",
appId = "1:1004619739289:android:3dbcefb10ea99654e5c808", appId = "1:1004619739289:android:3dbcefb10ea99654e5c808",
@@ -144,10 +157,18 @@ private val firebaseConfig2 = FirebaseConfig(
storageBucket = "hpos-qa.appspot.com" storageBucket = "hpos-qa.appspot.com"
) )
private val firebaseConfig3 = FirebaseConfig( private val firebaseConfigProd = FirebaseConfig(
serverName = "prod", serverName = "prod",
apiKey = "AIzaSyA_O0oZGzy3Kiw9fiLQ3OFPME-xQJP88vs",
appId = "1:1012719870714:android:d8d7c962d96f4097de5f43",
projectId = "hpos-prod",
storageBucket = "hpos-prod.appspot.com"
)
private val firebaseConfigPreProd = FirebaseConfig(
serverName = "pre prod",
apiKey = "AIzaSyDYySi27LioZGNisP1NfnNU5inJX_0FT38", apiKey = "AIzaSyDYySi27LioZGNisP1NfnNU5inJX_0FT38",
appId = "1:121176529204:android:a7bc0842f61e5095bbed61", appId = "1:121176529204:android:e6841fdac57bdc95bbed61",
projectId = "hpos-preprod", projectId = "hpos-preprod",
storageBucket = "hpos-preprod.appspot.com" storageBucket = "hpos-preprod.appspot.com"
) )

View File

@@ -141,6 +141,9 @@ 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") {
// moveToNext()
// }else{
if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") { if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") {
moveToNext() moveToNext()
}else{ }else{

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

@@ -13,7 +13,6 @@
package com.example.hpostesting.presentation.main_base package com.example.hpostesting.presentation.main_base
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
@@ -29,15 +28,21 @@ 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 com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.Constants.FIREBASE_INTEGRATION
import com.example.hpostesting.data.constant.Constants.MOLBIO_INTEGRATION
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.repository.DatabaseRepository import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.firebase.FirebaseConfig import com.example.hpostesting.firebase.FirebaseConfig
import com.example.hpostesting.firebase.FirebaseManager import com.example.hpostesting.firebase.FirebaseManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
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() {
@@ -58,7 +63,6 @@ class SlideshowFragment : Fragment() {
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()
binding.btnGo.setOnClickListener { binding.btnGo.setOnClickListener {
var labname = binding.nameEditText.text.toString() var labname = binding.nameEditText.text.toString()
@@ -97,6 +101,7 @@ class SlideshowFragment : Fragment() {
// 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()) {
@@ -113,24 +118,25 @@ class SlideshowFragment : Fragment() {
} }
} }
class PrefsFragment : PreferenceFragmentCompat(){ class PrefsFragment : PreferenceFragmentCompat() {
private lateinit var tapManager: AppVersionTapManager private lateinit var tapManager: AppVersionTapManager
private var isServerSelectionVisible = false
private lateinit var serverPreference: Preference private lateinit var serverPreference: Preference
private lateinit var currentServerPreference: Preference private lateinit var currentServerPreference: Preference
lateinit var firebaseManager: FirebaseManager lateinit var firebaseManager: FirebaseManager
private var topDevMode = false
lateinit var databaseRepository: DatabaseRepository lateinit var databaseRepository: DatabaseRepository
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
firebaseManager = FirebaseManager(requireContext()) firebaseManager = FirebaseManager(requireContext())
databaseRepository = (activity as DashboardActivity).databaseRepository databaseRepository = (activity as DashboardActivity).databaseRepository
tapManager = AppVersionTapManager() tapManager = AppVersionTapManager()
topDevMode = firebaseManager.getDevMode()
val sharedPreference = val sharedPreference =
requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
val preferenceScreen = preferenceManager.createPreferenceScreen(requireContext()) val preferenceScreen = preferenceManager.createPreferenceScreen(requireContext())
val currentServer = firebaseManager.getLastSelectedServer().serverName val currentServer = firebaseManager.getLastSelectedServer().serverName
// Language Preference // Language Preference
val languagePreference = ListPreference(requireContext()).apply { val languagePreference = ListPreference(requireContext()).apply {
key = "language_preference" key = "language_preference"
@@ -140,52 +146,102 @@ class PrefsFragment : PreferenceFragmentCompat(){
entryValues = arrayOf("en", "kn", "hi") entryValues = arrayOf("en", "kn", "hi")
setDefaultValue("en") setDefaultValue("en")
icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_translate_24) icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_translate_24)
onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
val languageCode = newValue as String val languageCode = newValue as String
updateLanguage(requireContext(), languageCode) updateLanguage(requireContext(), languageCode)
true true
} }
} }
val servers = firebaseManager.getAvailableServers()
val serverNames = servers.map { it.serverName }.toTypedArray()
val serverSelectorPreference = CustomDialogPreference(requireContext()).apply {
key = "server_preference"
title = "Select the Server"
summary = "Current server: $currentServer"
setEntries(serverNames)
setEntryValues(serverNames)
setValue(currentServer)
icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_cloud_sync_24)
setOnPreferenceChangeListener { newValue ->
val preferenceConfig = servers.find { it.serverName == newValue }
switchFirebaseServer(preferenceConfig!!)
true
}
}
// Add preferences to screen
preferenceScreen.addPreference(languagePreference)
preferenceScreen.addPreference(languagePreference) preferenceScreen.addPreference(languagePreference)
val appVersionPreference = Preference(requireContext()).apply {
title = "App Version"
summary =
getAppVersion(requireContext()) + " [ " + getAppEnvironment(requireContext()) +"->"+currentServer+"]"
icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_info_24)
setOnPreferenceClickListener { val developerToggle = SwitchPreferenceCompat(requireContext()).apply {
if ((sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN")) { title = "Developer Options"
tapManager.registerTap { summary = "Enable or disable developer options"
if (!isServerSelectionVisible) { icon =
showServerSelection() ContextCompat.getDrawable(requireContext(), R.drawable.baseline_developer_mode_24)
} key = "developer_options" // Unique key for SharedPreferences
}
} else {
// Load toggle state from SharedPreferences
isChecked = firebaseManager.getDevMode()
setOnPreferenceChangeListener { _, newValue ->
val isEnabled = newValue as Boolean
firebaseManager.setDevModeOn(isEnabled)
if (!isEnabled) {
preferenceScreen.removePreference(this)
preferenceScreen.removePreference(serverSelectorPreference)
}
if (!firebaseManager.getDevMode() && currentServer != "prod"){
val prodConfig = servers.find { it.serverName == "prod" }
switchFirebaseServer(prodConfig!!)
} }
true true
} }
} }
preferenceScreen.addPreference(appVersionPreference)
val shouldEnableCurrentServerVersion = FIREBASE_INTEGRATION && !MOLBIO_INTEGRATION
currentServerPreference = Preference(requireContext()).apply { val appVersionPreference = Preference(requireContext()).apply {
key = "current_server_preference" title = "App Version"
title = "Current Server" summary =
summary = "No server selected" getAppVersion(requireContext()) + " [ " + getAppEnvironment(requireContext()) + "->" + if (shouldEnableCurrentServerVersion) currentServer else "molbio"+ "]"
isVisible = false icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_info_24)
icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_cloud_done_24)
setOnPreferenceClickListener { setOnPreferenceClickListener {
// (activity as? DashboardActivity)?.sendData("hello test data") tapManager.registerTap {
// Toast.makeText(context, "data sent", Toast.LENGTH_SHORT).show() this was used to send the basic data as test data firebaseManager.setDevModeOn(true)
true
val devConfig = servers.find { it.serverName == "dev" }
if (firebaseManager.getDevMode() && currentServer != "dev") {
Toast.makeText(requireContext(), "Now you are a Developer", Toast.LENGTH_SHORT).show()
Toast.makeText(requireContext(), "Setting Up developer Environmnet", Toast.LENGTH_SHORT).show()
switchFirebaseServer(devConfig!!)
}
if (preferenceScreen.findPreference<SwitchPreferenceCompat>("developer_options") == null) {
preferenceScreen.addPreference(developerToggle)
}
if (preferenceScreen.findPreference<ListPreference>("server_preference") == null) {
preferenceScreen.addPreference(serverSelectorPreference)
}
developerToggle.isChecked = true
updateServerPreference(currentServer)
}
true
} }
} }
preferenceScreen.addPreference(currentServerPreference)
preferenceScreen.addPreference(appVersionPreference)
if (firebaseManager.getDevMode()) {
developerToggle.isChecked = true // Ensure it's checked
preferenceScreen.addPreference(developerToggle)
preferenceScreen.addPreference(serverSelectorPreference)
}
setPreferenceScreen(preferenceScreen) setPreferenceScreen(preferenceScreen)
if (isLanguageChanged) { if (isLanguageChanged) {
@@ -194,58 +250,23 @@ class PrefsFragment : PreferenceFragmentCompat(){
} }
private fun showServerSelection() { private fun updateServerPreference(newServer: String) {
val currentServer = firebaseManager.getLastSelectedServer().serverName (findPreference<CustomDialogPreference>("server_preference"))?.let { pref ->
serverPreference = Preference(requireContext()).apply { pref.setValue(newServer)
title = "Select Server" pref.summary = "Current server: $newServer"
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) { private fun switchFirebaseServer(firebaseConfig: FirebaseConfig) {
firebaseManager.switchServer(firebaseConfig) firebaseManager.switchServer(firebaseConfig)
Toast.makeText(requireContext(), "Switched to ${firebaseConfig.serverName}, Please wait for few seconds", Toast.LENGTH_SHORT).show() Toast.makeText(
Toast.makeText(requireContext(), "Restart needed restarting the app", Toast.LENGTH_SHORT).show() requireContext(),
firebaseManager.restartApp() "Switched to ${firebaseConfig.serverName}, Please wait for few seconds",
currentServerPreference.summary = "Current Server: ${firebaseConfig.serverName}" Toast.LENGTH_SHORT
).show()
} Toast.makeText(requireContext(), "Restart needed restarting the app", Toast.LENGTH_SHORT)
private fun switchCurrentServer(serverCode: String) {
Toast.makeText(requireContext(), "Switched to server: $serverCode", Toast.LENGTH_SHORT)
.show() .show()
currentServerPreference.summary = "Current Server: $serverCode" firebaseManager.restartApp()
} }
private fun updateLanguage(context: Context, languageCode: String) { private fun updateLanguage(context: Context, languageCode: String) {
@@ -275,3 +296,47 @@ class PrefsFragment : PreferenceFragmentCompat(){
} }
// CustomDialogPreference.kt
class CustomDialogPreference(context: Context) : Preference(context) {
private var entries: Array<String> = arrayOf()
private var entryValues: Array<String> = arrayOf()
private var currentValue: String = ""
private var onValueChangeListener: ((String) -> Boolean)? = null
fun setEntries(entries: Array<String>) {
this.entries = entries
}
fun setEntryValues(values: Array<String>) {
this.entryValues = values
}
fun setValue(value: String) {
currentValue = value
persistString(value)
}
fun setOnPreferenceChangeListener(listener: (String) -> Boolean) {
onValueChangeListener = listener
}
override fun onClick() {
val builder = MaterialAlertDialogBuilder(context)
builder.setTitle(title)
builder.setSingleChoiceItems(entries, entries.indexOf(currentValue)) { dialog, which ->
val newValue = entryValues[which]
if (onValueChangeListener?.invoke(newValue) == true) {
setValue(newValue)
dialog.dismiss()
}
}
builder.setNegativeButton("Cancel") { dialog, _ ->
dialog.dismiss()
}
builder.show()
}
}

View File

@@ -19,7 +19,6 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.UserDao import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.model.CalculationVariableForTest import com.example.hpostesting.data.model.CalculationVariableForTest
@@ -36,6 +35,7 @@ import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.domain.SickleFindResultCaluculationWithMaxImpl import com.example.hpostesting.domain.SickleFindResultCaluculationWithMaxImpl
import com.example.hpostesting.domain.TestRightResultCalculation import com.example.hpostesting.domain.TestRightResultCalculation
import com.example.hpostesting.util.MyUtils import com.example.hpostesting.util.MyUtils
import com.example.hpostesting.util.NetworkMonitor
import com.google.firebase.storage.FirebaseStorage import com.google.firebase.storage.FirebaseStorage
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -55,10 +55,10 @@ class TestRightViewModel @Inject constructor(
private val saveRawDataTest: SaveRawDataTest, private val saveRawDataTest: SaveRawDataTest,
private val repository: DatabaseRepository, private val repository: DatabaseRepository,
private val userDao: UserDao, private val userDao: UserDao,
networkMonitor: NetworkMonitor,
context: Context? context: Context?
) : ViewModel() { ) : ViewModel() {
var isServiceConnected = false var isServiceConnected = false
val progressBar = MutableLiveData(false) val progressBar = MutableLiveData(false)
@@ -69,9 +69,8 @@ class TestRightViewModel @Inject constructor(
var testDetails = DataHolder.selectedTest var testDetails = DataHolder.selectedTest
private val _networkStatusLiveData = context?.let { NetworkStatusLiveData(it) } private var _networkStatusLiveData = networkMonitor.isConnected
val networkStatusLiveData: NetworkStatusLiveData? val networkStatusLiveData = _networkStatusLiveData
get() = _networkStatusLiveData
val allUserData = userDao.getAll() val allUserData = userDao.getAll()
@@ -82,6 +81,11 @@ class TestRightViewModel @Inject constructor(
val calculationVariableList = ArrayList<CalculationVariableForTest>() val calculationVariableList = ArrayList<CalculationVariableForTest>()
init {
networkMonitor.startMonitoring()
_networkStatusLiveData = networkMonitor.isConnected
}
fun mapDeviceConstants(string: String) { fun mapDeviceConstants(string: String) {
if (string.isNotEmpty()) { if (string.isNotEmpty()) {
val listOfStrings = string.split(",") val listOfStrings = string.split(",")

View File

@@ -25,11 +25,8 @@ import androidx.lifecycle.viewModelScope
import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager import androidx.work.WorkManager
import com.example.hpostesting.util.CsvWriter
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.NetworkStatusLiveData
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.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.datasource.LocalFileDataSource import com.example.hpostesting.data.datasource.LocalFileDataSource
@@ -46,10 +43,12 @@ import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData import com.example.hpostesting.data.model.patient.toHemoCubeTestData
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.repository.Repository import com.example.hpostesting.data.repository.Repository
import com.example.hpostesting.domain.CheckUpdateWorker import com.example.hpostesting.domain.CheckUpdateWorker
import com.example.hpostesting.domain.LogFileManager import com.example.hpostesting.domain.LogFileManager
import com.example.hpostesting.util.CsvWriter
import com.example.hpostesting.util.NetworkMonitor
import com.example.hpostesting.util.Result
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
@@ -70,20 +69,22 @@ class TrueHemeViewModel @Inject constructor(
private val repository: Repository, private val repository: Repository,
private val logFileManager: LogFileManager, private val logFileManager: LogFileManager,
private val localFileDataSource: LocalFileDataSource, private val localFileDataSource: LocalFileDataSource,
networkMonitor: NetworkMonitor,
context: Context, context: Context,
) : ViewModel() { ) : ViewModel() {
var isServiceConnected = false var isServiceConnected = false
val progressBar = MutableLiveData(false) val progressBar = MutableLiveData(false)
private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
val messages = MutableLiveData<String>() val messages = MutableLiveData<String>()
private val sharedPreference = private val sharedPreference = context.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
context.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
private val workManager = WorkManager.getInstance(context) private val workManager = WorkManager.getInstance(context)
// init {
// init { // startPeriodicCheckUpdate()
// startPeriodicCheckUpdate() // }
// } init {
networkMonitor.startMonitoring()
}
val loginResponse = MutableLiveData<Result<LoginResponse>>() val loginResponse = MutableLiveData<Result<LoginResponse>>()
@@ -97,7 +98,7 @@ class TrueHemeViewModel @Inject constructor(
// Get the device ID of the device you want to retrieve data for (e.g., the first device in the list) // Get the device ID of the device you want to retrieve data for (e.g., the first device in the list)
private val _networkStatusLiveData = NetworkStatusLiveData(context) private val _networkStatusLiveData = networkMonitor.isConnected
val allUserData = hemoCubeDao.getAll() val allUserData = hemoCubeDao.getAll()
val allKitTestData = hemoCubeBufferDao.getAll() val allKitTestData = hemoCubeBufferDao.getAll()
val deviceData = MutableLiveData<DeviceData?>() val deviceData = MutableLiveData<DeviceData?>()
@@ -181,7 +182,7 @@ class TrueHemeViewModel @Inject constructor(
val logFile = logFileManager.createLogFile().let { file -> val logFile = logFileManager.createLogFile().let { file ->
val requestBody = file?.asRequestBody("multipart/form-data".toMediaTypeOrNull()) val requestBody = file?.asRequestBody("multipart/form-data".toMediaTypeOrNull())
val multipartFile = val multipartFile =
requestBody?.let { MultipartBody.Part.createFormData("logFile", file?.name, it) } requestBody?.let { MultipartBody.Part.createFormData("logFile", file.name, it) }
multipartFile?.let { partFile -> multipartFile?.let { partFile ->
repository.uploadLogs(partFile).let { result -> repository.uploadLogs(partFile).let { result ->
uploadLogs.postValue(result) uploadLogs.postValue(result)
@@ -193,37 +194,35 @@ class TrueHemeViewModel @Inject constructor(
fun uploadHemoCubeResultToDatabaseForBufferCheck( fun uploadHemoCubeResultToDatabaseForBufferCheck(
isOnline: Boolean, isOnline: Boolean,
bufferCheckData: BufferCheckData, bufferCheckData: BufferCheckData,
) = ) = viewModelScope.launch {
viewModelScope.launch { if (isOnline) {
if (isOnline) { try {
try { when (val response = repository.addTestToDatabaseforBufferCheck(bufferCheckData)) {
when (val response = is Response.Success -> {
repository.addTestToDatabaseforBufferCheck(bufferCheckData)) { Log.i("Testdb", "Data uploaded to Firestore successfully")
is Response.Success -> { fireBaseUpload.postValue("Success")
Log.i("Testdb", "Data uploaded to Firestore successfully") bufferCheckData.localFlag = true
fireBaseUpload.postValue("Success") hemoCubeBufferDao.insertAll(bufferCheckData)
bufferCheckData.localFlag = true
hemoCubeBufferDao.insertAll(bufferCheckData)
}
is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
bufferCheckData.localFlag = true
hemoCubeBufferDao.insertAll(bufferCheckData)
}
else -> {}
} }
} catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}") is Response.Error -> {
fireBaseUpload.postValue("Error") Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
bufferCheckData.localFlag = true
hemoCubeBufferDao.insertAll(bufferCheckData)
}
else -> {}
} }
} else { } catch (e: Exception) {
hemoCubeBufferDao.insertAll(bufferCheckData) Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Local") fireBaseUpload.postValue("Error")
} }
} else {
hemoCubeBufferDao.insertAll(bufferCheckData)
fireBaseUpload.postValue("Local")
} }
}
fun bulkAddResultKitTestToDb(bufferCheckData: BufferCheckData) { fun bulkAddResultKitTestToDb(bufferCheckData: BufferCheckData) {
viewModelScope.launch { viewModelScope.launch {
@@ -396,8 +395,7 @@ class TrueHemeViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
try { try {
when (val response = when (val response = repository.addTestToDatabaseforBufferCheck(bufferCheckData)) {
repository.addTestToDatabaseforBufferCheck(bufferCheckData)) {
is Response.Success -> { is Response.Success -> {
Log.i("Testdb", "Data uploaded to Firestore successfully") Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success") fireBaseUpload.postValue("Success")
@@ -415,10 +413,9 @@ class TrueHemeViewModel @Inject constructor(
} }
} }
private fun updateBufferLocalFlag(bufferId: String) = private fun updateBufferLocalFlag(bufferId: String) = viewModelScope.launch {
viewModelScope.launch { hemoCubeBufferDao.updateFieldById(id = bufferId, true)
hemoCubeBufferDao.updateFieldById(id = bufferId, true) }
}
fun getLocalUserDataForCsv(context: Context): Boolean { fun getLocalUserDataForCsv(context: Context): Boolean {
val localUserDataLiveData: LiveData<List<HemoCubeTestData>> = hemoCubeDao.getAll() val localUserDataLiveData: LiveData<List<HemoCubeTestData>> = hemoCubeDao.getAll()
@@ -455,16 +452,12 @@ class TrueHemeViewModel @Inject constructor(
fun getBatteryLevel(): Float? { fun getBatteryLevel(): Float? {
val batteryPct: Float? = batteryStatus?.let { intent -> val batteryPct: Float? = batteryStatus?.let { intent ->
val level: Int = val level: Int = intent.getIntExtra(
intent.getIntExtra( BatteryManager.EXTRA_LEVEL, -1
BatteryManager.EXTRA_LEVEL, )
-1 val scale: Int = intent.getIntExtra(
) BatteryManager.EXTRA_SCALE, -1
val scale: Int = )
intent.getIntExtra(
BatteryManager.EXTRA_SCALE,
-1
)
level * 100 / scale.toFloat() level * 100 / scale.toFloat()
} }
@@ -474,8 +467,7 @@ class TrueHemeViewModel @Inject constructor(
fun getBatteryTemperature(): Float? { fun getBatteryTemperature(): Float? {
val batteryTemp: Float? = batteryStatus?.let { intent -> val batteryTemp: Float? = batteryStatus?.let { intent ->
val temperature = intent.getIntExtra( val temperature = intent.getIntExtra(
BatteryManager.EXTRA_TEMPERATURE, BatteryManager.EXTRA_TEMPERATURE, 0
0
) )
temperature.toFloat() / 10 temperature.toFloat() / 10
} }
@@ -484,14 +476,11 @@ class TrueHemeViewModel @Inject constructor(
} }
fun getBatteryVoltage(context: Context): Float { fun getBatteryVoltage(context: Context): Float {
val batteryIntent = val batteryIntent = context.registerReceiver(
context.registerReceiver( null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)
null, )
IntentFilter(Intent.ACTION_BATTERY_CHANGED)
)
val voltage = batteryIntent?.getIntExtra( val voltage = batteryIntent?.getIntExtra(
BatteryManager.EXTRA_VOLTAGE, BatteryManager.EXTRA_VOLTAGE, 0
0
) ?: 0 ) ?: 0
// milli-volts to volts // milli-volts to volts
@@ -500,8 +489,7 @@ class TrueHemeViewModel @Inject constructor(
fun getBatteryCapacity(context: Context): Int { fun getBatteryCapacity(context: Context): Int {
val batteryManager = val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val currentCapacity = val currentCapacity =
batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER) batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER)
@@ -510,8 +498,7 @@ class TrueHemeViewModel @Inject constructor(
fun getBatteryMaxCapacity(context: Context): Float { fun getBatteryMaxCapacity(context: Context): Float {
val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val designCapacity = val designCapacity = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
val currentCapacity = val currentCapacity =
batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER) batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER)
@@ -528,8 +515,7 @@ class TrueHemeViewModel @Inject constructor(
hemoCubeTestData.forEach { data -> hemoCubeTestData.forEach { data ->
data.localFlag = true data.localFlag = true
hemoCubeDao.updateCSVFieldById( hemoCubeDao.updateCSVFieldById(
data._id, data._id, true
true
) )
} }
} }

View File

@@ -1390,6 +1390,7 @@ class TrueHemeTestFragment : Fragment() {
apply() apply()
} }
} }
trueHemeTestViewModel.updateLocalData()
} catch (e: Exception) { } catch (e: Exception) {
Toast.makeText( Toast.makeText(
requireContext(), requireContext(),

View File

@@ -27,7 +27,6 @@ import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager import androidx.work.WorkManager
import com.example.hpostesting.util.CsvWriter import com.example.hpostesting.util.CsvWriter
import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.NetworkStatusLiveData
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
import com.example.hpostesting.data.dao.HemoCubeBufferDao import com.example.hpostesting.data.dao.HemoCubeBufferDao
@@ -50,6 +49,7 @@ import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import com.example.hpostesting.data.repository.Repository import com.example.hpostesting.data.repository.Repository
import com.example.hpostesting.domain.CheckUpdateWorker import com.example.hpostesting.domain.CheckUpdateWorker
import com.example.hpostesting.domain.LogFileManager import com.example.hpostesting.domain.LogFileManager
import com.example.hpostesting.util.NetworkMonitor
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -72,6 +72,7 @@ class TrueHemeTestViewModel @Inject constructor(
private val repository: Repository, private val repository: Repository,
private val logFileManager: LogFileManager, private val logFileManager: LogFileManager,
private val localFileDataSource: LocalFileDataSource, private val localFileDataSource: LocalFileDataSource,
networkMonitor: NetworkMonitor,
context: Context, context: Context,
) : ViewModel() { ) : ViewModel() {
private var testUpload: Boolean = false private var testUpload: Boolean = false
@@ -87,6 +88,9 @@ class TrueHemeTestViewModel @Inject constructor(
// init { // init {
// startPeriodicCheckUpdate() // startPeriodicCheckUpdate()
// } // }
init {
networkMonitor.startMonitoring()
}
val loginResponse = MutableLiveData<Result<LoginResponse>>() val loginResponse = MutableLiveData<Result<LoginResponse>>()
@@ -103,7 +107,7 @@ class TrueHemeTestViewModel @Inject constructor(
// Get the device ID of the device you want to retrieve data for (e.g., the first device in the list) // Get the device ID of the device you want to retrieve data for (e.g., the first device in the list)
private val _networkStatusLiveData = NetworkStatusLiveData(context) private val _networkStatusLiveData =networkMonitor.isConnected
val allUserData = hemoCubeDao.getAll() val allUserData = hemoCubeDao.getAll()
val allLocalData = hemoCubeDao.getAll() val allLocalData = hemoCubeDao.getAll()
val allPendingUserToUpload = hemoCubeDao.getPendingUser() val allPendingUserToUpload = hemoCubeDao.getPendingUser()
@@ -791,4 +795,11 @@ class TrueHemeTestViewModel @Inject constructor(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
} }
fun updateLocalData() {
viewModelScope.launch {
parseData()
hemoCubeDao.updateTest(testDetails!!)
}
}
} }

View File

@@ -0,0 +1,117 @@
package com.example.hpostesting.util
import android.annotation.SuppressLint
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.net.HttpURLConnection
import java.net.URL
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class NetworkMonitor @Inject constructor(
@ApplicationContext private val context: Context
) {
private var isMonitoringStarted = false
private val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private val _isConnected = MutableLiveData(false)
val isConnected: LiveData<Boolean> get() = _isConnected
private val networkScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
performPingCheck()
}
override fun onLost(network: Network) {
_isConnected.postValue(false)
}
override fun onCapabilitiesChanged(
network: Network, networkCapabilities: NetworkCapabilities
) {
// Recheck connectivity when capabilities change (e.g., network becomes validated)
performPingCheck()
}
}
@SuppressLint("NewApi")
fun startMonitoring() {
if (isMonitoringStarted) return // Already started, do nothing.
isMonitoringStarted = true
// Check initial connectivity status
val network = connectivityManager.activeNetwork
val capabilities = connectivityManager.getNetworkCapabilities(network)
val isInitiallyConnected = capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true
if (isInitiallyConnected) {
performPingCheck()
} else {
_isConnected.postValue(false)
}
val networkRequest =
NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
// Start periodic checks:
startPeriodicPingCheck()
}
fun stopMonitoring() { // never needed to call
try {
connectivityManager.unregisterNetworkCallback(networkCallback)
} catch (_: IllegalArgumentException) {
// Ignore if callback was not registered
}
networkScope.cancel()
}
private fun performPingCheck() {
networkScope.launch {
try {
val url = URL("https://www.google.com")
val connection = url.openConnection() as HttpURLConnection
connection.connectTimeout = 2000
connection.readTimeout = 2000
connection.setRequestProperty("Connection", "close")
connection.connect()
// Consider any 2xx response as successful
val isReachable = connection.responseCode in 200..299
_isConnected.postValue(isReachable)
connection.disconnect()
} catch (e: Exception) {
_isConnected.postValue(false)
}
}
}
private fun startPeriodicPingCheck(intervalMillis: Long = 1 * 60_000L) {
networkScope.launch {
while (isActive) {
performPingCheck()
delay(intervalMillis)
}
}
}
}

View File

@@ -1,75 +0,0 @@
/*
* // 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.
*/
package com.example.hpostesting.util
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.lifecycle.LiveData
class NetworkStatusLiveData(context: Context) : LiveData<Boolean>() {
private val connectivityManager: ConnectivityManager =
context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
postValue(true)
}
override fun onLost(network: Network) {
postValue(false)
}
}
@RequiresApi(Build.VERSION_CODES.M)
override fun onActive() {
super.onActive()
postValue(isNetworkAvailable())
registerNetworkCallback()
}
override fun onInactive() {
super.onInactive()
unregisterNetworkCallback()
}
private fun registerNetworkCallback() {
val networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.build()
connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
}
private fun unregisterNetworkCallback() {
connectivityManager.unregisterNetworkCallback(networkCallback)
}
@RequiresApi(Build.VERSION_CODES.M)
private fun isNetworkAvailable(): Boolean {
val network = connectivityManager.activeNetwork
val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
return networkCapabilities != null &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}
}

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="M7,5h10v2h2L19,3c0,-1.1 -0.9,-1.99 -2,-1.99L7,1c-1.1,0 -2,0.9 -2,2v4h2L7,5zM15.41,16.59L20,12l-4.59,-4.59L14,8.83 17.17,12 14,15.17l1.41,1.42zM10,15.17L6.83,12 10,8.83 8.59,7.41 4,12l4.59,4.59L10,15.17zM17,19L7,19v-2L5,17v4c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2v-4h-2v2z"/>
</vector>

View File

@@ -1,38 +0,0 @@
<?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

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

@@ -16,12 +16,12 @@ package com.example.hpostesting
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.repository.Repository import com.example.hpostesting.data.repository.Repository
import com.example.hpostesting.presentation.autodac.AutoDacViewModel import com.example.hpostesting.presentation.autodac.AutoDacViewModel
import com.example.hpostesting.util.NetworkMonitor
import io.mockk.* import io.mockk.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -43,7 +43,7 @@ class AutoDacViewModelTest {
private val repository = mockk<Repository>() private val repository = mockk<Repository>()
private val context = mockk<Context>() private val context = mockk<Context>()
private val sharedPreferences = mockk<SharedPreferences>() private val sharedPreferences = mockk<SharedPreferences>()
private val networkStatusLiveData = mockk<NetworkStatusLiveData>() private val networkStatusLiveData = mockk<NetworkMonitor>()
@Before @Before
fun setup() { fun setup() {
@@ -54,7 +54,7 @@ class AutoDacViewModelTest {
every { context.getSystemService(any()) } returns networkStatusLiveData every { context.getSystemService(any()) } returns networkStatusLiveData
// Mocking the NetworkStatusLiveData // Mocking the NetworkStatusLiveData
every { networkStatusLiveData.observe(any(), any()) } just Runs every { networkStatusLiveData.startMonitoring() } just Runs
every { hemoCubeDao.getAll() } returns mockk() every { hemoCubeDao.getAll() } returns mockk()
// every { repository.addDiagnostics(any()) } returns Response.Success(Unit) // every { repository.addDiagnostics(any()) } returns Response.Success(Unit)