Compare commits
6 Commits
dev-server
...
smi_131_re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c89efeb5e | ||
|
|
63eaf1cadc | ||
|
|
c180f7be31 | ||
|
|
c243ec6c8f | ||
|
|
7c9238591b | ||
|
|
5c843ca232 |
@@ -21,7 +21,7 @@ android {
|
|||||||
minSdk 30
|
minSdk 30
|
||||||
targetSdk 34
|
targetSdk 34
|
||||||
versionCode 134
|
versionCode 134
|
||||||
versionName "2.1.132"
|
versionName "2.1.131"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -47,7 +47,6 @@ object Constants {
|
|||||||
|
|
||||||
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_SINGLE_TEST = 0
|
|
||||||
|
|
||||||
const val RANGE_IN_RESULT_CALCULATIONS = 10
|
const val RANGE_IN_RESULT_CALCULATIONS = 10
|
||||||
|
|
||||||
@@ -1587,7 +1586,6 @@ object Constants {
|
|||||||
//Trueheme for 10mm
|
//Trueheme for 10mm
|
||||||
//Before changing below values review before
|
//Before changing below values review before
|
||||||
//classification borderline metric
|
//classification borderline metric
|
||||||
const val TEST_FOR_10MM = "SMI/SC-2-D10/"
|
|
||||||
const val positiveBoderLineMetricCheck10mmMin = 1.3
|
const val positiveBoderLineMetricCheck10mmMin = 1.3
|
||||||
const val positiveBoderLineMetricCheck10mmMax = 1.66
|
const val positiveBoderLineMetricCheck10mmMax = 1.66
|
||||||
const val negativeBoderLineMetricCheck10mmMin = 2.0
|
const val negativeBoderLineMetricCheck10mmMin = 2.0
|
||||||
@@ -1605,7 +1603,6 @@ object Constants {
|
|||||||
const val sickleCellDiseaseMax10mm = 0.7
|
const val sickleCellDiseaseMax10mm = 0.7
|
||||||
//Trueheme for 2mm
|
//Trueheme for 2mm
|
||||||
//classification borderline metric
|
//classification borderline metric
|
||||||
const val TEST_FOR_2MM = "SMI/SC/"
|
|
||||||
const val positiveBoderLineMetricCheck2mmMin = 0.8
|
const val positiveBoderLineMetricCheck2mmMin = 0.8
|
||||||
const val positiveBoderLineMetricCheck2mmMax = 1.1
|
const val positiveBoderLineMetricCheck2mmMax = 1.1
|
||||||
const val negativeBoderLineMetricCheck2mmMin = 1.5
|
const val negativeBoderLineMetricCheck2mmMin = 1.5
|
||||||
@@ -1622,25 +1619,6 @@ object Constants {
|
|||||||
const val sickleCellDiseaseMin2mm = 0.45
|
const val sickleCellDiseaseMin2mm = 0.45
|
||||||
const val sickleCellDiseaseMax2mm = 0.7
|
const val sickleCellDiseaseMax2mm = 0.7
|
||||||
|
|
||||||
//Trueheme for 10mm Single Test
|
|
||||||
//classification borderline metric
|
|
||||||
const val singleTest = "SMI/SC-ST/"
|
|
||||||
const val positiveBoderLineMetricCheck2mmStMin = 1.3
|
|
||||||
const val positiveBoderLineMetricCheck2mmStMax = 1.66
|
|
||||||
const val negativeBoderLineMetricCheck2mmStMin = 2.0
|
|
||||||
const val negativeBoderLineMetricCheck2mmStMax = 2.4
|
|
||||||
//classification device ratio
|
|
||||||
const val normalMinSt2mm = 0.07
|
|
||||||
const val normalMaxSt2mm = 0.23
|
|
||||||
const val negativeBorderlineMinSt2mm = 0.23
|
|
||||||
const val negativeBorderlineMaxSt2mm = 0.27
|
|
||||||
const val sickleCellTraitMinSt2mm = 0.27
|
|
||||||
const val sickleCellTraitMaxSt2mm = 0.31
|
|
||||||
const val positiveForSickleCellMinSt2mm = 0.31
|
|
||||||
const val positiveForSickleCellMaxSt2mm = 0.39
|
|
||||||
const val sickleCellDiseaseMinSt2mm = 0.39
|
|
||||||
const val sickleCellDiseaseMaxSt2mm = 0.7
|
|
||||||
|
|
||||||
const val min2mmLed1 = 0.34
|
const val min2mmLed1 = 0.34
|
||||||
const val max2mmLed1 = 1.48
|
const val max2mmLed1 = 1.48
|
||||||
const val min2mmLed2 = 0.04
|
const val min2mmLed2 = 0.04
|
||||||
|
|||||||
@@ -38,16 +38,15 @@ class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun exportDataToCSV(
|
override fun exportDataToCSV(
|
||||||
filePath: String, dataList: List<HemoCubeTestData>,
|
fileName: String, dataList: List<HemoCubeTestData>,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
try {
|
try {
|
||||||
// Create the file directly from the provided path
|
val formattedFileName = fileName.replace(
|
||||||
val file = File(filePath)
|
Regex("[^a-zA-Z0-9.-]"),
|
||||||
|
"_"
|
||||||
// Ensure parent directory exists
|
) // Replace special characters with underscores
|
||||||
file.parentFile?.mkdirs()
|
val filePath = File(getExternalStorageDirectory(), formattedFileName)
|
||||||
|
val writer = FileWriter(filePath)
|
||||||
val writer = FileWriter(file)
|
|
||||||
val csvWriter = CSVWriter(writer)
|
val csvWriter = CSVWriter(writer)
|
||||||
// Write CSV header
|
// Write CSV header
|
||||||
val header = arrayOf(
|
val header = arrayOf(
|
||||||
@@ -104,8 +103,8 @@ class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
|
|||||||
csvWriter.writeNext(header)
|
csvWriter.writeNext(header)
|
||||||
|
|
||||||
// Filter and write data rows where testStatus is true
|
// Filter and write data rows where testStatus is true
|
||||||
// val filteredDataList = dataList.filter { it.testStatus == true }
|
val filteredDataList = dataList.filter { it.testStatus == true }
|
||||||
for (data in dataList) {
|
for (data in filteredDataList) {
|
||||||
val row = arrayOf(
|
val row = arrayOf(
|
||||||
data._id,
|
data._id,
|
||||||
data.name,
|
data.name,
|
||||||
@@ -227,8 +226,8 @@ class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
|
|||||||
csvWriter.writeNext(header)
|
csvWriter.writeNext(header)
|
||||||
|
|
||||||
// Filter and write data rows where testStatus is true
|
// Filter and write data rows where testStatus is true
|
||||||
//val filteredDataList = dataList.filter { it.testStatus == true }
|
val filteredDataList = dataList.filter { it.testStatus == true }
|
||||||
for (data in dataList) {
|
for (data in filteredDataList) {
|
||||||
val row = arrayOf(
|
val row = arrayOf(
|
||||||
data._id,
|
data._id,
|
||||||
data.name,
|
data.name,
|
||||||
|
|||||||
@@ -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() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -24,9 +24,6 @@ import android.widget.Toast
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
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.Constants.TEST_FOR_10MM
|
|
||||||
import com.example.hpostesting.data.constant.Constants.TEST_FOR_2MM
|
|
||||||
import com.example.hpostesting.data.constant.Constants.singleTest
|
|
||||||
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.presentation.main_base.DashboardActivity
|
import com.example.hpostesting.presentation.main_base.DashboardActivity
|
||||||
@@ -55,7 +52,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 var maxTest = 9
|
|
||||||
private lateinit var sharedPreference: SharedPreferences
|
private lateinit var sharedPreference: SharedPreferences
|
||||||
|
|
||||||
var sdkHandler: SDKHandler? = null
|
var sdkHandler: SDKHandler? = null
|
||||||
@@ -74,27 +71,20 @@ 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(TEST_FOR_2MM)){
|
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(TEST_FOR_10MM)){
|
}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 if(contents.contains(singleTest)){
|
|
||||||
with(sharedPreference.edit()) {
|
|
||||||
putString(Constants.CUVETTE_SIZE, "10mmSt")
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
Toast.makeText(this, "Selected cuvette size: 2mm for single test", Toast.LENGTH_SHORT).show()
|
|
||||||
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()
|
||||||
}
|
}
|
||||||
@@ -143,12 +133,10 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
|
|||||||
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()
|
||||||
if(sharedPreference.getString(Constants.CUVETTE_SIZE, "10mm").toString() == "2mm"){
|
val maxTest = if(sharedPreference.getString(Constants.CUVETTE_SIZE, "10mm").toString() == "2mm"){
|
||||||
maxTest = Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE
|
Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE
|
||||||
}else if(sharedPreference.getString(Constants.CUVETTE_SIZE, "10mm").toString() == "10mm"){
|
}else{
|
||||||
maxTest = Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM
|
Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM
|
||||||
} else if(sharedPreference.getString(Constants.CUVETTE_SIZE, "10mmSt").toString() == "10mmSt"){
|
|
||||||
maxTest = Constants.MAXIMUM_TEST_ALLOWED_SINGLE_TEST
|
|
||||||
}
|
}
|
||||||
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()
|
||||||
@@ -224,27 +212,19 @@ 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(TEST_FOR_2MM)){
|
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(TEST_FOR_10MM)){
|
}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()
|
||||||
}
|
}
|
||||||
Toast.makeText(this, "Selected cuvette size: 10mm", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "Selected cuvette size: 10mm", Toast.LENGTH_SHORT).show()
|
||||||
}else if(serialNumber.contains(singleTest)){
|
|
||||||
with(sharedPreference.edit()) {
|
|
||||||
putString(Constants.CUVETTE_SIZE, "10mmSt")
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
Toast.makeText(this, "Selected cuvette size: 2mm for single test", Toast.LENGTH_SHORT).show()
|
|
||||||
binding.nameEditText.setText(serialNumber)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val kitTime = SimpleDateFormat(
|
val kitTime = SimpleDateFormat(
|
||||||
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
|
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
|
||||||
).format(Calendar.getInstance().time).toString()
|
).format(Calendar.getInstance().time).toString()
|
||||||
@@ -371,21 +351,16 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
private fun isSerialValid(s: String): Boolean {
|
private fun isSerialValid(s: String): Boolean {
|
||||||
if (s.contains(TEST_FOR_2MM)) {
|
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(TEST_FOR_10MM)){
|
}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 if(s.contains(singleTest)){
|
|
||||||
if(s.length != 27){
|
|
||||||
binding.nameEditText.error = "Invalid Kit Serial Number, correct example SMI/SC-ST/000000/000/000"
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -14,58 +14,41 @@
|
|||||||
package com.example.hpostesting.presentation.main_base
|
package com.example.hpostesting.presentation.main_base
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.DialogInterface
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
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.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.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.model.patient.HemoCubeTestData
|
|
||||||
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.example.hpostesting.presentation.trueheme_test.TrueHemeTestViewModel
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.firebase.ktx.Firebase
|
|
||||||
import com.google.firebase.storage.ktx.storage
|
|
||||||
import com.google.firebase.storage.ktx.storageMetadata
|
|
||||||
import `in`.sminnovations.hpostesting.R
|
import `in`.sminnovations.hpostesting.R
|
||||||
import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding
|
import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import java.io.File
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Date
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
|
|
||||||
private var isLanguageChanged = false
|
private var isLanguageChanged = false
|
||||||
|
|
||||||
class SlideshowFragment : Fragment() {
|
class SlideshowFragment : Fragment() {
|
||||||
private var selectedItem = "10mm"
|
private var selectedItem = "10mm"
|
||||||
private val values = arrayOf("10mm", "2mm", "10mmSt")
|
private val values = arrayOf("10mm", "2mm")
|
||||||
private lateinit var binding: FragmentSlideshowBinding
|
private lateinit var binding: FragmentSlideshowBinding
|
||||||
private val trueHemeTestViewModel: TrueHemeTestViewModel by activityViewModels()
|
|
||||||
private lateinit var sharedPreferences: SharedPreferences
|
private lateinit var sharedPreferences: SharedPreferences
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
@@ -78,9 +61,7 @@ class SlideshowFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
binding.btnDownload.setOnClickListener {
|
|
||||||
sendData()
|
|
||||||
}
|
|
||||||
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 {
|
||||||
@@ -102,10 +83,8 @@ class SlideshowFragment : Fragment() {
|
|||||||
val pos: Int
|
val pos: Int
|
||||||
if (selectedItem == "10mm") {
|
if (selectedItem == "10mm") {
|
||||||
pos = 0
|
pos = 0
|
||||||
} else if (selectedItem == "2mm"){
|
|
||||||
pos = 1
|
|
||||||
} else {
|
} else {
|
||||||
pos = 2
|
pos = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.spinnerCuvette.adapter = adapter
|
binding.spinnerCuvette.adapter = adapter
|
||||||
@@ -137,111 +116,6 @@ class SlideshowFragment : Fragment() {
|
|||||||
childFragmentManager.beginTransaction().replace(binding.container.id, PrefsFragment())
|
childFragmentManager.beginTransaction().replace(binding.container.id, PrefsFragment())
|
||||||
.commit()
|
.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendData() {
|
|
||||||
//This data will saved in firebase storage check in HPOS-Prod
|
|
||||||
val dialog = AlertDialog.Builder(requireContext())
|
|
||||||
.setTitle("Downloading")
|
|
||||||
.setMessage("Please wait...")
|
|
||||||
.setCancelable(false)
|
|
||||||
.create()
|
|
||||||
dialog.show()
|
|
||||||
downloadLocalDBData(dialog)
|
|
||||||
|
|
||||||
}
|
|
||||||
private fun downloadLocalDBData(dialog: DialogInterface) {
|
|
||||||
var csvDownloaded = false
|
|
||||||
|
|
||||||
trueHemeTestViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
|
|
||||||
if (!csvDownloaded) {
|
|
||||||
val downloadList = mutableListOf<HemoCubeTestData>()
|
|
||||||
|
|
||||||
userDataList.forEach { userData ->
|
|
||||||
Log.d("DownloadDebug", "userData: $userData, isCSVCreated: ${userData.isCSVCreated}")
|
|
||||||
downloadList.add(userData)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (downloadList.isNotEmpty()) {
|
|
||||||
// Set flag to prevent multiple executions due to observer
|
|
||||||
csvDownloaded = true
|
|
||||||
|
|
||||||
// Launch coroutine to handle CSV creation and upload
|
|
||||||
lifecycleScope.launch {
|
|
||||||
try {
|
|
||||||
// Call suspend function to create CSV and wait for result
|
|
||||||
val csvFile = trueHemeTestViewModel.createCSVNew(downloadList, requireContext())
|
|
||||||
|
|
||||||
if (csvFile != null && csvFile.exists() && csvFile.length() > 0) {
|
|
||||||
uploadToFirebaseStorage(csvFile)
|
|
||||||
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
"CSV file created successfully at ${csvFile.absolutePath}",
|
|
||||||
Toast.LENGTH_LONG
|
|
||||||
).show()
|
|
||||||
} else {
|
|
||||||
csvDownloaded = false // Reset flag if failed
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
"CSV file creation failed, please try again",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
csvDownloaded = false // Reset flag if exception
|
|
||||||
e.printStackTrace()
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
"Error creating CSV file: ${e.message}",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
} finally {
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Toast.makeText(requireContext(), "No data to download", Toast.LENGTH_SHORT).show()
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun uploadToFirebaseStorage(file: File) {
|
|
||||||
// Get Firebase Storage reference
|
|
||||||
val storage = Firebase.storage
|
|
||||||
val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
|
|
||||||
val storageRef = storage.reference.child("!!!csv_files/hemocube_data_$timestamp.csv")
|
|
||||||
|
|
||||||
// Create file metadata
|
|
||||||
val metadata = storageMetadata {
|
|
||||||
contentType = "text/csv"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upload file
|
|
||||||
val uploadTask = storageRef.putFile(Uri.fromFile(file), metadata)
|
|
||||||
|
|
||||||
uploadTask
|
|
||||||
.addOnSuccessListener {
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
"CSV file uploaded to Firebase successfully",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
.addOnFailureListener { exception ->
|
|
||||||
Log.e("FirebaseUpload", "Upload failed", exception)
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
"Failed to upload CSV to Firebase",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
.addOnProgressListener { taskSnapshot ->
|
|
||||||
val progress = (100.0 * taskSnapshot.bytesTransferred / taskSnapshot.totalByteCount)
|
|
||||||
Log.d("FirebaseUpload", "Upload is $progress% done")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrefsFragment : PreferenceFragmentCompat() {
|
class PrefsFragment : PreferenceFragmentCompat() {
|
||||||
@@ -329,11 +203,11 @@ class PrefsFragment : PreferenceFragmentCompat() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val shouldEnableCurrentServerVersion = FIREBASE_INTEGRATION && !MOLBIO_INTEGRATION
|
||||||
val appVersionPreference = Preference(requireContext()).apply {
|
val appVersionPreference = Preference(requireContext()).apply {
|
||||||
title = "App Version"
|
title = "App Version"
|
||||||
summary =
|
summary =
|
||||||
getAppVersion(requireContext()) + " [ " + getAppEnvironment(requireContext()) + "->" + currentServer + "]"
|
getAppVersion(requireContext()) + " [ " + getAppEnvironment(requireContext()) + "->" + if (shouldEnableCurrentServerVersion) currentServer else "molbio"+ "]"
|
||||||
icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_info_24)
|
icon = ContextCompat.getDrawable(requireContext(), R.drawable.baseline_info_24)
|
||||||
|
|
||||||
setOnPreferenceClickListener {
|
setOnPreferenceClickListener {
|
||||||
|
|||||||
@@ -32,20 +32,6 @@ import androidx.lifecycle.MutableLiveData
|
|||||||
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
|
||||||
import com.example.hpostesting.data.constant.Constants.negativeBoderLineMetricCheck2mmStMax
|
|
||||||
import com.example.hpostesting.data.constant.Constants.negativeBoderLineMetricCheck2mmStMin
|
|
||||||
import com.example.hpostesting.data.constant.Constants.negativeBorderlineMaxSt2mm
|
|
||||||
import com.example.hpostesting.data.constant.Constants.negativeBorderlineMinSt2mm
|
|
||||||
import com.example.hpostesting.data.constant.Constants.normalMaxSt2mm
|
|
||||||
import com.example.hpostesting.data.constant.Constants.normalMinSt2mm
|
|
||||||
import com.example.hpostesting.data.constant.Constants.positiveBoderLineMetricCheck2mmStMax
|
|
||||||
import com.example.hpostesting.data.constant.Constants.positiveBoderLineMetricCheck2mmStMin
|
|
||||||
import com.example.hpostesting.data.constant.Constants.positiveForSickleCellMaxSt2mm
|
|
||||||
import com.example.hpostesting.data.constant.Constants.positiveForSickleCellMinSt2mm
|
|
||||||
import com.example.hpostesting.data.constant.Constants.sickleCellDiseaseMaxSt2mm
|
|
||||||
import com.example.hpostesting.data.constant.Constants.sickleCellDiseaseMinSt2mm
|
|
||||||
import com.example.hpostesting.data.constant.Constants.sickleCellTraitMaxSt2mm
|
|
||||||
import com.example.hpostesting.data.constant.Constants.sickleCellTraitMinSt2mm
|
|
||||||
import com.example.hpostesting.data.constant.HemoCubeCommands
|
import com.example.hpostesting.data.constant.HemoCubeCommands
|
||||||
import com.example.hpostesting.data.constant.TestStatus
|
import com.example.hpostesting.data.constant.TestStatus
|
||||||
import com.example.hpostesting.data.model.TestState
|
import com.example.hpostesting.data.model.TestState
|
||||||
@@ -1210,20 +1196,6 @@ class TrueHemeTestFragment : Fragment() {
|
|||||||
binding.btnSamplestart.isEnabled = true
|
binding.btnSamplestart.isEnabled = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}else if(cuvetteSizeSP == "2mmSt"){
|
|
||||||
inRange2mmLed1 = led1Average in min2mmLed1..max2mmLed1
|
|
||||||
inRange2mmLed2 = led2Average in min2mmLed2..max2mmLed2
|
|
||||||
if(!inRange2mmLed1 || !inRange2mmLed2){
|
|
||||||
trueHemeTestViewModel.messages.postValue("Absorbance out-of-Range - Repeat test with adequate blood volume and Incubation time")
|
|
||||||
this.testStatusCode = TestStatus.BUFFER_PRINT_COMPLETED.code
|
|
||||||
binding.testing.visibility = View.GONE
|
|
||||||
binding.btnPlaceRefreshbuffer.visibility = View.GONE
|
|
||||||
binding.btnPlacebuffer.visibility = View.GONE
|
|
||||||
binding.btnSamplestart.visibility = View.VISIBLE
|
|
||||||
binding.btnSamplestart.isClickable = true
|
|
||||||
binding.btnSamplestart.isEnabled = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1506,25 +1478,6 @@ class TrueHemeTestFragment : Fragment() {
|
|||||||
return "Positive for Sickle Cell. Confirm with HPLC"
|
return "Positive for Sickle Cell. Confirm with HPLC"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if(cuvetteSizeSP == "2mmSt"){
|
|
||||||
if (deviceRatioClass == "Negative Borderline") {
|
|
||||||
if (borderlineMetric < negativeBoderLineMetricCheck2mmStMin){//1.34
|
|
||||||
return "Sickle Cell Trait"
|
|
||||||
}else if(borderlineMetric > negativeBoderLineMetricCheck2mmStMax){
|
|
||||||
return "Normal"
|
|
||||||
}else if(borderlineMetric > negativeBoderLineMetricCheck2mmStMin && borderlineMetric < negativeBoderLineMetricCheck2mmStMax){
|
|
||||||
return "Negative borderline. Confirm with HPLC"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") {
|
|
||||||
if (borderlineMetric < positiveBoderLineMetricCheck2mmStMin){//1.34
|
|
||||||
return "Sickle Cell Disease"
|
|
||||||
}else if(borderlineMetric > positiveBoderLineMetricCheck2mmStMax){
|
|
||||||
return "Sickle Cell Trait"
|
|
||||||
}else if(borderlineMetric > positiveBoderLineMetricCheck2mmStMin && borderlineMetric < positiveBoderLineMetricCheck2mmStMax){
|
|
||||||
return "Positive for Sickle Cell. Confirm with HPLC"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -1595,22 +1548,6 @@ class TrueHemeTestFragment : Fragment() {
|
|||||||
if (ratio in sickleCellDiseaseMin2mm..sickleCellDiseaseMax2mm){
|
if (ratio in sickleCellDiseaseMin2mm..sickleCellDiseaseMax2mm){
|
||||||
return "Sickle Cell Disease"
|
return "Sickle Cell Disease"
|
||||||
}
|
}
|
||||||
}else if(cuvetteSize == "2mmSt"){
|
|
||||||
if (ratio in normalMinSt2mm..normalMaxSt2mm) {
|
|
||||||
return "Normal"
|
|
||||||
}
|
|
||||||
if (ratio in negativeBorderlineMinSt2mm..negativeBorderlineMaxSt2mm){
|
|
||||||
return "Negative Borderline"
|
|
||||||
}
|
|
||||||
if (ratio in sickleCellTraitMinSt2mm..sickleCellTraitMaxSt2mm){
|
|
||||||
return "Sickle Cell Trait"
|
|
||||||
}
|
|
||||||
if (ratio in positiveForSickleCellMinSt2mm..positiveForSickleCellMaxSt2mm){//0.36
|
|
||||||
return "Positive for Sickle Cell. HPLC for Confirmation"
|
|
||||||
}
|
|
||||||
if (ratio in sickleCellDiseaseMinSt2mm..sickleCellDiseaseMaxSt2mm){
|
|
||||||
return "Sickle Cell Disease"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -53,15 +53,11 @@ 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
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.MultipartBody
|
import okhttp3.MultipartBody
|
||||||
import okhttp3.RequestBody.Companion.asRequestBody
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
import okhttp3.ResponseBody
|
import okhttp3.ResponseBody
|
||||||
import java.io.BufferedWriter
|
|
||||||
import java.io.File
|
|
||||||
import java.io.FileWriter
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
@@ -779,44 +775,7 @@ class TrueHemeTestViewModel @Inject constructor(
|
|||||||
|
|
||||||
return maxCapacity
|
return maxCapacity
|
||||||
}
|
}
|
||||||
suspend fun createCSVNew(data: List<HemoCubeTestData>, context: Context): File? {
|
|
||||||
return withContext(Dispatchers.IO) {
|
|
||||||
try {
|
|
||||||
val timestamp = System.currentTimeMillis()
|
|
||||||
val fileName = "hemocube_data_$timestamp.csv"
|
|
||||||
|
|
||||||
// Create file in app's external files directory
|
|
||||||
val appFile = File(context.getExternalFilesDir(null), fileName)
|
|
||||||
|
|
||||||
// Ensure this file is used by localFileDataSource
|
|
||||||
val exportSuccess = localFileDataSource.exportDataToCSV(appFile.absolutePath, data)
|
|
||||||
|
|
||||||
if (exportSuccess) {
|
|
||||||
// Update database records
|
|
||||||
data.forEach { item ->
|
|
||||||
hemoCubeDao.updateCSVFieldById(
|
|
||||||
item._id,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify file exists and has content
|
|
||||||
if (appFile.exists() && appFile.length() > 0) {
|
|
||||||
return@withContext appFile
|
|
||||||
} else {
|
|
||||||
Log.e("CSVCreation", "File creation verified failed: exists=${appFile.exists()}, size=${appFile.length()}")
|
|
||||||
return@withContext null
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.e("CSVCreation", "exportDataToCSV returned false")
|
|
||||||
return@withContext null
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e("CSVCreation", "Error creating CSV", e)
|
|
||||||
return@withContext null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fun createCSV(hemoCubeTestData: List<HemoCubeTestData>, appContext: Context) =
|
fun createCSV(hemoCubeTestData: List<HemoCubeTestData>, appContext: Context) =
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val fileName = "HPOS${getCurrentDate()}.csv"
|
val fileName = "HPOS${getCurrentDate()}.csv"
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -88,22 +88,12 @@
|
|||||||
app:layout_constraintBottom_toBottomOf="@id/spinnerCuvette"
|
app:layout_constraintBottom_toBottomOf="@id/spinnerCuvette"
|
||||||
app:layout_constraintStart_toEndOf="@id/spinnerCuvette"
|
app:layout_constraintStart_toEndOf="@id/spinnerCuvette"
|
||||||
app:layout_constraintTop_toTopOf="@id/spinnerCuvette" />
|
app:layout_constraintTop_toTopOf="@id/spinnerCuvette" />
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btn_download"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="24dp"
|
|
||||||
android:text="Send Data To Server"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
app:cornerRadius="16dp"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/spinnerCuvette"
|
|
||||||
/>
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/container"
|
android:id="@+id/container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/btn_download"
|
app:layout_constraintTop_toBottomOf="@+id/btn_add_size"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:layout_marginTop="10dp"/>
|
android:layout_marginTop="10dp"/>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user