diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 91b6fb9..c94e89b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -90,7 +90,7 @@ android:theme="@style/Theme.HPOS.NoActionBar" /> @@ -194,6 +196,7 @@ diff --git a/app/src/main/java/com/example/hpostesting/HPOSTestingApplication.kt b/app/src/main/java/com/example/hpostesting/HPOSTestingApplication.kt index 14cc695..2b02aed 100644 --- a/app/src/main/java/com/example/hpostesting/HPOSTestingApplication.kt +++ b/app/src/main/java/com/example/hpostesting/HPOSTestingApplication.kt @@ -15,7 +15,6 @@ package com.example.hpostesting import android.app.Application import com.example.hpostesting.firebase.FirebaseManager -import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestoreSettings import dagger.hilt.android.HiltAndroidApp import kotlinx.coroutines.CoroutineScope @@ -36,7 +35,7 @@ class HPOSTestingApplication : Application() { .setPersistenceEnabled(true) // Enable offline persistence if needed .build() - val firestore = firebaseManager.getCurrentFirestore() + val firestore = firebaseManager.getCurrentFirestoreF() firestore.firestoreSettings = firestoreSettings } } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/api/MolbioResultApi.kt b/app/src/main/java/com/example/hpostesting/data/api/MolbioResultApi.kt index d7ec4b6..d93fd17 100644 --- a/app/src/main/java/com/example/hpostesting/data/api/MolbioResultApi.kt +++ b/app/src/main/java/com/example/hpostesting/data/api/MolbioResultApi.kt @@ -43,10 +43,6 @@ interface MolbioResultApi { @Body checkUpdateRequest: CheckUpdateRequest, ): CheckUpdateResponse -// @POST("deviceService/device/getUpdate") -// suspend fun deviceUpdate( -// @Body deviceUpdateRequest: DeviceUpdateRequest, -// ): ResponseBody @POST("deviceService/device/getUpdate") suspend fun deviceUpdate( @Body deviceUpdateRequest: DeviceUpdateRequest, diff --git a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt index d56f9e7..11270f7 100644 --- a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt +++ b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt @@ -1628,177 +1628,4 @@ object Constants { const val bufferMaxLed1 = 23000.00 const val bufferMinLed2 = 17000.00 const val bufferMaxLed2 = 19000.00 - - - // val STATICID = listOf( -// "FACTORY", -// "ADMIN", -// "PQUSER", -// "QCUSER", -// "VIZ-1000-0004", -// "VIZ-1000-0005", -// "VIZ-1000-0006", -// "HC-V1-001", -// "HC-V1-002", -// "HC-V1-003", -// "HC-V1-004", -// "HC-V1-005", -// "HC-V1-006", -// "HC-V1-007", -// "HC-V1-008", -// "HC-V1-009", -// "HC-V1-010", -// "HC-V1-011", -// "HC-V1-012", -// "HC-V1-013", -// "HC-V1-014", -// "HC-V1-015", -// "HC-V1-016", -// "HC-V1-017", -// "HC-V1-018", -// "HC-V1-019", -// "HC-V1-020", -// "HCV-000-1015", -// "HCV-000-3002", -// "HCV-000-3003", -// "HCV-000-3004", -// "HCV-000-3005", -// "HCV-000-3006", -// "HCV-000-3007", -// "HCV-000-3008", -// "HCV-000-3009", -// "HCV-000-3010", -// "HCV-000-3011", -// "HCV-000-3012", -// "HCV-000-3013", -// "HCV-000-3014", -// "HCV-000-3015", -// "HCV-000-3016", -// "HCV-000-3017", -// "HCV-000-3018", -// "HCV-000-3019", -// "HCV-000-3020", -// "HCV-000-3021", -// "HCV-000-3022", -// "HCV-000-3023", -// "HCV-000-3024", -// "HCV-000-3025", -// "HCV-000-3026", -// "HCV-000-3027", -// "HCV-000-3028", -// "HCV-000-3029", -// "HCV-000-3030", -// "HPP1-0124-0001", -// "HPP1-0124-0002", -// "HPP1-0124-0003", -// "HPP1-0124-0004", -// "HPP1-0124-0005", -// "HPP1-0124-0006", -// "HPP1-0124-0007", -// "HPP1-0124-0008", -// "HPP1-0124-0009", -// "HPP1-0124-0010", -// "HPP1-0124-0011", -// "HPP1-0124-0012", -// "HPP1-0124-0013", -// "HPP1-0124-0014", -// "HPP1-0124-0015", -// "HPP1-0124-0016", -// "HPP1-0124-0017", -// "HPP1-0124-0018", -// "HPP1-0124-0019", -// "HPP1-0124-0020", -// "HPP1-0124-0021", -// "HPP1-0124-0022", -// "HPP1-0124-0023", -// "HPP1-0124-0024", -// "HPP1-0124-0025", -// "HPP1-0124-0026", -// "HPP1-0124-0027", -// "HPP1-0124-0028", -// "HPP1-0124-0029", -// "HPP1-0124-0030", -// "HPP1-0124-0031", -// "HPP1-0124-0032", -// "HPP1-0124-0033", -// "HPP1-0124-0034", -// "HPP1-0124-0035", -// "HPP1-0124-0036", -// "HPP1-0124-0037", -// "HPP1-0124-0038", -// "HPP1-0124-0039", -// "HPP1-0124-0040", -// "HPP1-0124-0041", -// "HPP1-0124-0042", -// "HPP1-0124-0043", -// "HPP1-0124-0044", -// "HPP1-0124-0045", -// "HPP1-0124-0046", -// "HPP1-0124-0047", -// "HPP1-0124-0048", -// "HPP1-0124-0049", -// "HPP1-0124-0050", -// "HCV-001-0001", -// "HCV-001-0002", -// "HCV-001-0003", -// "HCV-001-0004", -// "HCV-001-0005", -// "HCV-001-0006", -// "HCV-001-0007", -// "HCV-001-0008", -// "HCV-001-0009", -// "HCV-001-0010", -// "HCV-001-0011", -// "HCV-001-0012", -// "HCV-001-0013", -// "HCV-001-0014", -// "HCV-001-0015", -// "HCV-001-0016", -// "HCV-001-0017", -// "HCV-001-0018", -// "HCV-001-0019", -// "HCV-001-0020", -// "HCV-001-0021", -// "HCV-001-0022", -// "HCV-001-0023", -// "HCV-001-0024", -// "HCV-001-0025", -// "HCV-001-0026", -// "HCV-001-0027", -// "HCV-001-0028", -// "HCV-001-0029", -// "HCV-001-0030", -// "HCV-001-0031", -// "HCV-001-0032", -// "HCV-001-0033", -// "HCV-001-0034", -// "HCV-001-0003", -// "HCV-001-0035", -// "HCV-001-0036", -// "HCV-001-0037", -// "HCV-001-0038", -// "HCV-001-0039", -// "HCV-001-0040", -// "HCV-001-0041", -// "HCV-001-0042", -// "HCV-001-0043", -// "HCV-001-0044", -// "HCV-001-0045", -// "HCV-001-0046", -// "HCV-001-0047", -// "HCV-001-0048", -// "HCV-001-0049", -// "HCV-001-0050", -// "HCV-000-6001", -// "HCV-000-6002", -// "HCV-000-6003", -// "HCV-000-6004", -// "HCV-000-6005", -// "HCV-000-6006", -// "HCV-000-6007", -// "HCV-000-6008", -// "HCV-000-6009", -// "HCV-000-6010", -// ) -// } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt b/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt index a8ae59f..84282de 100644 --- a/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt +++ b/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt @@ -14,10 +14,6 @@ package com.example.hpostesting.data.repository import android.net.Uri -import android.os.Build -import android.util.Log -import androidx.annotation.RequiresApi -import com.example.hpostesting.util.Result import com.example.hpostesting.data.api.MolbioAuthApi import com.example.hpostesting.data.api.MolbioResultApi import com.example.hpostesting.data.model.PendingUploads @@ -41,6 +37,7 @@ import com.example.hpostesting.data.model.updates.CheckUpdateRequest import com.example.hpostesting.data.model.updates.CheckUpdateResponse import com.example.hpostesting.data.model.updates.DeviceUpdateRequest import com.example.hpostesting.firebase.FirebaseManager +import com.example.hpostesting.util.Result import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.ktx.Firebase @@ -51,7 +48,6 @@ import okhttp3.ResponseBody import java.io.File import java.net.ConnectException import java.net.SocketTimeoutException -import java.time.LocalTime import javax.inject.Inject import javax.inject.Named @@ -63,26 +59,12 @@ class DatabaseRepository @Inject constructor( ) : Repository { private val localdb: FirebaseFirestore - get() = firebaseManager.getCurrentFirestore() + get() = firebaseManager.getCurrentFirestoreF() private val localStg: FirebaseStorage - get() = firebaseManager.getCurrentStorage() + get() = firebaseManager.getCurrentStorageF() - -// // Example function to add data to Firestore , like the basic data as test data -// @RequiresApi(Build.VERSION_CODES.O) -// fun addtodb(data: String) { -// val date = LocalTime.now() -// localdb.collection("BasicData") -// .add(mapOf("data $date" to data)) -// .addOnSuccessListener { -// Log.d("UPLOAD", "Data uploaded successfully ${localdb.app.name}") -// } -// .addOnFailureListener { exception -> -// Log.d("UPLOAD", "Failed to upload data: ${exception.message} ${localdb.app.name}") -// } -// } private suspend fun safeApiCall(apiCall: suspend () -> T): Result { return try { val response = apiCall.invoke() diff --git a/app/src/main/java/com/example/hpostesting/data/repository/LocalFileRepository.kt b/app/src/main/java/com/example/hpostesting/data/repository/LocalFileRepository.kt index c2ef96a..9bbd686 100644 --- a/app/src/main/java/com/example/hpostesting/data/repository/LocalFileRepository.kt +++ b/app/src/main/java/com/example/hpostesting/data/repository/LocalFileRepository.kt @@ -13,13 +13,7 @@ package com.example.hpostesting.data.repository -import android.os.Environment import com.example.hpostesting.data.datasource.LocalFileDataSource -import com.example.hpostesting.data.model.patient.HemoCubeTestData -import com.opencsv.CSVWriter -import java.io.File -import java.io.FileWriter -import java.io.IOException class LocalFileRepository(private val localFileDataSource: LocalFileDataSource) { fun saveCsvToDisk(filepath: String, contents: ArrayList>) = diff --git a/app/src/main/java/com/example/hpostesting/domain/LogFileManagerImpl.kt b/app/src/main/java/com/example/hpostesting/domain/LogFileManagerImpl.kt index aa1fbc9..9f1e90f 100644 --- a/app/src/main/java/com/example/hpostesting/domain/LogFileManagerImpl.kt +++ b/app/src/main/java/com/example/hpostesting/domain/LogFileManagerImpl.kt @@ -44,7 +44,6 @@ class LogFileManagerImpl @Inject constructor(private val context: Context) : Log file } catch (e: IOException) { -// Log.e("LogFileManager", "Error creating log file: ${e.message}") null } } diff --git a/app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithMaxImpl.kt b/app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithMaxImpl.kt index e7e9c4f..b2dbf35 100644 --- a/app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithMaxImpl.kt +++ b/app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithMaxImpl.kt @@ -38,17 +38,21 @@ class ResultCalculationWithMaxImpl : TestRightResultCalculation { var wavelengthOfAbsorbanceTwo = 0.0 for (each in wavelengthToAbsorbance) { - if (each[0] >= startWavelengthOne && each[0] < endWavelengthOne) { - if (each[1] > maxAbsorbanceAtOne) { - maxAbsorbanceAtOne = each[1] - wavelengthOfAbsorbanceOne = each[0] + when { + each[0] >= startWavelengthOne && each[0] < endWavelengthOne -> { + if (each[1] > maxAbsorbanceAtOne) { + maxAbsorbanceAtOne = each[1] + wavelengthOfAbsorbanceOne = each[0] + } } } - if (each[0] >= startWavelengthTwo && each[0] < endWavelengthTwo) { -// maxAbsorbanceAtTwo = max(maxAbsorbanceAtTwo, each[1]) - if (each[1] > maxAbsorbanceAtTwo) { - maxAbsorbanceAtTwo = each[1] - wavelengthOfAbsorbanceTwo = each[0] + when { + each[0] >= startWavelengthTwo && each[0] < endWavelengthTwo -> { + // maxAbsorbanceAtTwo = max(maxAbsorbanceAtTwo, each[1]) + if (each[1] > maxAbsorbanceAtTwo) { + maxAbsorbanceAtTwo = each[1] + wavelengthOfAbsorbanceTwo = each[0] + } } } } @@ -70,26 +74,32 @@ class ResultCalculationWithMaxImpl : TestRightResultCalculation { val value = absorbanceAtWaveTwo / absorbanceAtWaveOne testRightCalculationData.ratioValue = value - if (value <= 0.29) { - testRightCalculationData.ratioMinRange = 0.0 - testRightCalculationData.ratioMaxRange = 0.29 - return TestRightResultType.NORMAL - } else if (value > 0.29 && value <= 0.32) { - testRightCalculationData.ratioMinRange = 0.29 - testRightCalculationData.ratioMaxRange = 0.32 - return TestRightResultType.NEGATIVEBORDERLINE - } else if (value > 0.32 && value <= 0.50) { - testRightCalculationData.ratioMinRange = 0.32 - testRightCalculationData.ratioMaxRange = 0.50 - return TestRightResultType.SICKLECELLTRAIT - } else if (value > 0.50 && value <= 0.55) { - testRightCalculationData.ratioMinRange = 0.50 - testRightCalculationData.ratioMaxRange = 0.55 - return TestRightResultType.POSITIVEBORDERLINE - }else if (value > 0.55) { - testRightCalculationData.ratioMinRange = 0.55 - testRightCalculationData.ratioMaxRange = 999.0 - return TestRightResultType.SICKLECELLDISEASE + when { + value <= 0.29 -> { + testRightCalculationData.ratioMinRange = 0.0 + testRightCalculationData.ratioMaxRange = 0.29 + return TestRightResultType.NORMAL + } + value > 0.29 && value <= 0.32 -> { + testRightCalculationData.ratioMinRange = 0.29 + testRightCalculationData.ratioMaxRange = 0.32 + return TestRightResultType.NEGATIVEBORDERLINE + } + value > 0.32 && value <= 0.50 -> { + testRightCalculationData.ratioMinRange = 0.32 + testRightCalculationData.ratioMaxRange = 0.50 + return TestRightResultType.SICKLECELLTRAIT + } + value > 0.50 && value <= 0.55 -> { + testRightCalculationData.ratioMinRange = 0.50 + testRightCalculationData.ratioMaxRange = 0.55 + return TestRightResultType.POSITIVEBORDERLINE + } + value > 0.55 -> { + testRightCalculationData.ratioMinRange = 0.55 + testRightCalculationData.ratioMaxRange = 999.0 + return TestRightResultType.SICKLECELLDISEASE + } } } diff --git a/app/src/main/java/com/example/hpostesting/domain/SaveRawData.kt b/app/src/main/java/com/example/hpostesting/domain/SaveRawData.kt index c0a4de2..39d8f9e 100644 --- a/app/src/main/java/com/example/hpostesting/domain/SaveRawData.kt +++ b/app/src/main/java/com/example/hpostesting/domain/SaveRawData.kt @@ -27,7 +27,6 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) { fun saveCsv(folderPath: String, fileName: String, matrix: ArrayList>) { // try { val fullPath = "$folderPath/$fileName" -// val writer = CSVWriter(FileWriter(fullPath)) sort(matrix) { one: ArrayList, two: ArrayList -> one[0].compareTo(two[0]) @@ -39,7 +38,6 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) { for (eachRow in matrix) { if (eachRow[0] >= Constants.MIN_WAVELENGTH_RANGE_TO_RECORD && eachRow[0] < Constants.MAX_WAVELENGTH_RANGE_TO_RECORD + 1) { -// val rowContent = arrayOf(String.format("%.3f", eachRow[0]), String.format("%.3f", eachRow[1])) val rowContent = arrayOf( String.format("%.10f", eachRow[0]), @@ -50,22 +48,9 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) { } localFileRepository.saveCsvToDisk(fullPath, content) -// writer.writeAll(content) // data is adding to csv -// writer.close() - -// } catch (e: Exception) { -// Log.e(TAG, e.toString()) -// } } fun saveLog(folderPath: String, fileName: String, calculationData: TestRightCalculationData) { -// val fileObj = File(folderPath, fileName) -// val writer = FileWriter(fileObj) - -// writer.append(getLogStringFromObj(calculationData)) -// writer.flush() -// writer.close() - val fullPath = folderPath + fileName localFileRepository.saveTextToDisk(fullPath, getLogStringFromObj(calculationData)) } @@ -113,13 +98,6 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) { calculationData: TestRightCalculationData, testDetails: UserData?, ) { -// val fileObj = File(folderPath, fileName) -// val writer = FileWriter(fileObj) - -// writer.append(getLogStringFromObjWithPatientData(calculationData, patientData)) -// writer.flush() -// writer.close() - val fullPath = folderPath + fileName localFileRepository.saveTextToDisk( fullPath, diff --git a/app/src/main/java/com/example/hpostesting/domain/SaveRawDataTest.kt b/app/src/main/java/com/example/hpostesting/domain/SaveRawDataTest.kt index 3cb2dc3..915ee10 100644 --- a/app/src/main/java/com/example/hpostesting/domain/SaveRawDataTest.kt +++ b/app/src/main/java/com/example/hpostesting/domain/SaveRawDataTest.kt @@ -24,7 +24,6 @@ class SaveRawDataTest(private val localFileRepository: LocalFileRepository) { // try { val fullPath = "$folderPath/$fileName" -// val writer = CSVWriter(FileWriter(fullPath)) val content = ArrayList>() // Header @@ -53,19 +52,6 @@ class SaveRawDataTest(private val localFileRepository: LocalFileRepository) { } fun saveLog(folderPath: String, fileName: String, isReference: Boolean, fullString: String) { -// val fileObj = File(folderPath, fileName) - -// Log.d(TAG, "$folderPath --- $fileName") -// val writer = FileWriter(fileObj) - -// if (isReference) -// writer.append("\nREFERENCE OUTPUT\n") -// else -// writer.append("\nSAMPLE OUTPUT\n") -// -// writer.append(fullString) -// writer.flush() -// writer.close() val filePath = folderPath + fileName var stringToWrite = "" diff --git a/app/src/main/java/com/example/hpostesting/domain/SickleFindResultCaluculationWithMaxImpl.kt b/app/src/main/java/com/example/hpostesting/domain/SickleFindResultCaluculationWithMaxImpl.kt index 7f1f117..c122e38 100644 --- a/app/src/main/java/com/example/hpostesting/domain/SickleFindResultCaluculationWithMaxImpl.kt +++ b/app/src/main/java/com/example/hpostesting/domain/SickleFindResultCaluculationWithMaxImpl.kt @@ -38,17 +38,21 @@ class SickleFindResultCaluculationWithMaxImpl : TestRightResultCalculation{ var wavelengthOfAbsorbanceTwo = 0.0 for (each in wavelengthToAbsorbance) { - if (each[0] >= startWavelengthOne && each[0] < endWavelengthOne) { - if (each[1] > maxAbsorbanceAtOne) { - maxAbsorbanceAtOne = each[1] - wavelengthOfAbsorbanceOne = each[0] + when { + each[0] >= startWavelengthOne && each[0] < endWavelengthOne -> { + if (each[1] > maxAbsorbanceAtOne) { + maxAbsorbanceAtOne = each[1] + wavelengthOfAbsorbanceOne = each[0] + } } } - if (each[0] >= startWavelengthTwo && each[0] < endWavelengthTwo) { -// maxAbsorbanceAtTwo = max(maxAbsorbanceAtTwo, each[1]) - if (each[1] > maxAbsorbanceAtTwo) { - maxAbsorbanceAtTwo = each[1] - wavelengthOfAbsorbanceTwo = each[0] + when { + each[0] >= startWavelengthTwo && each[0] < endWavelengthTwo -> { + // maxAbsorbanceAtTwo = max(maxAbsorbanceAtTwo, each[1]) + if (each[1] > maxAbsorbanceAtTwo) { + maxAbsorbanceAtTwo = each[1] + wavelengthOfAbsorbanceTwo = each[0] + } } } } @@ -70,18 +74,22 @@ class SickleFindResultCaluculationWithMaxImpl : TestRightResultCalculation{ val value = absorbanceAtWaveTwo / absorbanceAtWaveOne testRightCalculationData.ratioValue = value - if (value < 0.30 || value == 0.0) { - testRightCalculationData.ratioMinRange = 0.0 - testRightCalculationData.ratioMaxRange = 0.30 - return TestRightResultType.NORMAL - } else if (value >= 0.30 && value < 0.31) { - testRightCalculationData.ratioMinRange = 0.30 - testRightCalculationData.ratioMaxRange = 0.31 - return TestRightResultType.UNDEFINED - } else if (value >= 0.31) { - testRightCalculationData.ratioMinRange = 0.31 - testRightCalculationData.ratioMaxRange = 999.0 - return TestRightResultType.SICKLECELLDISEASE + when { + value < 0.30 || value == 0.0 -> { + testRightCalculationData.ratioMinRange = 0.0 + testRightCalculationData.ratioMaxRange = 0.30 + return TestRightResultType.NORMAL + } + value >= 0.30 && value < 0.31 -> { + testRightCalculationData.ratioMinRange = 0.30 + testRightCalculationData.ratioMaxRange = 0.31 + return TestRightResultType.UNDEFINED + } + value >= 0.31 -> { + testRightCalculationData.ratioMinRange = 0.31 + testRightCalculationData.ratioMaxRange = 999.0 + return TestRightResultType.SICKLECELLDISEASE + } } } diff --git a/app/src/main/java/com/example/hpostesting/encryption/Encryption.kt b/app/src/main/java/com/example/hpostesting/encryption/Encryption.kt index 107e3f1..313d6be 100644 --- a/app/src/main/java/com/example/hpostesting/encryption/Encryption.kt +++ b/app/src/main/java/com/example/hpostesting/encryption/Encryption.kt @@ -14,6 +14,7 @@ package com.example.hpostesting.encryption import android.util.Base64 +import java.security.SecureRandom import javax.crypto.Cipher import javax.crypto.SecretKeyFactory import javax.crypto.spec.IvParameterSpec @@ -21,7 +22,8 @@ import javax.crypto.spec.PBEKeySpec import javax.crypto.spec.SecretKeySpec object Encryption { - private const val AES_MODE = "AES/CBC/PKCS5Padding" + //private const val AES_MODE = "AES/CBC/PKCS5Padding" + private const val AES_MODE= "AES/GCM/NoPadding" private const val KEY_SPEC_ALGORITHM = "PBKDF2WithHmacSHA1" private const val SALT = "Bigtec" private const val ITERATION_COUNT = 10000 @@ -29,7 +31,8 @@ object Encryption { private val FIXED_IV = byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) fun encrypt(textToEncrypt: String, password: String): String { - val salt = SALT.toByteArray() + val salt = ByteArray(16) + SecureRandom().nextBytes(salt) val factory = SecretKeyFactory.getInstance(KEY_SPEC_ALGORITHM) val spec = PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH) val tmp = factory.generateSecret(spec) @@ -37,12 +40,12 @@ object Encryption { val cipher = Cipher.getInstance(AES_MODE) cipher.init(Cipher.ENCRYPT_MODE, key, IvParameterSpec(FIXED_IV)) val encryptedBytes = cipher.doFinal(textToEncrypt.toByteArray(Charsets.UTF_8)) - return Base64.encodeToString(encryptedBytes, Base64.NO_WRAP) + return Base64.encodeToString(salt + encryptedBytes, Base64.NO_WRAP) } fun decrypt(encryptedText: String, password: String): String { - val salt = SALT.toByteArray() - val encryptedBytes = Base64.decode(encryptedText, Base64.NO_WRAP) + val salt = encryptedText.substring(0, 24).toByteArray() + val encryptedBytes = Base64.decode(encryptedText.substring(24), Base64.NO_WRAP) val factory = SecretKeyFactory.getInstance(KEY_SPEC_ALGORITHM) val spec = PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH) val tmp = factory.generateSecret(spec) @@ -52,4 +55,29 @@ object Encryption { val decryptedBytes = cipher.doFinal(encryptedBytes) return String(decryptedBytes, Charsets.UTF_8) } +// fun encrypt(textToEncrypt: String, password: String): String { +// val salt = SALT.toByteArray() +// val factory = SecretKeyFactory.getInstance(KEY_SPEC_ALGORITHM) +// val spec = PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH) +// val tmp = factory.generateSecret(spec) +// val key = SecretKeySpec(tmp.encoded, "AES") +// val cipher = Cipher.getInstance(AES_MODE) +// cipher.init(Cipher.ENCRYPT_MODE, key, IvParameterSpec(FIXED_IV)) +// val encryptedBytes = cipher.doFinal(textToEncrypt.toByteArray(Charsets.UTF_8)) +// return Base64.encodeToString(encryptedBytes, Base64.NO_WRAP) +// } +// +// fun decrypt(encryptedText: String, password: String): String { +// val salt = SALT.toByteArray() +// val encryptedBytes = Base64.decode(encryptedText, Base64.NO_WRAP) +// val factory = SecretKeyFactory.getInstance(KEY_SPEC_ALGORITHM) +// val spec = PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH) +// val tmp = factory.generateSecret(spec) +// val key = SecretKeySpec(tmp.encoded, "AES") +// val cipher = Cipher.getInstance(AES_MODE) +// cipher.init(Cipher.DECRYPT_MODE, key, IvParameterSpec(FIXED_IV)) +// val decryptedBytes = cipher.doFinal(encryptedBytes) +// return String(decryptedBytes, Charsets.UTF_8) +// } + } diff --git a/app/src/main/java/com/example/hpostesting/firebase/FirebaseManage.kt b/app/src/main/java/com/example/hpostesting/firebase/FirebaseManage.kt index df06a1c..c479a62 100644 --- a/app/src/main/java/com/example/hpostesting/firebase/FirebaseManage.kt +++ b/app/src/main/java/com/example/hpostesting/firebase/FirebaseManage.kt @@ -18,9 +18,9 @@ import com.google.firebase.FirebaseApp import com.google.firebase.FirebaseOptions import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.storage.FirebaseStorage -import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import javax.inject.Inject @@ -30,8 +30,8 @@ class FirebaseManager @Inject constructor(private val context: Context) { private val sharedPreferences = context.getSharedPreferences("FirebaseConfigPrefs", Context.MODE_PRIVATE) - private var currentFirestore: FirebaseFirestore = FirebaseFirestore.getInstance() - private var currentStorage: FirebaseStorage = FirebaseStorage.getInstance() + var currentFirestore: FirebaseFirestore = FirebaseFirestore.getInstance() + var currentStorage: FirebaseStorage = FirebaseStorage.getInstance() var updateStatus = false private val defaultServers = listOf( @@ -44,8 +44,8 @@ class FirebaseManager @Inject constructor(private val context: Context) { switchServer(lastSelectedServer) } - fun getCurrentFirestore(): FirebaseFirestore = currentFirestore - fun getCurrentStorage(): FirebaseStorage = currentStorage + fun getCurrentFirestoreF(): FirebaseFirestore = currentFirestore + fun getCurrentStorageF(): FirebaseStorage = currentStorage fun switchServer(firebaseConfig: FirebaseConfig) { saveSelectedServer(firebaseConfig) @@ -120,9 +120,12 @@ fun restartApp(context: Context) { context.startActivity(intent) Process.killProcess(Process.myPid()) } -@OptIn(DelicateCoroutinesApi::class) -fun delayedRestart(context: Context) { - GlobalScope.launch(Dispatchers.Main) { +fun delayedRestart( + context: Context, + coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main), + dispatcher: CoroutineDispatcher = Dispatchers.Main +) { + coroutineScope.launch(dispatcher) { delay(5000L) restartApp(context) } diff --git a/app/src/main/java/com/example/hpostesting/presentation/KitScanActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/KitScanActivity.kt index c4f32c8..fcc4188 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/KitScanActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/KitScanActivity.kt @@ -19,23 +19,19 @@ import android.content.SharedPreferences import android.os.Bundle import android.text.Editable import android.util.Log -import android.view.View import android.widget.EditText import android.widget.Toast import androidx.appcompat.app.AppCompatActivity -import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.model.test.TestType import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.hb_test.HBTestActivity import com.example.hpostesting.presentation.hemocube.HemocubeActivity import com.example.hpostesting.presentation.testRight.TestRightActivity -import com.google.android.material.snackbar.Snackbar -import com.google.firebase.crashlytics.FirebaseCrashlytics import com.journeyapps.barcodescanner.ScanContract import com.journeyapps.barcodescanner.ScanIntentResult -import com.journeyapps.barcodescanner.ScanOptions import com.zebra.barcode.sdk.sms.ConfigurationUpdateEvent import com.zebra.scannercontrol.DCSSDKDefs import com.zebra.scannercontrol.DCSSDKDefs.DCSSDK_COMMAND_OPCODE @@ -50,10 +46,11 @@ import java.text.SimpleDateFormat import java.util.Calendar import java.util.Date import java.util.Locale -import kotlin.math.max class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate { private var fromWhere = "Home" + private val forD10 = "SMI/SC-2-D10/" + private val forD35 = "SMI/SC/" private val TAG = "KitScanActivity" private lateinit var binding: ActivityKitScanBinding @@ -75,14 +72,14 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate { } private fun processScannedData(contents: String) {//edited auto selection of cuvette size - if(contents.contains("SMI/SC/")){ + if(contents.contains(forD35)){ with(sharedPreference.edit()) { putString(Constants.CUVETTE_SIZE, "2mm") apply() } Toast.makeText(this, "Selected cuvette size: 2mm", Toast.LENGTH_SHORT).show() binding.nameEditText.setText(contents) - }else if(contents.contains("SMI/SC-2-D10/")){ + }else if(contents.contains(forD10)){ with(sharedPreference.edit()) { putString(Constants.CUVETTE_SIZE, "10mm") apply() @@ -101,33 +98,51 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate { } - override fun dcssdkEventScannerAppeared(dcsScannerInfo: DCSScannerInfo?) {} + override fun dcssdkEventScannerAppeared(dcsScannerInfo: DCSScannerInfo?) { + //nothing + } - override fun dcssdkEventScannerDisappeared(i: Int) {} + override fun dcssdkEventScannerDisappeared(i: Int) { + //nothing + } - override fun dcssdkEventCommunicationSessionEstablished(dcsScannerInfo: DCSScannerInfo?) {} + override fun dcssdkEventCommunicationSessionEstablished(dcsScannerInfo: DCSScannerInfo?) { + //nothing + } - override fun dcssdkEventCommunicationSessionTerminated(i: Int) {} + override fun dcssdkEventCommunicationSessionTerminated(i: Int) { + //nothing + } // override fun dcssdkEventBarcode(p0: ByteArray?, p1: Int, p2: Int) { -// TODO("Not yet implemented") // } - override fun dcssdkEventImage(bytes: ByteArray?, i: Int) {} + override fun dcssdkEventImage(bytes: ByteArray?, i: Int) { + //nothing + } - override fun dcssdkEventVideo(bytes: ByteArray?, i: Int) {} + override fun dcssdkEventVideo(bytes: ByteArray?, i: Int) { + //nothing + } - override fun dcssdkEventBinaryData(bytes: ByteArray?, i: Int) {} + override fun dcssdkEventBinaryData(bytes: ByteArray?, i: Int) { + //nothing + } - override fun dcssdkEventFirmwareUpdate(firmwareUpdateEvent: FirmwareUpdateEvent?) {} + override fun dcssdkEventFirmwareUpdate(firmwareUpdateEvent: FirmwareUpdateEvent?) { + //nothing + } override fun dcssdkEventAuxScannerAppeared( dcsScannerInfo: DCSScannerInfo?, dcsScannerInfo1: DCSScannerInfo?, ) { + //nothing } - override fun dcssdkEventConfigurationUpdate(configurationUpdateEvent: ConfigurationUpdateEvent?) {} + override fun dcssdkEventConfigurationUpdate(configurationUpdateEvent: ConfigurationUpdateEvent?) { + //nothing + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -210,13 +225,13 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate { binding.btnGo.setOnClickListener { val serialNumber = binding.nameEditText.text.toString().trim() if (serialNumber.isNotEmpty() && isSerialValid(serialNumber)) { - if(serialNumber.contains("SMI/SC/")){ + if(serialNumber.contains(forD35)){ with(sharedPreference.edit()) { putString(Constants.CUVETTE_SIZE, "2mm") apply() } Toast.makeText(this, "Selected cuvette size: 2mm", Toast.LENGTH_SHORT).show() - }else if(serialNumber.contains("SMI/SC-2-D10/")){ + }else if(serialNumber.contains(forD10)){ with(sharedPreference.edit()) { putString(Constants.CUVETTE_SIZE, "10mm") apply() @@ -289,11 +304,11 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate { //deciding what kind of notifications we want to receive. Explained more in the function //first we use bitmapping to set these values into the notifications_mask. - var notifications_mask = 0 + var notificationsMask = 0 // We would like to subscribe to all barcode events - notifications_mask = - notifications_mask or DCSSDKDefs.DCSSDK_EVENT.DCSSDK_EVENT_BARCODE.value - sdkHandler!!.dcssdkSubsribeForEvents(notifications_mask) + notificationsMask = + notificationsMask or DCSSDKDefs.DCSSDK_EVENT.DCSSDK_EVENT_BARCODE.value + sdkHandler!!.dcssdkSubsribeForEvents(notificationsMask) mScannerInfoList.addAll(sdkHandler!!.dcssdkGetAvailableScannersList()) Log.e("scannersize", sdkHandler!!.dcssdkGetAvailableScannersList().size.toString()) if (mScannerInfoList.isNotEmpty()) { @@ -335,7 +350,7 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate { val result = String(barcodeData!!) Log.d("BARCODE", result) runOnUiThread { - val editableResult: Editable = Editable.Factory.getInstance().newEditable(result) + Editable.Factory.getInstance().newEditable(result) processScannedData(result) // binding.nameEditText.text = editableResult } @@ -349,12 +364,12 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate { // } private fun isSerialValid(s: String): Boolean { - if (s.contains("SMI/SC/")) { + if (s.contains(forD35)) { if(s.length != 17){ binding.nameEditText.error = "Invalid Kit Serial Number, correct example SMI/SC/000/00/000" return false } - }else if(s.contains("SMI/SC-2-D10/")){ + }else if(s.contains(forD10)){ if(s.length != 27){ binding.nameEditText.error = "Invalid Kit Serial Number, correct example SMI/SC-2-D10/000000/000/000" return false @@ -373,56 +388,50 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate { }else{ DataHolder.deviceType.observe(this) { deviceType -> when (deviceType) { - Constants.DEVICE_TYPE_HEMOCUBE -> { + Constants.DEVICE_TYPE_HEMOCUBE ,Constants.DEVICE_TYPE_TRUEHEME -> { val i = Intent(applicationContext, HemocubeActivity::class.java) startActivity(i) } - Constants.DEVICE_TYPE_TEST_RIGHT -> { val i = Intent(applicationContext, TestRightActivity::class.java) startActivity(i) } - - Constants.DEVICE_TYPE_TRUEHEME -> { - val i = Intent(applicationContext, HemocubeActivity::class.java) - startActivity(i) - } } } } } } - private fun startScanningNow() { - val options = ScanOptions() - options.setDesiredBarcodeFormats(ScanOptions.QR_CODE) - options.setPrompt("Scan a barcode") - options.setCameraId(0) // Use a specific camera of the device - - options.setBeepEnabled(true) - options.setBarcodeImageEnabled(true) - - options.setPrompt("Start Scanning") - options.setOrientationLocked(false) -// options.setTimeout(10000) // in ms - - barcodeLauncher.launch(options) - } - - private fun checkDataNotNull(): Boolean { - return if (DataHolder.selectedTest?._id == null) { - Toast.makeText( - applicationContext, R.string.select_patient, Toast.LENGTH_SHORT - ).show() - - val i = Intent(applicationContext, DashboardActivity::class.java) - startActivity(i) - - false - } else { - true - } - } +// private fun startScanningNow() { +// val options = ScanOptions() +// options.setDesiredBarcodeFormats(ScanOptions.QR_CODE) +// options.setPrompt("Scan a barcode") +// options.setCameraId(0) // Use a specific camera of the device +// +// options.setBeepEnabled(true) +// options.setBarcodeImageEnabled(true) +// +// options.setPrompt("Start Scanning") +// options.setOrientationLocked(false) +//// options.setTimeout(10000) // in ms +// +// barcodeLauncher.launch(options) +// } +// +// private fun checkDataNotNull(): Boolean { +// return if (DataHolder.selectedTest?._id == null) { +// Toast.makeText( +// applicationContext, R.string.select_patient, Toast.LENGTH_SHORT +// ).show() +// +// val i = Intent(applicationContext, DashboardActivity::class.java) +// startActivity(i) +// +// false +// } else { +// true +// } +// } private fun timeDifference(createdAt: String): Long { val currentTime = Calendar.getInstance().time val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) diff --git a/app/src/main/java/com/example/hpostesting/presentation/MainActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/MainActivity.kt index dd4d298..cc6d7eb 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/MainActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/MainActivity.kt @@ -122,11 +122,17 @@ class MainActivity : AppCompatActivity() { // finish() // } } - + private fun changeUI(){ + binding.cvItem1.visibility = View.VISIBLE + binding.cvItem3.visibility = View.VISIBLE + binding.cvItem2.visibility = View.GONE + binding.cvItem4.visibility = View.GONE + } private fun checkAndUpdateUsbConnection() { val availableDrivers = UsbSerialProber.getDefaultProber() .findAllDrivers(getSystemService(Context.USB_SERVICE) as UsbManager) + .toList() val deviceType = when { availableDrivers.isNotEmpty() -> { @@ -137,51 +143,18 @@ class MainActivity : AppCompatActivity() { Toast.LENGTH_SHORT ).show() when { - device.productId == Constants.HOMO_CUBE_ID && device.vendorId == Constants.VENDOR_ID -> { - binding.cvItem1.visibility = View.VISIBLE - binding.cvItem3.visibility = View.VISIBLE - binding.cvItem2.visibility = View.GONE - binding.cvItem4.visibility = View.GONE + (device.productId == Constants.HOMO_CUBE_ID && device.vendorId == Constants.VENDOR_ID) || (device.productId == Constants.HEMO_CUBE_V2_PRODUCT_ID && device.vendorId == Constants.HEMO_CUBE_V2_VENDOR_ID) -> { + changeUI() DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HEMOCUBE) Constants.DEVICE_TYPE_HEMOCUBE } - device.productId == Constants.HEMO_CUBE_V2_PRODUCT_ID && device.vendorId == Constants.HEMO_CUBE_V2_VENDOR_ID -> { - binding.cvItem1.visibility = View.VISIBLE - binding.cvItem3.visibility = View.VISIBLE - binding.cvItem2.visibility = View.GONE - binding.cvItem4.visibility = View.GONE - DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HEMOCUBE) - Constants.DEVICE_TYPE_HEMOCUBE - } - - device.productId == 24577 && device.vendorId == 1027 -> { - binding.cvItem1.visibility = View.VISIBLE - binding.cvItem3.visibility = View.VISIBLE - binding.cvItem2.visibility = View.GONE - binding.cvItem4.visibility = View.GONE + (device.productId == 24577 && device.vendorId == 1027) || (device.productId == 8963 && device.vendorId == 1659) || (device.productId == 4614 && device.vendorId == 7111) -> { + changeUI() DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_TRUEHEME) Constants.DEVICE_TYPE_TRUEHEME } - device.productId == 8963 && device.vendorId == 1659 -> { - binding.cvItem1.visibility = View.VISIBLE - binding.cvItem3.visibility = View.VISIBLE - binding.cvItem2.visibility = View.GONE - binding.cvItem4.visibility = View.GONE - DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HEMOCUBE) - Constants.DEVICE_TYPE_HEMOCUBE - } - - device.productId == 4614 && device.vendorId == 7111 -> { - binding.cvItem1.visibility = View.VISIBLE - binding.cvItem3.visibility = View.VISIBLE - binding.cvItem2.visibility = View.GONE - binding.cvItem4.visibility = View.GONE - DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HEMOCUBE) - Constants.DEVICE_TYPE_HEMOCUBE - } - device.productId == Constants.DEVICE_PRODUCT_ID && device.vendorId == Constants.DEVICE_VENDOR_ID -> { Log.d( TAG, diff --git a/app/src/main/java/com/example/hpostesting/presentation/SplashActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/SplashActivity.kt index 4a5bb1a..84e37bd 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/SplashActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/SplashActivity.kt @@ -93,7 +93,7 @@ class SplashActivity : AppCompatActivity() { handlePermissionsResult(true) } else { val requestPermissionLauncher = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { _ -> if (Environment.isExternalStorageManager()) { handlePermissionsResult(true) } else { diff --git a/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt b/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt index 987deea..e9cab5a 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/adapter/OfflineUserListAdapter.kt @@ -15,18 +15,17 @@ package com.example.hpostesting.presentation.adapter import android.annotation.SuppressLint import android.content.Context -import android.content.res.Resources -import android.provider.ContactsContract.Data import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast +import androidx.annotation.StringRes import androidx.navigation.findNavController import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.UserData import `in`.sminnovations.hpostesting.R @@ -72,78 +71,97 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int,p @SuppressLint("SetTextI18n") override fun onBindViewHolder(holder: OfflineUserListViewHolder, position: Int) { val userList = differ.currentList[position] + updateHolderBinding(holder, userList) + } + private fun formatTime(incubationTime: String): String { + val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) + val incubationTimeDate = formatter.parse(incubationTime)!! + val timeFormatter = SimpleDateFormat("HH:mm:ss", Locale.getDefault()) + return "Time: ${isBetween15And30Minutes(incubationTime)} \n Started at: ${timeFormatter.format(incubationTimeDate)}" + } + private fun getSampleIdText(userList: HemoCubeTestData): String { + return "Sample ID: ${userList._id}" + } + + private fun getBloodGroupText(userList: HemoCubeTestData): String { + return "Blood group: ${userList.bloodGroup}" + } + + private fun getTestStatusText(userList: HemoCubeTestData): String { + return if (userList.testStatus!!) { + view.context.getString(R.string.test_concluded) + } else { + view.context.getString(R.string.test_pending) + } + } + private fun updateHolderBinding(holder: OfflineUserListViewHolder, userList: HemoCubeTestData) { holder.binding.apply { - userID.text = "Sample ID: ${userList._id}" - bloodGroup.text = "Blood group: ${userList.bloodGroup}" - time.text = "Time: ${isBetween15And30Minutes(userList.incubationTime)} \n Started at: ${ - SimpleDateFormat("HH:mm:ss").format( - SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() - ).parse(userList.incubationTime)!! - ) - }" - - if (userList.testStatus!!) { - teststatus.text = view.context.getString(R.string.test_concluded) - - } else { - teststatus.text = view.context.getString(R.string.test_pending) - } - if(fromWhere == "Home") { - userCard.setOnClickListener { - if (false) { - Toast.makeText( - view.context, - view.context.getString(R.string.low_battery_warning), - Toast.LENGTH_SHORT - ).show() - return@setOnClickListener - } - if (userList.testStatus != null) { - if (userList.testStatus!!) { - Toast.makeText( - view.context, - view.context.getString(R.string.test_already_conducted), - Toast.LENGTH_SHORT - ).show() - } else { - if (userList.incubationTime != "") { - if (isBetween15And30Minutes(userList.incubationTime) < Constants.INCUBATION_TIME_MIN) { - Toast.makeText( - view.context, - view.context.getString(R.string.incubation_not_completed), - Toast.LENGTH_SHORT - ).show() - } else if (isBetween15And30Minutes(userList.incubationTime) > Constants.INCUBATION_TIME_MAX) { - Toast.makeText( - view.context, - view.context.getString(R.string.incubation_crossed_30_minutes), - Toast.LENGTH_SHORT - ).show() - } else { - DataHolder.selectedTest = UserData( - sampleid = userList.sampleid, - _id = userList._id, - bloodGroup = userList.bloodGroup, - incubationTime = userList.incubationTime - ) - view.findNavController() - .navigate(R.id.action_nav_home_to_mainActivity) - } - } else { - Toast.makeText( - view.context, - view.context.getString(R.string.incubation_not_started), - Toast.LENGTH_SHORT - ).show() - } - } - } - } + updateBasicUserInfo(this, userList) + if (fromWhere == "Home") { + setupUserCardClickListener(userCard, userList) } } } + private fun updateBasicUserInfo(binding: OfflineUserListViewBinding, userList: HemoCubeTestData) { + binding.apply { + userID.text = getSampleIdText(userList) + bloodGroup.text = getBloodGroupText(userList) + time.text = formatTime(userList.incubationTime) + teststatus.text = getTestStatusText(userList) + } + } + + private fun setupUserCardClickListener(userCard: View, userList: HemoCubeTestData) { + userCard.setOnClickListener { + when { + isLowBattery(userList.batteryLevel) -> showToast(R.string.low_battery_warning) + isTestAlreadyCompleted(userList.testStatus) -> showToast(R.string.test_already_conducted) + else -> handleIncubationCheck(userList) + } + } + } + + private fun isLowBattery(batteryLevel: String): Boolean = + batteryLevel < "20" + + private fun isTestAlreadyCompleted(testStatus: Boolean?): Boolean = + testStatus == true + + private fun handleIncubationCheck(userList: HemoCubeTestData) { + if (userList.incubationTime.isEmpty()) { + showToast(R.string.incubation_not_started) + return + } + + val incubationMinutes = isBetween15And30Minutes(userList.incubationTime) + when { + incubationMinutes < Constants.INCUBATION_TIME_MIN -> + showToast(R.string.incubation_not_completed) + incubationMinutes > Constants.INCUBATION_TIME_MAX -> + showToast(R.string.incubation_crossed_30_minutes) + else -> navigateToMainActivity(userList) + } + } + + private fun showToast(@StringRes messageResId: Int) { + Toast.makeText( + view.context, + view.context.getString(messageResId), + Toast.LENGTH_SHORT + ).show() + } + + private fun navigateToMainActivity(userList: HemoCubeTestData) { + DataHolder.selectedTest = UserData( + sampleid = userList.sampleid, + _id = userList._id, + bloodGroup = userList.bloodGroup, + incubationTime = userList.incubationTime + ) + view.findNavController().navigate(R.id.action_nav_home_to_mainActivity) + } + private fun isBetween15And30Minutes(createdAt: String): Long { val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) val createdAtDate: Date = formatter.parse(createdAt)!! @@ -155,19 +173,19 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int,p return diffMillis / (60 * 1000) } - private fun showWarningToast(resId: Int) { - val contextToUse = view.context ?: return - - val message = try { - contextToUse.getString(resId) - } catch (e: Resources.NotFoundException) { - "Resource not found for ID: $resId" - } - - Toast.makeText( - contextToUse, - message, - Toast.LENGTH_SHORT - ).show() - } +// private fun showWarningToast(resId: Int) { +// val contextToUse = view.context ?: return +// +// val message = try { +// contextToUse.getString(resId) +// } catch (e: Resources.NotFoundException) { +// "Resource not found for ID: $resId" +// } +// +// Toast.makeText( +// contextToUse, +// message, +// Toast.LENGTH_SHORT +// ).show() +// } } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt b/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt index 334d777..3e94d8b 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt @@ -33,6 +33,7 @@ import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.firebase.ui.firestore.FirestoreRecyclerAdapter import com.firebase.ui.firestore.FirestoreRecyclerOptions import com.google.firebase.firestore.FirebaseFirestore +import com.google.firebase.firestore.QuerySnapshot import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.UserItemViewBinding import java.text.SimpleDateFormat @@ -61,212 +62,274 @@ class UserListAdapter( @SuppressLint("SetTextI18n") override fun onBindViewHolder(holder: OrderItemViewHolder, position: Int, model: UserData) { holder.binding.apply { + setupUserInfo(this, model) + setupBloodGroupButton(this, model) + setupTestStatusAndImage(this, model) + setupStartIncubationButton(this) + setupUserCardClickListener(this, model) + } + } + + private fun setupUserInfo(binding: UserItemViewBinding, model: UserData) { + binding.apply { userName.text = "Name: ${model.name}" - userId.text = "User ID:${model._id}" - if (model.incubationTime == "") { + if (model.incubationTime.isEmpty()) { + userId.text = "User ID:${model._id}" btnBlood.visibility = View.VISIBLE } else { - userId.text = - "User ID:${model._id} \n Time: ${isBetween15And30Minutes(model.incubationTime)} \n Started at: ${ - SimpleDateFormat("HH:mm:ss").format( - SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() - ).parse(model.incubationTime)!! - ) - }" + val timeFormatted = SimpleDateFormat("HH:mm:ss").format( + SimpleDateFormat(context.resources.getString(R.string.DateTimeFormat), Locale.getDefault()) + .parse(model.incubationTime)!! + ) + userId.text = "User ID:${model._id} \n Time: ${isBetween15And30Minutes(model.incubationTime)} \n Started at: $timeFormatted" btnBlood.visibility = View.GONE } + } + } - + private fun setupTestStatusAndImage(binding: UserItemViewBinding, model: UserData) { + binding.apply { Glide.with(view).load(model.userImageURL).into(userImage) - if (model.testStatus!!) { - teststatus.text = view.context.getString(R.string.test_concluded) - + teststatus.text = if (model.testStatus!!) { + view.context.getString(R.string.test_concluded) } else { - teststatus.text = view.context.getString(R.string.test_pending) + view.context.getString(R.string.test_pending) } + } + } - holder.binding.btnBlood.setOnClickListener { - val view: View? = requireActivity.currentFocus + private fun setupBloodGroupButton(binding: UserItemViewBinding, model: UserData) { + binding.btnBlood.setOnClickListener { + hideKeyboard() + showBloodGroupDialog(model, binding) + } + } - // on below line checking if view is not null. - if (view != null) { - // on below line we are creating a variable - // for input manager and initializing it. - val inputMethodManager = - context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager + private fun hideKeyboard() { + val view: View? = requireActivity.currentFocus + view?.let { + val inputMethodManager = + context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager + inputMethodManager.hideSoftInputFromWindow(it.windowToken, 0) + } + } - // on below line hiding our keyboard. - inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0) - } - val inflater = LayoutInflater.from(context) - val dialogView = inflater.inflate(R.layout.dialog_custom, null) + private fun showBloodGroupDialog(model: UserData, binding: UserItemViewBinding) { + val dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_custom, null) + val builder = AlertDialog.Builder(context) + .setView(dialogView) + .setTitle(R.string.blood_group) - val builder = AlertDialog.Builder(context) - .setView(dialogView) - .setTitle(R.string.blood_group) + val etBloodGroup = dialogView.findViewById(R.id.et_blood_group) + setupDialogButtons(builder, etBloodGroup, model, binding) + } - val etBloodGroup = - dialogView.findViewById(R.id.et_blood_group) + private fun setupDialogButtons( + builder: AlertDialog.Builder, + etBloodGroup: AutoCompleteTextView, + model: UserData, + binding: UserItemViewBinding + ) { + builder.setPositiveButton(R.string.ok) { _, _ -> + handleBloodGroupSelection(etBloodGroup, model, binding) + } - builder.setPositiveButton(R.string.ok) { dialog, which -> - val bloodGroup = etBloodGroup.text.toString() - if (bloodGroup.equals("Select Blood Group") || bloodGroup.equals("ರಕ್ತ ಗುಂಪು ಆಯ್ಕೆಮಾಡಿ") || bloodGroup.isNullOrBlank()) { - if (view != null) { - etBloodGroup.error = view.context.getString(R.string.blood_group_error) - } - if (view != null) { - Toast.makeText( - context, - view.context.getString(R.string.blood_group_toast), - Toast.LENGTH_SHORT - ).show() - } - } else { - // Check if hemoCubeViewModel and testDetails are not null - val db: FirebaseFirestore = FirebaseFirestore.getInstance() + builder.setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() } + builder.create().show() + } - db.collection("patientData") - .whereEqualTo("_id", model._id) - .get() - .addOnSuccessListener { userdata -> - try { - val document = userdata.documents[0] - db.collection("patientData") - .document(document.id) - .update( - "bloodGroup", bloodGroup, - "incubationTime", SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() - ).format(Calendar.getInstance().time).toString() - ) - .addOnSuccessListener { - if (view != null) { - Toast.makeText( - view.context, - context?.getString(R.string.blood_group_updated_successfully), - Toast.LENGTH_SHORT - ).show() - } - btnBlood.visibility = View.GONE - } - .addOnFailureListener { e -> - if (view != null) { - Toast.makeText( - view.context, - context?.getString(R.string.failed_to_update_blood_group), - Toast.LENGTH_SHORT - ).show() - } - } - } catch (e: IndexOutOfBoundsException) { - // Handle the case where no documents are found for the specified ID - if (view != null) { - Toast.makeText( - view.context, - context?.getString(R.string.no_user_data_found), - Toast.LENGTH_SHORT - ).show() - } - } + private fun handleBloodGroupSelection( + etBloodGroup: AutoCompleteTextView, + model: UserData, + binding: UserItemViewBinding + ) { + val bloodGroup = etBloodGroup.text.toString() + if (isInvalidBloodGroup(bloodGroup)) { + showBloodGroupError(etBloodGroup) + return + } + updateBloodGroupInFirestore(bloodGroup, model, binding) + } - } - .addOnFailureListener { e -> - Toast.makeText( - context, - "Error fetching user data: ${e.message}", - Toast.LENGTH_SHORT - ).show() - } - } - // Handle the selected blood group here - } + private fun isInvalidBloodGroup(bloodGroup: String): Boolean { + return bloodGroup == "Select Blood Group" || + bloodGroup == "ರಕ್ತ ಗುಂಪು ಆಯ್ಕೆಮಾಡಿ" || + bloodGroup.isBlank() + } - builder.setNegativeButton(R.string.cancel) { dialog, which -> - dialog.dismiss() - } + private fun showBloodGroupError(etBloodGroup: AutoCompleteTextView) { + etBloodGroup.error = view.context.getString(R.string.blood_group_error) + Toast.makeText( + context, + view.context.getString(R.string.blood_group_toast), + Toast.LENGTH_SHORT + ).show() + } - val alertDialog = builder.create() - alertDialog.show() + private fun updateBloodGroupInFirestore( + bloodGroup: String, + model: UserData, + binding: UserItemViewBinding + ) { + val db = FirebaseFirestore.getInstance() + db.collection("patientData") + .whereEqualTo("_id", model._id) + .get() + .addOnSuccessListener { userdata -> + handleFirestoreUpdate(userdata, bloodGroup, binding) } + .addOnFailureListener { e -> + Toast.makeText( + context, + "Error fetching user data: ${e.message}", + Toast.LENGTH_SHORT + ).show() + } + } - btnStartIncubation.setOnClickListener { -// it.visibility = View.GONE -// Firebase.firestore.collection("patientData").whereEqualTo("_id", model._id).get() -// .addOnSuccessListener { data -> -// if (data.documents.isNotEmpty()) { -// data.documents.forEach { userData -> -// Firebase.firestore.collection("patientData").document(userData.id) -// .update( -// "incubationTime", SimpleDateFormat( -// "yyyy-MM-dd HH:mm:ss", Locale.getDefault() -// ).format(Calendar.getInstance().time).toString() -// ).addOnSuccessListener { -// Toast.makeText( -// view.context, "Incubation started", Toast.LENGTH_SHORT -// ).show() -// startListening() -// } -// } + private fun handleFirestoreUpdate( + userdata: QuerySnapshot, + bloodGroup: String, + binding: UserItemViewBinding + ) { + try { + val document = userdata.documents[0] + updateDocument(document.id, bloodGroup, binding) + } catch (e: IndexOutOfBoundsException) { + Toast.makeText( + view.context, + context.getString(R.string.no_user_data_found), + Toast.LENGTH_SHORT + ).show() + } + } + + private fun updateDocument( + documentId: String, + bloodGroup: String, + binding: UserItemViewBinding + ) { + FirebaseFirestore.getInstance().collection("patientData") + .document(documentId) + .update( + "bloodGroup", bloodGroup, + "incubationTime", getCurrentTimeFormatted() + ) + .addOnSuccessListener { + Toast.makeText( + view.context, + context.getString(R.string.blood_group_updated_successfully), + Toast.LENGTH_SHORT + ).show() + binding.btnBlood.visibility = View.GONE + } + .addOnFailureListener { + Toast.makeText( + view.context, + context.getString(R.string.failed_to_update_blood_group), + Toast.LENGTH_SHORT + ).show() + } + } + + private fun getCurrentTimeFormatted(): String { + return SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) + .format(Calendar.getInstance().time) + } + + private fun setupStartIncubationButton(binding: UserItemViewBinding) { + // Commented code preserved as per requirement + binding.btnStartIncubation.setOnClickListener { +// it.visibility = View.GONE +// Firebase.firestore.collection("patientData").whereEqualTo("_id", model._id).get() +// .addOnSuccessListener { data -> +// if (data.documents.isNotEmpty()) { +// data.documents.forEach { userData -> +// Firebase.firestore.collection("patientData").document(userData.id) +// .update( +// "incubationTime", SimpleDateFormat( +// "yyyy-MM-dd HH:mm:ss", Locale.getDefault() +// ).format(Calendar.getInstance().time).toString() +// ).addOnSuccessListener { +// Toast.makeText( +// view.context, "Incubation started", Toast.LENGTH_SHORT +// ).show() +// startListening() +// } // } // } - } - userCard.setOnClickListener { - if (false) { - Toast.makeText( - view.context, - context?.getString(R.string.low_battery_warning), - Toast.LENGTH_SHORT - ).show() - return@setOnClickListener - } - if (model.testStatus != null) { - if (model.testStatus!!) { - Toast.makeText( - view.context, - context?.getString(R.string.test_already_conducted), - Toast.LENGTH_SHORT - ).show() - } else { - if (model.incubationTime != "") { - if (isBetween15And30Minutes(model.incubationTime) < -15000) { - Toast.makeText( - view.context, - context?.getString(R.string.incubation_not_completed), - Toast.LENGTH_SHORT - ).show() - } else if (isBetween15And30Minutes(model.incubationTime) > 300000) { - Toast.makeText( - view.context, - context?.getString(R.string.incubation_crossed_30_minutes), - Toast.LENGTH_SHORT - ).show() - } else { - DataHolder.selectedTest = model - view.findNavController() - .navigate(R.id.action_nav_home_to_mainActivity) - } - } else { - Toast.makeText( - view.context, - context?.getString(R.string.incubation_not_started), - Toast.LENGTH_SHORT - ).show() - } - } +// } + } + } + + private fun setupUserCardClickListener(binding: UserItemViewBinding, model: UserData) { + binding.userCard.setOnClickListener { + model.testStatus?.let { testStatus -> + if (testStatus) { + showTestAlreadyConductedMessage() + } else { + handleIncubationTimeCheck(model) } } } } + private fun showTestAlreadyConductedMessage() { + Toast.makeText( + view.context, + context.getString(R.string.test_already_conducted), + Toast.LENGTH_SHORT + ).show() + } + + private fun handleIncubationTimeCheck(model: UserData) { + if (model.incubationTime.isEmpty()) { + showIncubationNotStartedMessage() + return + } + + val incubationTime = isBetween15And30Minutes(model.incubationTime) + when { + incubationTime < -15000 -> showIncubationNotCompletedMessage() + incubationTime > 300000 -> showIncubationCrossedMessage() + else -> navigateToMainActivity(model) + } + } + + private fun showIncubationNotStartedMessage() { + Toast.makeText( + view.context, + context.getString(R.string.incubation_not_started), + Toast.LENGTH_SHORT + ).show() + } + + private fun showIncubationNotCompletedMessage() { + Toast.makeText( + view.context, + context.getString(R.string.incubation_not_completed), + Toast.LENGTH_SHORT + ).show() + } + + private fun showIncubationCrossedMessage() { + Toast.makeText( + view.context, + context.getString(R.string.incubation_crossed_30_minutes), + Toast.LENGTH_SHORT + ).show() + } + + private fun navigateToMainActivity(model: UserData) { + DataHolder.selectedTest = model + view.findNavController().navigate(R.id.action_nav_home_to_mainActivity) + } + private fun isBetween15And30Minutes(createdAt: String): Long { val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) val createdAtDate: Date = formatter.parse(createdAt)!! - val currentTime = Calendar.getInstance().time - val diffMillis = currentTime.time - createdAtDate.time - return diffMillis / (60 * 1000) } } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/assurance/AssuranceControlsFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/assurance/AssuranceControlsFragment.kt index 135acac..77cff8a 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/assurance/AssuranceControlsFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/assurance/AssuranceControlsFragment.kt @@ -36,234 +36,277 @@ import `in`.sminnovations.hpostesting.databinding.FragmentAssuranceControlsBindi import java.time.Instant class AssuranceControlsFragment : Fragment() { - lateinit var binding: FragmentAssuranceControlsBinding + private val selectConcentration = "Select concentration" + private val selectSolution = "Select solution" + private lateinit var binding: FragmentAssuranceControlsBinding private lateinit var sharedPreferences: SharedPreferences override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentAssuranceControlsBinding.inflate(inflater, container, false) - sharedPreferences = - requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) - - DataHolder.hemoCubeTestData!!.solution = "" - DataHolder.hemoCubeTestData!!.volume = "" + initializeSharedPreferences() + resetTestData() return binding.root } + private fun initializeSharedPreferences() { + sharedPreferences = requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) + } + + private fun resetTestData() { + DataHolder.hemoCubeTestData?.apply { + solution = "" + volume = "" + } + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initViews() } private fun initViews() { -// binding.btnSubmit.visibility = View.GONE - val solutionSpinner: Spinner = binding.spinnerSolutions - val solutionOptions = arrayOf("Select solution", "Tartrazine", "Acid Red","Sickle-Cert-Buffer", "1 Abs Holo Filter", "0.25 Abs Holo Filter", "Air Blank") - val solutionAdapter = - ArrayAdapter(requireContext(), R.layout.simple_spinner_item, solutionOptions) - solutionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - solutionSpinner.adapter = solutionAdapter - solutionSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { - override fun onItemSelected( - parent: AdapterView<*>?, - view: View?, - position: Int, - id: Long, - ) { - val selectedSolution: String = solutionOptions[position] - if (selectedSolution != "Select solution") { - DataHolder.hemoCubeTestData!!.solution = selectedSolution + setupSolutionSpinner() + setupConcentrationSpinner() + setupVolumeSpinner() + setupAdminSpinner() + loadSavedValues() + setupSubmitButton() + } - // Update visibility and name based on selected solution - if(selectedSolution == "Tartrazine" || selectedSolution == "Acid Red"){ - activity?.runOnUiThread { - binding.spinnerConcentration.visibility = View.VISIBLE - // Ensure the name is updated only after concentration is selected. - // You might need to adjust this logic based on how and when you want to update the name. - // For now, it simply shows that the visibility is being handled. - } - } else { - activity?.runOnUiThread { - binding.spinnerConcentration.visibility = View.GONE - } - } - } else { - activity?.runOnUiThread { - binding.spinnerConcentration.visibility = View.GONE - } - } - } - - override fun onNothingSelected(parent: AdapterView<*>?) { - } - } - - val concentrationSpinner: Spinner = binding.spinnerConcentration - val concentrationOptions = arrayOf( - "Select concentration", - "65umol", - "45umol", - "22.5umol", - "12.25umol", - "6.125umol", - "75umol", - "50umol", - "25umol", - "12.5umol", - "6.25umol" - ) - val concentrationAdapter = - ArrayAdapter(requireContext(), R.layout.simple_spinner_item, concentrationOptions) - concentrationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - concentrationSpinner.adapter = concentrationAdapter - concentrationSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { - override fun onItemSelected( - parent: AdapterView<*>?, - view: View?, - position: Int, - id: Long, - ) { - val selectedValue: String = concentrationOptions[position] - if (!selectedValue.equals("Select concentration")) { - DataHolder.hemoCubeTestData!!.concentration = selectedValue - } - } - - override fun onNothingSelected(parent: AdapterView<*>?) { - } - } - - val volumeSpinner: Spinner = binding.spinnerVolume - val volumeOptions = arrayOf("Select volume", "1uml", "2uml", "4uml", "4.5uml", "5uml") - val volumeAdapter = - ArrayAdapter(requireContext(), R.layout.simple_spinner_item, volumeOptions) - volumeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - volumeSpinner.adapter = volumeAdapter - volumeSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { - override fun onItemSelected( - parent: AdapterView<*>?, - view: View?, - position: Int, - id: Long, - ) { - val selectedValue: String = volumeOptions[position] - } - - override fun onNothingSelected(parent: AdapterView<*>?) { - } - } - - - val adminspinner: Spinner = binding.spinnerAdmin - val adminOptions = arrayOf("Select options", "Sickle-Cert-Buffer", "1 Abs Holo Filter", "0.25 Abs Holo Filter", "Air Blank") - val adminAdapter = - ArrayAdapter(requireContext(), R.layout.simple_spinner_item, adminOptions) - adminAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - adminspinner.adapter =adminAdapter - adminspinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { - override fun onItemSelected( - parent: AdapterView<*>?, - view: View?, - position: Int, - id: Long, - ) { - val selectedValue: String = adminOptions[position] - - } - - override fun onNothingSelected(parent: AdapterView<*>?) { - } - } - // load saved values - val savedSolution = - sharedPreferences.getString(Constants.QUICK_CAPTURE_SOLUTION, "").toString() - val solutionPosition = getPositionOfValue(savedSolution, solutionOptions.toList()) - solutionSpinner.setSelection(solutionPosition) - - val savedConcentration = - sharedPreferences.getString(Constants.QUICK_CAPTURE_CONCENTRATION, "").toString() - val concentrationPosition = - getPositionOfValue(savedConcentration, concentrationOptions.toList()) - concentrationSpinner.setSelection(concentrationPosition) - - val savedVolume = sharedPreferences.getString(Constants.QUICK_CAPTURE_VOLUME, "").toString() - val volumePosition = getPositionOfValue(savedVolume, volumeOptions.toList()) - volumeSpinner.setSelection(volumePosition) - - - val foradmin = - sharedPreferences.getString(Constants.QUICK_CAPTURE_FOR_ADMIN, "").toString() - val adminPosition = getPositionOfValue(foradmin, adminOptions.toList()) - adminspinner.setSelection(adminPosition) - - binding.btnSubmit.setOnClickListener { - val selectedSolution = binding.spinnerSolutions.selectedItem.toString() - val selectedConcentration = binding.spinnerConcentration.selectedItem.toString() - val selectedadminOption = binding.spinnerAdmin.selectedItem.toString() - - // Check if any of the selections are default values - if (selectedSolution == "Select solution") { - Toast.makeText(requireContext(), "Please select a solution", Toast.LENGTH_LONG).show() - return@setOnClickListener // Prevent further execution - }else{ - DataHolder.hemoCubeTestData!!.name = selectedSolution - } - - if (selectedConcentration == "Select concentration" && binding.spinnerConcentration.isVisible) { - Toast.makeText(requireContext(), "Please select a concentration", Toast.LENGTH_LONG).show() - return@setOnClickListener // Prevent further execution - }else if(binding.spinnerConcentration.isVisible){ - DataHolder.hemoCubeTestData!!.name = "$selectedSolution $selectedConcentration" - }else{ - DataHolder.hemoCubeTestData!!.name = selectedSolution - } - - - - - if (selectedadminOption == "Select options" && binding.spinnerAdmin.isVisible) { - Toast.makeText(requireContext(), "Please select a option", Toast.LENGTH_LONG).show() - return@setOnClickListener // Prevent further execution - } - DataHolder.hemoCubeTestData!!.quickCapture = true - val currentUnixTime = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - Instant.now().epochSecond - } else { - "" - } - DataHolder.hemoCubeTestData!!._id = currentUnixTime.toString() + "SMI" - DataHolder.hemoCubeTestData!!.solution = binding.spinnerSolutions.selectedItem.toString() - DataHolder.hemoCubeTestData!!.concentration = binding.spinnerConcentration.selectedItem.toString() - DataHolder.hemoCubeTestData!!.filter = binding.spinnerAdmin.selectedItem.toString() -// if(binding.spinnerAdmin.selectedItem.toString().equals("Select options") && binding.spinnerAdmin.isVisible){ -// Toast.makeText(requireContext(), "Please select a option", Toast.LENGTH_LONG).show() -// }else { -// DataHolder.hemoCubeTestData!!.name = DataHolder.hemoCubeTestData!!.filter.toString() -// } - - - - DataHolder.selectedTest = UserData() - DataHolder.selectedTest?._id = DataHolder.hemoCubeTestData!!._id - DataHolder.selectedTest?.name = DataHolder.hemoCubeTestData!!.name - - with(sharedPreferences.edit()) { - putString(Constants.QUICK_CAPTURE_SOLUTION, DataHolder.hemoCubeTestData!!.solution) - putString( - Constants.QUICK_CAPTURE_CONCENTRATION, - DataHolder.hemoCubeTestData!!.concentration - ) - putString(Constants.QUICK_CAPTURE_VOLUME, DataHolder.hemoCubeTestData!!.volume) - putString(Constants.QUICK_CAPTURE_FOR_ADMIN, DataHolder.hemoCubeTestData!!.filter) - apply() - } - - val i = Intent(requireContext(), HemocubeActivity::class.java) - startActivity(i) + private fun setupSolutionSpinner() { + val solutionOptions = getSolutionOptions() + val solutionAdapter = createSpinnerAdapter(solutionOptions) + binding.spinnerSolutions.apply { + adapter = solutionAdapter + onItemSelectedListener = createSolutionSelectionListener(solutionOptions) } } + private fun getSolutionOptions() = arrayOf( + selectSolution, "Tartrazine", "Acid Red", "Sickle-Cert-Buffer", + "1 Abs Holo Filter", "0.25 Abs Holo Filter", "Air Blank" + ) + + private fun createSolutionSelectionListener(solutionOptions: Array) = + object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, position: Int, id: Long + ) { + handleSolutionSelection(solutionOptions[position]) + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + //Nothing + } + } + + private fun handleSolutionSelection(selectedSolution: String) { + if (selectedSolution != selectSolution) { + DataHolder.hemoCubeTestData?.solution = selectedSolution + updateConcentrationSpinnerVisibility(selectedSolution) + } else { + activity?.runOnUiThread { + binding.spinnerConcentration.visibility = View.GONE + } + } + } + + private fun updateConcentrationSpinnerVisibility(selectedSolution: String) { + val shouldShowConcentration = selectedSolution in listOf("Tartrazine", "Acid Red") + activity?.runOnUiThread { + binding.spinnerConcentration.visibility = + if (shouldShowConcentration) View.VISIBLE else View.GONE + } + } + + private fun setupConcentrationSpinner() { + val concentrationOptions = getConcentrationOptions() + val concentrationAdapter = createSpinnerAdapter(concentrationOptions) + binding.spinnerConcentration.apply { + adapter = concentrationAdapter + onItemSelectedListener = createConcentrationSelectionListener(concentrationOptions) + } + } + + private fun getConcentrationOptions() = arrayOf( + selectConcentration, "65umol", "45umol", "22.5umol", "12.25umol", + "6.125umol", "75umol", "50umol", "25umol", "12.5umol", "6.25umol" + ) + + private fun createConcentrationSelectionListener(concentrationOptions: Array) = + object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, position: Int, id: Long + ) { + val selectedValue = concentrationOptions[position] + if (selectedValue != selectConcentration) { + DataHolder.hemoCubeTestData?.concentration = selectedValue + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + //Nothing + } + } + + private fun setupVolumeSpinner() { + val volumeOptions = getVolumeOptions() + val volumeAdapter = createSpinnerAdapter(volumeOptions) + binding.spinnerVolume.apply { + adapter = volumeAdapter + onItemSelectedListener = createVolumeSelectionListener(volumeOptions) + } + } + + private fun getVolumeOptions() = + arrayOf("Select volume", "1uml", "2uml", "4uml", "4.5uml", "5uml") + + private fun setupAdminSpinner() { + val adminOptions = getAdminOptions() + val adminAdapter = createSpinnerAdapter(adminOptions) + binding.spinnerAdmin.apply { + adapter = adminAdapter + onItemSelectedListener = createAdminSelectionListener(adminOptions) + } + } + + private fun getAdminOptions() = arrayOf( + "Select options", "Sickle-Cert-Buffer", "1 Abs Holo Filter", + "0.25 Abs Holo Filter", "Air Blank" + ) + + private fun createSpinnerAdapter(options: Array): ArrayAdapter { + return ArrayAdapter(requireContext(), R.layout.simple_spinner_item, options).apply { + setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + } + } + + private fun loadSavedValues() { + loadSpinnerValue(Constants.QUICK_CAPTURE_SOLUTION, getSolutionOptions(), binding.spinnerSolutions) + loadSpinnerValue(Constants.QUICK_CAPTURE_CONCENTRATION, getConcentrationOptions(), binding.spinnerConcentration) + loadSpinnerValue(Constants.QUICK_CAPTURE_VOLUME, getVolumeOptions(), binding.spinnerVolume) + loadSpinnerValue(Constants.QUICK_CAPTURE_FOR_ADMIN, getAdminOptions(), binding.spinnerAdmin) + } + + private fun loadSpinnerValue(key: String, options: Array, spinner: Spinner) { + val savedValue = sharedPreferences.getString(key, "").toString() + val position = getPositionOfValue(savedValue, options.toList()) + spinner.setSelection(position) + } + + private fun setupSubmitButton() { + binding.btnSubmit.setOnClickListener { + if (!validateSelections()) return@setOnClickListener + updateTestData() + savePreferences() + navigateToHemocubeActivity() + } + } + + private fun validateSelections(): Boolean { + val selectedSolution = binding.spinnerSolutions.selectedItem.toString() + val selectedConcentration = binding.spinnerConcentration.selectedItem.toString() + val selectedAdminOption = binding.spinnerAdmin.selectedItem.toString() + + if (selectedSolution == selectSolution) { + showToast("Please select a solution") + return false + } + + if (selectedConcentration == selectConcentration && binding.spinnerConcentration.isVisible) { + showToast("Please select a concentration") + return false + } + + if (selectedAdminOption == "Select options" && binding.spinnerAdmin.isVisible) { + showToast("Please select a option") + return false + } + + return true + } + + private fun showToast(message: String) { + Toast.makeText(requireContext(), message, Toast.LENGTH_LONG).show() + } + + private fun updateTestData() { + DataHolder.hemoCubeTestData?.apply { + quickCapture = true + _id = generateTestId() + solution = binding.spinnerSolutions.selectedItem.toString() + concentration = binding.spinnerConcentration.selectedItem.toString() + filter = binding.spinnerAdmin.selectedItem.toString() + name = determineTestName() + } + + DataHolder.selectedTest = UserData().apply { + _id = DataHolder.hemoCubeTestData?._id.toString() + name = DataHolder.hemoCubeTestData?.name.toString() + } + } + + private fun generateTestId(): String { + val currentUnixTime = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Instant.now().epochSecond + } else { + "" + } + return "${currentUnixTime}SMI" + } + + private fun determineTestName(): String { + val solution = binding.spinnerSolutions.selectedItem.toString() + return if (binding.spinnerConcentration.isVisible) { + "$solution ${binding.spinnerConcentration.selectedItem}" + } else { + solution + } + } + + private fun savePreferences() { + with(sharedPreferences.edit()) { + putString(Constants.QUICK_CAPTURE_SOLUTION, DataHolder.hemoCubeTestData?.solution) + putString(Constants.QUICK_CAPTURE_CONCENTRATION, DataHolder.hemoCubeTestData?.concentration) + putString(Constants.QUICK_CAPTURE_VOLUME, DataHolder.hemoCubeTestData?.volume) + putString(Constants.QUICK_CAPTURE_FOR_ADMIN, DataHolder.hemoCubeTestData?.filter) + apply() + } + } + + private fun navigateToHemocubeActivity() { + val intent = Intent(requireContext(), HemocubeActivity::class.java) + startActivity(intent) + } + + private fun createVolumeSelectionListener(volumeOptions: Array) = + object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, position: Int, id: Long + ) { + volumeOptions[position] + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + //Nothing + } + } + + private fun createAdminSelectionListener(adminOptions: Array) = + object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, position: Int, id: Long + ) { + adminOptions[position] + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + //Nothing + } + } + fun getPositionOfValue(value: T, data: List?): Int { data?.let { for (i in it.indices) { @@ -272,7 +315,6 @@ class AssuranceControlsFragment : Fragment() { } } } - return 0 } } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/presentation/autodac/AutoDacFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/autodac/AutoDacFragment.kt index 4ee7fa1..dfbdf07 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/autodac/AutoDacFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/autodac/AutoDacFragment.kt @@ -44,74 +44,101 @@ class AutoDacFragment : Fragment() { private lateinit var sharedPreferences: SharedPreferences private var currentDeviceData: DeviceData? = null private var resultData: String = "" - // private val messages = MutableLiveData() private var startListening = MutableLiveData(false) override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentAutoDacBinding.inflate(inflater, container, false) - sharedPreferences = - requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) + initSharedPreferences() return binding.root } + private fun initSharedPreferences() { + sharedPreferences = requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initViews() - observeViewModel() + setupObservers() } private fun initViews() { - binding.btnSubmit.visibility = View.GONE + setupInitialViewState() + setupClickListeners() + setupAdminControls() listenToHemoCube() getDeviceId() - binding.tvSubtitle4.movementMethod = ScrollingMovementMethod() - binding.btnSubmit.setOnClickListener { - resultData += "Calibrating the device...\n" - autoDacViewModel.messages.postValue(resultData) - testStatusCode = 0.5 - binding.btnSubmit.visibility = View.GONE - runJCommand() - } - binding.btnReadDac.setOnClickListener { - readClick = true - binding.btnReadDac.visibility = View.GONE - runECommand() - } - if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") { - binding.btnReadDac.visibility = View.VISIBLE - }else{ - binding.btnReadDac.visibility = View.GONE - } - } - private fun observeViewModel() { - - autoDacViewModel.deviceData.observe(viewLifecycleOwner) { - currentDeviceData = it + private fun setupInitialViewState() { + binding.apply { + btnSubmit.visibility = View.GONE + tvSubtitle4.movementMethod = ScrollingMovementMethod() } + } - autoDacViewModel.messages.observe(viewLifecycleOwner) { - binding.tvSubtitle4.text = it + private fun setupClickListeners() { + binding.apply { + btnSubmit.setOnClickListener { + resultData += "Calibrating the device...\n" + autoDacViewModel.messages.postValue(resultData) + testStatusCode = 0.5 + btnSubmit.visibility = View.GONE + sendHemoCubeCommand(HemoCubeCommands.J_COMMAND) + } + btnReadDac.setOnClickListener { + readClick = true + btnReadDac.visibility = View.GONE + sendHemoCubeCommand(HemoCubeCommands.LOAD_DAC_VALUES) + } } + } - autoDacViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result -> - if (result == "Success") { - showToast("Auto Dac data uploaded successfully") - } - if (result == "Local") { - showToast("Auto Dac uploading failed, note it down manually") - } + private fun setupAdminControls() { + binding.btnReadDac.visibility = + if (isAdminUser()) View.VISIBLE else View.GONE + } - binding.progressBar.visibility = View.GONE + private fun isAdminUser(): Boolean = + sharedPreferences.getString(Constants.USER_ID, "") == "ADMIN" + + private fun setupObservers() { + with(autoDacViewModel) { + deviceData.observe(viewLifecycleOwner) { currentDeviceData = it } + messages.observe(viewLifecycleOwner) { binding.tvSubtitle4.text = it } + fireBaseUpload.observe(viewLifecycleOwner) { handleFirebaseUploadResult(it) } + } + } + + private fun handleFirebaseUploadResult(result: String) { + when (result) { + "Success" -> showToast("Auto Dac data uploaded successfully") + "Local" -> showToast("Auto Dac uploading failed, note it down manually") + } + binding.progressBar.visibility = View.GONE + } + + private fun sendHemoCubeCommand( + command: HemoCubeCommands, + listener: UsbServiceListener = defaultUsbListener() + ) { + autoDacViewModel.progressBar.postValue(true) + (activity as AutoDacActivity).mService.sendAndListenToHemoCube(command, listener) + } + + private fun defaultUsbListener() = object : UsbServiceListener { + override fun onUsbRead(data: ByteArray?) { + //Nothing + } + override fun onUsbError(e: Exception?) { + autoDacViewModel.progressBar.postValue(false) } } private fun getDeviceId() { - autoDacViewModel.progressBar.postValue(true) - (activity as AutoDacActivity).mService.sendAndListenToHemoCube( + sendHemoCubeCommand( HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) { @@ -125,257 +152,143 @@ class AutoDacFragment : Fragment() { override fun onUsbError(e: Exception?) { autoDacViewModel.progressBar.postValue(false) } - }) - } - private fun runJCommand() { - autoDacViewModel.progressBar.postValue(true) - (activity as AutoDacActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.J_COMMAND, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) { - } - - override fun onUsbError(e: Exception?) { - autoDacViewModel.progressBar.postValue(false) - } - }) - } - private fun runDCommand() { - autoDacViewModel.progressBar.postValue(true) - (activity as AutoDacActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.DIAGNOSTICS_COMMAND, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) { - } - - override fun onUsbError(e: Exception?) { - autoDacViewModel.progressBar.postValue(false) - } - }) - } - private fun runCCommand() { - autoDacViewModel.progressBar.postValue(true) - (activity as AutoDacActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.AUTO_DAC_COMMAND, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) { - } - - override fun onUsbError(e: Exception?) { - autoDacViewModel.progressBar.postValue(false) - } - }) - } - private fun runGCommand() { - autoDacViewModel.progressBar.postValue(true) - (activity as AutoDacActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.SET_AUTO_DAC_TO_EPROM_COMMAND, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) { - } - - override fun onUsbError(e: Exception?) { - autoDacViewModel.progressBar.postValue(false) - } - }) - } - private fun runECommand() { - autoDacViewModel.progressBar.postValue(true) - (activity as AutoDacActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.LOAD_DAC_VALUES, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) { - } - - override fun onUsbError(e: Exception?) { - autoDacViewModel.progressBar.postValue(false) - } - }) - } - - - private fun setAutoDacValuesCommand() { - autoDacViewModel.progressBar.postValue(true) - (activity as AutoDacActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.SET_AUTO_DAC_TO_EPROM_COMMAND, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) { - } - - override fun onUsbError(e: Exception?) { - autoDacViewModel.progressBar.postValue(false) - } - }) - } - - private fun readCurrentDACValuesCommand() { - autoDacViewModel.progressBar.postValue(true) - (activity as AutoDacActivity).mService.sendAndListenToHemoCube( - HemoCubeCommands.READ_DAC_COMMAND, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) { - } - - override fun onUsbError(e: Exception?) { - autoDacViewModel.progressBar.postValue(false) - } - }) + } + ) } private fun listenToHemoCube() { - - val fullReadOutput = StringBuilder() startListening.postValue(true) - try { - (activity as AutoDacActivity).mService.listenToHemoCube(object : - UsbServiceListener { - override fun onUsbRead(data: ByteArray?) { - data?.let { - val stringData = String(it) - fullReadOutput.append(stringData) - resultData += stringData - if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") { - autoDacViewModel.messages.postValue(resultData) - } - // binding.tvSubtitle4.text = resultData - if (stringData.contains("SN")) { - val slData = stringData.split(" ") - if (slData.size > 1) { - val hardwareId = slData[1].trim() -// with(sharedPreferences.edit()) { -// putString(Constants.DEVICE_ID, hardwareId) -// apply() -// } - } - activity?.runOnUiThread { - binding.btnSubmit.visibility = View.VISIBLE - } - } - } - if (resultData.contains("#JC") && testStatusCode < 1.0) { - testStatusCode = 1.1 - runDCommand() - } - if (resultData.contains("#DC") && testStatusCode < 1.2) { - testStatusCode = 1.3 - if(validateDacValues()){ - if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") { - resultData += "Calibrating the device, Please wait...\n" - }else{ - resultData = "Calibrating the device, Please wait...\n" - } - autoDacViewModel.messages.postValue(resultData) - runCCommand() - }else{ - activity?.runOnUiThread { - if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") { - resultData += "Calibration failed!\nContact us for help at support@sminnovations.in" - }else{ - resultData = "Calibration failed!\nContact us for help at support@sminnovations.in" - } - autoDacViewModel.messages.postValue(resultData) - binding.btnReadDac.visibility = View.GONE - } - } - } - if (resultData.contains("#GC") && testStatusCode < 1.6) { - testStatusCode = 1.7 - runECommand() - } - if (resultData.contains("#EC") && testStatusCode < 1.8) { - testStatusCode = 1.9 - if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") { - resultData += "Calibration Completed\n" - }else{ - resultData = "Calibration Completed\n" - } - autoDacViewModel.messages.postValue(resultData) - activity?.runOnUiThread { - Toast.makeText(requireActivity(), "Calibration completed", Toast.LENGTH_LONG).show() - binding.ivCheck.visibility = View.VISIBLE - } - } - if (resultData.contains("#EC") && readClick && testStatusCode < 2.1) { - testStatusCode = 2.2 - readCurrentDACValuesCommand() - } - if (resultData.contains("#CC") && testStatusCode < 1.4) { - testStatusCode = 1.5 - setAutoDacValuesCommand() - autoDacViewModel.addAutoDacDataToDb( - DiagnosticsData( - deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "") - .toString(), - devicePassword = sharedPreferences.getString( - Constants.DEVICE_PASSWORD_API, - "" - ).toString(), - deviceNatsToken = sharedPreferences.getString( - Constants.NATS_TOKEN, - "" - ).toString(), - accessToken = sharedPreferences.getString( - Constants.ACCESS_TOKEN, - "" - ).toString(), - deviceData = resultData, - runTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() - ).format(Calendar.getInstance().time) - ) - ) - + (activity as AutoDacActivity).mService.listenToHemoCube( + object : UsbServiceListener { + override fun onUsbRead(data: ByteArray?) { + data?.let { handleHemoCubeData(String(it)) } } - if (resultData.contains("#WC")) { - showToast("DAC Values saved to EPROM") + override fun onUsbError(e: Exception?) { + autoDacViewModel.progressBar.postValue(false) } } - - override fun onUsbError(e: Exception?) { - autoDacViewModel.progressBar.postValue(false) - } - }) + ) } catch (e: Exception) { Firebase.crashlytics.recordException(e) } } - fun extractSubstring(input: String): String { - val regex = "#CS(.*?)#CC".toRegex() - val matchResult = regex.find(input) - return matchResult?.groups?.get(1)?.value?.trim() ?: "" + + private fun handleHemoCubeData(stringData: String) { + resultData += stringData + if (isAdminUser()) { + autoDacViewModel.messages.postValue(resultData) + } + + when { + stringData.contains("SN") -> handleSerialNumber(stringData) + resultData.contains("#JC") && testStatusCode < 1.0 -> handleJCommandResponse() + resultData.contains("#DC") && testStatusCode < 1.2 -> handleDCommandResponse() + resultData.contains("#GC") && testStatusCode < 1.6 -> handleGCommandResponse() + resultData.contains("#EC") && testStatusCode < 1.8 -> handleECommandResponse() + resultData.contains("#EC") && readClick && testStatusCode < 2.1 -> handleReadClickResponse() + resultData.contains("#CC") && testStatusCode < 1.4 -> handleCCommandResponse() + resultData.contains("#WC") -> showToast("DAC Values saved to EPROM") + } } + + private fun handleSerialNumber(stringData: String) { + stringData.split(" ").getOrNull(1)?.trim()?.let { _ -> + // Commented as per original code + // saveHardwareId(hardwareId) + } + activity?.runOnUiThread { + binding.btnSubmit.visibility = View.VISIBLE + } + } + + private fun handleJCommandResponse() { + testStatusCode = 1.1 + sendHemoCubeCommand(HemoCubeCommands.DIAGNOSTICS_COMMAND) + } + + private fun handleDCommandResponse() { + testStatusCode = 1.3 + if (validateDacValues()) { + val message = if (isAdminUser()) { + resultData += "Calibrating the device, Please wait...\n" + resultData + } else { + "Calibrating the device, Please wait...\n" + } + autoDacViewModel.messages.postValue(message) + sendHemoCubeCommand(HemoCubeCommands.AUTO_DAC_COMMAND) + } else { + handleCalibrationFailure() + } + } + + private fun handleCalibrationFailure() { + activity?.runOnUiThread { + val message = if (isAdminUser()) { + resultData += "Calibration failed!\nContact us for help at support@sminnovations.in" + resultData + } else { + "Calibration failed!\nContact us for help at support@sminnovations.in" + } + autoDacViewModel.messages.postValue(message) + binding.btnReadDac.visibility = View.GONE + } + } + + private fun handleGCommandResponse() { + testStatusCode = 1.7 + sendHemoCubeCommand(HemoCubeCommands.LOAD_DAC_VALUES) + } + + private fun handleECommandResponse() { + testStatusCode = 1.9 + val message = if (isAdminUser()) { + resultData += "Calibration Completed\n" + resultData + } else { + "Calibration Completed\n" + } + autoDacViewModel.messages.postValue(message) + activity?.runOnUiThread { + showToast("Calibration completed") + binding.ivCheck.visibility = View.VISIBLE + } + } + + private fun handleReadClickResponse() { + testStatusCode = 2.2 + sendHemoCubeCommand(HemoCubeCommands.READ_DAC_COMMAND) + } + + private fun handleCCommandResponse() { + testStatusCode = 1.5 + sendHemoCubeCommand(HemoCubeCommands.SET_AUTO_DAC_TO_EPROM_COMMAND) + uploadAutoDacData() + } + + private fun uploadAutoDacData() { + autoDacViewModel.addAutoDacDataToDb( + DiagnosticsData( + deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString(), + devicePassword = sharedPreferences.getString(Constants.DEVICE_PASSWORD_API, "").toString(), + deviceNatsToken = sharedPreferences.getString(Constants.NATS_TOKEN, "").toString(), + accessToken = sharedPreferences.getString(Constants.ACCESS_TOKEN, "").toString(), + deviceData = resultData, + runTime = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) + .format(Calendar.getInstance().time) + ) + ) + } + private fun validateDacValues(): Boolean { val pattern = Regex("(LED:\\d+)__DAC:(\\d+)__ADC:(\\d+)") - val matches = pattern.findAll(resultData) - for (match in matches) { - val ledName = match.groupValues[1] + return pattern.findAll(resultData).none { match -> val xValue = match.groupValues[2].toDouble() val yValue = match.groupValues[3].toDouble() - - if(xValue == 3200.0){ - if(yValue < 500.0){ - return false - } - } + xValue == 3200.0 && yValue < 500.0 } - return true - } - - fun parseData(inputData: List): List> { - val pattern = Regex("([A-Z]+)\\s(\\d+)") - val parsedData = mutableListOf>() - - for (item in inputData) { - val matchResult = pattern.find(item) - if (matchResult != null) { - val (letters, numbers) = matchResult.destructured - parsedData.add(Pair(letters, numbers)) - } - } - - return parsedData } private fun showToast(message: String) { diff --git a/app/src/main/java/com/example/hpostesting/presentation/autodac/AutoDacViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/autodac/AutoDacViewModel.kt index 1da6b9a..3f42e68 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/autodac/AutoDacViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/autodac/AutoDacViewModel.kt @@ -45,7 +45,7 @@ class AutoDacViewModel @Inject constructor( fun addAutoDacDataToDb(data: DiagnosticsData) { viewModelScope.launch { try { - when (val response = repository.addDiagnostics(data)) { + when (repository.addDiagnostics(data)) { is Response.Success -> { fireBaseUpload.postValue("Success") } diff --git a/app/src/main/java/com/example/hpostesting/presentation/buffercheck/HemoCubeBufferCheckFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/buffercheck/HemoCubeBufferCheckFragment.kt index d29e373..1f2a76e 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/buffercheck/HemoCubeBufferCheckFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/buffercheck/HemoCubeBufferCheckFragment.kt @@ -42,7 +42,7 @@ import java.util.UUID import kotlin.math.log10 class HemoCubeBufferCheckFragment : Fragment() { - + private val kitFailed = "Kit Failed" private lateinit var binding: FragmentHemoCubeReferenceBinding private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels() private lateinit var sharedPreferences: SharedPreferences @@ -178,6 +178,7 @@ class HemoCubeBufferCheckFragment : Fragment() { } override fun onUsbError(e: Exception?) { + //nothing } }) } catch (e: Exception) { @@ -402,27 +403,27 @@ class HemoCubeBufferCheckFragment : Fragment() { } } - private fun findResult(calculatedRatio: Double?): String { - try { - hemoCubeViewModel.messages.postValue("result classification") - if (calculatedRatio != null) { - if (calculatedRatio < 0.05) return "Inconclusive. Very low Absorbance - Repeat test with Higher Blood Volume" - if (calculatedRatio in 0.05..0.155) return "Normal" - if (calculatedRatio in 0.155..0.175) return "Negative Borderline. Repeat Test" - if (calculatedRatio in 0.175..0.22) return "Sickle Cell Trait" - if (calculatedRatio in 0.22..0.25) return "Positive for Sickle Cell. HPLC for Confirmation" - if (calculatedRatio in 0.25..0.35) return "Sickle Cell Disease" - if (calculatedRatio > 0.35) return "Inconclusive. Repeat with test with lower volume of blood" - } else { - return "INVALID" - } - } catch (e: Exception) { - showToast(R.string.error_classification) - Firebase.crashlytics.recordException(e) - return "ERROR" - } - return "INVALID" - } +// private fun findResult(calculatedRatio: Double?): String { +// try { +// hemoCubeViewModel.messages.postValue("result classification") +// if (calculatedRatio != null) { +// if (calculatedRatio < 0.05) return "Inconclusive. Very low Absorbance - Repeat test with Higher Blood Volume" +// if (calculatedRatio in 0.05..0.155) return "Normal" +// if (calculatedRatio in 0.155..0.175) return "Negative Borderline. Repeat Test" +// if (calculatedRatio in 0.175..0.22) return "Sickle Cell Trait" +// if (calculatedRatio in 0.22..0.25) return "Positive for Sickle Cell. HPLC for Confirmation" +// if (calculatedRatio in 0.25..0.35) return "Sickle Cell Disease" +// if (calculatedRatio > 0.35) return "Inconclusive. Repeat with test with lower volume of blood" +// } else { +// return "INVALID" +// } +// } catch (e: Exception) { +// showToast(R.string.error_classification) +// Firebase.crashlytics.recordException(e) +// return "ERROR" +// } +// return "INVALID" +// } private fun absorbanceBasedClassification(predictedDenovixRatio: Double?): String { try { @@ -430,9 +431,9 @@ class HemoCubeBufferCheckFragment : Fragment() { if (predictedDenovixRatio != null) { if (predictedDenovixRatio in 0.0..0.16) return "Kit Passed" if (predictedDenovixRatio in 0.16..0.165) return "Kit Passed" - if (predictedDenovixRatio in 0.165..0.235) return "Kit Failed" - if (predictedDenovixRatio in 0.235..0.24) return "Kit Failed" - if (predictedDenovixRatio in 0.24..1.0) return "Kit Failed" + if (predictedDenovixRatio in 0.165..0.235) return kitFailed + if (predictedDenovixRatio in 0.235..0.24) return kitFailed + if (predictedDenovixRatio in 0.24..1.0) return kitFailed } else { return "INVALID" } @@ -460,9 +461,12 @@ class HemoCubeBufferCheckFragment : Fragment() { (activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.START_BUFFER_COMMAND, object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} + override fun onUsbRead(data: ByteArray?) { + //nothing + } override fun onUsbError(e: Exception?) { + //nothing } }) } @@ -474,9 +478,12 @@ class HemoCubeBufferCheckFragment : Fragment() { (activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.START_SAMPLE, object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} + override fun onUsbRead(data: ByteArray?) { + //nothing + } override fun onUsbError(e: Exception?) { + //nothing } }) } @@ -504,18 +511,21 @@ class HemoCubeBufferCheckFragment : Fragment() { (activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.PRINT_COMMAND, object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} + override fun onUsbRead(data: ByteArray?) { + //nothing + } override fun onUsbError(e: Exception?) { + //nothing } }) } - - private fun calculateRatio(ratio: Double): Double { - val coefficient1 = currentDeviceData?.coefficients?.get(0) ?: 0.0 - val coefficient2 = currentDeviceData?.coefficients?.get(1) ?: 1.0 - return coefficient1 * ratio + coefficient2 - } +// +// private fun calculateRatio(ratio: Double): Double { +// val coefficient1 = currentDeviceData?.coefficients?.get(0) ?: 0.0 +// val coefficient2 = currentDeviceData?.coefficients?.get(1) ?: 1.0 +// return coefficient1 * ratio + coefficient2 +// } private fun isSerialValid(s: String): Boolean { if (s.length != 17) { diff --git a/app/src/main/java/com/example/hpostesting/presentation/calibration/CalibrationFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/calibration/CalibrationFragment.kt index 479d2cf..93b4cc1 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/calibration/CalibrationFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/calibration/CalibrationFragment.kt @@ -75,9 +75,11 @@ class CalibrationFragment : Fragment() { val etLed1Slope = binding.etLed1Slope etLed1Slope.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + //nothing } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + //nothing } override fun afterTextChanged(s: Editable?) { @@ -87,9 +89,11 @@ class CalibrationFragment : Fragment() { val etLed1Intercept = binding.etLed1Intercept etLed1Intercept.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + //nothing } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + //nothing } override fun afterTextChanged(s: Editable?) { @@ -100,9 +104,11 @@ class CalibrationFragment : Fragment() { val etLed2Slope = binding.etLed2Slope etLed2Slope.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + //nothing } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + //nothing } override fun afterTextChanged(s: Editable?) { @@ -112,9 +118,11 @@ class CalibrationFragment : Fragment() { val etLed2Intercept = binding.etLed2Intercept etLed2Intercept.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + //nothing } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + //nothing } override fun afterTextChanged(s: Editable?) { @@ -125,9 +133,11 @@ class CalibrationFragment : Fragment() { val etLed3Slope = binding.etLed3Slope etLed3Slope.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + //nothing } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + //nothing } override fun afterTextChanged(s: Editable?) { @@ -137,9 +147,11 @@ class CalibrationFragment : Fragment() { val etLed3Intercept = binding.etLed3Intercept etLed3Intercept.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + //nothing } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + //nothing } override fun afterTextChanged(s: Editable?) { @@ -150,9 +162,11 @@ class CalibrationFragment : Fragment() { val etLed4Slope = binding.etLed4Slope etLed4Slope.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + //nothing } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + //nothing } override fun afterTextChanged(s: Editable?) { @@ -162,9 +176,11 @@ class CalibrationFragment : Fragment() { val etLed4Intercept = binding.etLed4Intercept etLed4Intercept.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + //nothing } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + //nothing } override fun afterTextChanged(s: Editable?) { diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/AboutFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/AboutFragment.kt index 86819cb..937db87 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/AboutFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/AboutFragment.kt @@ -13,27 +13,12 @@ package com.example.hpostesting.presentation.dashboard -import android.content.Context -import android.content.SharedPreferences -import android.os.BatteryManager import android.os.Bundle -import android.util.Log -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.fragment.app.activityViewModels -import com.example.hpostesting.data.constant.Constants -import com.example.hpostesting.data.constant.DataHolder -import com.example.hpostesting.data.model.patient.HemoCubeTestData -import com.example.hpostesting.presentation.adapter.OfflineUserListAdapter -import com.example.hpostesting.presentation.adapter.UserListAdapter -import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel -import com.example.hpostesting.presentation.testRight.TestRightViewModel -import `in`.sminnovations.hpostesting.R +import androidx.fragment.app.Fragment import `in`.sminnovations.hpostesting.databinding.FragmentAboutBinding -import `in`.sminnovations.hpostesting.databinding.FragmentActivitiesBinding -import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding class AboutFragment : Fragment() { private lateinit var binding: FragmentAboutBinding diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt index 0ed1103..963faba 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt @@ -23,7 +23,6 @@ import android.os.Build import android.os.Bundle import android.util.Log import android.view.Menu -import android.widget.Toast import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.content.FileProvider @@ -54,7 +53,7 @@ import java.io.File import java.security.MessageDigest import javax.inject.Inject -interface NatsMessageCallback { +fun interface NatsMessageCallback { fun onMessageReceived(topic: String, message: String) } @@ -77,7 +76,6 @@ class DashboardActivity : AppCompatActivity(), IDataCollector { lateinit var nats: NatsManager private var downloadId: Long = 0 - // TODO: Remove hemocube viewmodel private val hemocubeViewModel: HemoCubeViewModel by viewModels() override fun attachBaseContext(newBase: Context?) { @@ -211,7 +209,10 @@ class DashboardActivity : AppCompatActivity(), IDataCollector { var apk = it val file = File(getExternalFilesDir("Downloads"), "update.apk") - file.setReadable(true, false) + val isReadable = file.setReadable(true, false) + if (!isReadable) { + Log.w(TAG, "Failed to set file readable") + } // Write APK to file apk.byteStream().use { input -> @@ -291,7 +292,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector { return actualChecksum.equals(expectedChecksum, ignoreCase = true) } private fun installApk(file: File) { - val pInfo = baseContext.packageManager.getPackageInfo(baseContext.packageName, 0) + baseContext.packageManager.getPackageInfo(baseContext.packageName, 0) val uri: Uri = FileProvider.getUriForFile( this, "${BuildConfig.APPLICATION_ID}.fileprovider", @@ -377,11 +378,11 @@ class DashboardActivity : AppCompatActivity(), IDataCollector { // } } - private fun createDeviceUpdateRequestData(): DeviceUpdateRequest { - return DeviceUpdateRequest( - serial_no = sharedPreferences.getString(Constants.DEVICE_ID, "") - ) - } +// private fun createDeviceUpdateRequestData(): DeviceUpdateRequest { +// return DeviceUpdateRequest( +// serial_no = sharedPreferences.getString(Constants.DEVICE_ID, "") +// ) +// } private fun getAppVersion(context: Context): String { return try { val pInfo = context.packageManager.getPackageInfo(context.packageName, 0) diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt index ed6afd6..ae7637d 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt @@ -13,25 +13,18 @@ package com.example.hpostesting.presentation.dashboard -import android.annotation.SuppressLint import android.app.AlertDialog import android.app.DownloadManager import android.content.BroadcastReceiver import android.content.Context import android.content.Context.BATTERY_SERVICE -import android.content.Context.RECEIVER_EXPORTED import android.content.DialogInterface import android.content.Intent -import android.content.IntentFilter import android.content.SharedPreferences -import android.net.ConnectivityManager -import android.net.NetworkCapabilities import android.net.Uri import android.os.BatteryManager import android.os.Build import android.os.Bundle -import android.os.Environment -import android.provider.ContactsContract.Data import android.provider.Settings import android.util.Base64 import android.util.Log @@ -44,8 +37,6 @@ import androidx.appcompat.content.res.AppCompatResources import androidx.core.content.FileProvider import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.lifecycle.lifecycleScope -import androidx.navigation.findNavController import androidx.navigation.fragment.findNavController import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.DataHolder @@ -67,24 +58,21 @@ import com.example.hpostesting.presentation.testRight.TestRightViewModel import com.example.hpostesting.presentation.utils.DeviceCommunicationHandler import com.example.hpostesting.presentation.utils.UsbServiceListener import com.example.hpostesting.util.Result -import com.firebase.ui.firestore.FirestoreRecyclerOptions -import com.google.firebase.crashlytics.ktx.crashlytics -import com.google.firebase.firestore.Query import com.google.firebase.firestore.ktx.firestore import com.google.firebase.ktx.Firebase -import com.google.firebase.perf.ktx.performance import dagger.hilt.android.AndroidEntryPoint import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import okhttp3.ResponseBody import org.json.JSONObject import java.io.BufferedOutputStream import java.io.File import java.io.FileInputStream import java.io.FileOutputStream +import java.io.IOException import java.net.HttpURLConnection import java.net.URL import java.nio.charset.Charset @@ -96,8 +84,12 @@ import java.util.zip.ZipEntry import java.util.zip.ZipInputStream import kotlin.properties.Delegates + @AndroidEntryPoint class HomeFragment : Fragment() { + private val errorMsg = "Error fetching device data" + private val docNotExist= "Document does not exist." + private val ioScope = CoroutineScope(Dispatchers.IO) private var wasConnected = false private var isRegistered = false private var downloadId: Long = 0 @@ -130,140 +122,110 @@ class HomeFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") { - binding.labelQuickCapture.visibility = View.VISIBLE - binding.btnQuickCapture.visibility = View.VISIBLE - } + setupInitialUI() + setupObservers() + setupClickListeners() + initializeRequiredData() + } - getDeviceId() - checkUnprocessedCSVData() - //checkForUpdate() + private fun setupInitialUI() { + if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") { + binding.apply { + labelQuickCapture.visibility = View.VISIBLE + btnQuickCapture.visibility = View.VISIBLE + } + } + } + + private fun setupObservers() { viewModel.allUserData.observe(viewLifecycleOwner) { userData -> deleteIncompleteRegistrations(userData) } - // getLocationIP() - hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData -> - deleteHemoCubeIncompleteRegistrations(userData) - if (userData.isNotEmpty()) { - val userList = mutableListOf() - userData.forEach { - if (it.testStatus == false) { - userList.add(it) - }else if(it.testStatus == true){ - userList.removeAll(userData) - } - if (timeDifference(it.incubationTime) >= 50){ - userList.removeAll(userData) - } - } - val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager - val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) - adapter = OfflineUserListAdapter(binding.root, batLevel,"Home") - adapter.differ.submitList(userList) - binding.rvOrderOffline.adapter = adapter + hemoCubeViewModel.apply { + allUserData.observe(viewLifecycleOwner) { userData -> + deleteHemoCubeIncompleteRegistrations(userData) + updateRecyclerView(userData) + updateCSVButtonVisibility(userData) + } + + fireBaseBulkUpload.observe(viewLifecycleOwner) { result -> + handleFirebaseUploadResult(result) } } -// hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) { deviceData -> -// val devicelist = mutableListOf() -// if (deviceData != null) { -// devicelist.add(DeviceData(deviceData.deviceId)) -// } -// -// } + } + private fun updateRecyclerView(userData: List) { + if (userData.isNotEmpty()) { + val userList = userData.filter { + it.testStatus == false && timeDifference(it.incubationTime) < 50 + }.toMutableList() - hemoCubeViewModel.fireBaseBulkUpload.observe(viewLifecycleOwner) { result -> - if (result == "Success") { - Toast.makeText( - requireContext(), R.string.test_upload, Toast.LENGTH_SHORT - ).show() + val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager + val batLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) + + adapter = OfflineUserListAdapter(binding.root, batLevel, "Home") + adapter.differ.submitList(userList) + binding.rvOrderOffline.adapter = adapter + } + } + + private fun handleFirebaseUploadResult(result: String) { + when (result) { + "Success" -> { + Toast.makeText(requireContext(), R.string.test_upload, Toast.LENGTH_SHORT).show() hemoCubeViewModel.fireBaseBulkUpload.postValue("Done") } - if (result == "Error") { - Toast.makeText(requireContext(), R.string.test_upload_failed, Toast.LENGTH_SHORT) - .show() + "Error" -> { + Toast.makeText(requireContext(), R.string.test_upload_failed, Toast.LENGTH_SHORT).show() } } -// binding.btnLogout.setOnClickListener { -// logoutUser(requireContext()) -// } + } - binding.btnLogout1.setOnClickListener { - logoutUser(requireContext()) - } + private fun updateCSVButtonVisibility(userData: List) { + val btnSaveLocalVisibility = if (userData.any { it.testStatus == true }) View.VISIBLE else View.GONE + binding.downloadCSV.visibility = btnSaveLocalVisibility + } -// binding.uploadData.setOnClickListener { -//// showUploadDialog(requireContext()) -// } - hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData -> -// if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") { -// -// }else{ -// binding.downloadCSV.visibility = View.GONE -// } - val btnSaveLocalVisibility = - if (userData.any { it.testStatus == true }) View.VISIBLE else View.GONE - binding.downloadCSV.visibility = btnSaveLocalVisibility - binding.downloadCSV.setOnClickListener { - if (btnSaveLocalVisibility == View.VISIBLE) { - // Execute the action when the button is visible (testStatus is true for at least one user) + private fun setupClickListeners() { + binding.apply { + btnLogout1.setOnClickListener { + logoutUser(requireContext()) + } + + btnNewKitoffline.setOnClickListener { + DataHolder.selectedTest = null + val intent = Intent(requireContext(), KitScanActivity::class.java).apply { + putExtra("fromWhere", "Home") + } + startActivity(intent) + } + + btnQuickCapture.setOnClickListener { + with(sharedPreference.edit()) { + putBoolean(Constants.QUICK_CAPTURE, true) + apply() + } + DataHolder.quickCapture = true + DataHolder.hemoCubeTestData = HemoCubeTestData() + startActivity(Intent(requireContext().applicationContext, AssuranceControlsActivity::class.java)) + } + + downloadCSV.setOnClickListener { + if (downloadCSV.visibility == View.VISIBLE) { showDownloadDialog(requireContext()) } else { - // Handle the case when the button is not visible - Toast.makeText( - requireContext(), - "No test details stored locally", - Toast.LENGTH_SHORT - ).show() + Toast.makeText(requireContext(), "No test details stored locally", Toast.LENGTH_SHORT).show() } } } + } - -// binding.btnNewKit.setOnClickListener { -// with(sharedPreference.edit()) { -// putString(Constants.KIT_NUMBER, "") -// putInt(Constants.KIT_COUNT, 0) -// apply() -// } -// startActivity(Intent(requireContext(), KitScanActivity::class.java)) -// // requireActivity().finish() -// } - - - binding.btnNewKitoffline.setOnClickListener { -// with(sharedPreference.edit()) { -// putString(Constants.KIT_NUMBER, "") -// putInt(Constants.KIT_COUNT, 0) -// apply() -// } - DataHolder.selectedTest = null - val intent = Intent(requireContext(), KitScanActivity::class.java) - intent.putExtra("fromWhere","Home") - startActivity(intent) - // requireActivity().finish() - } - binding.btnQuickCapture.setOnClickListener { - with(sharedPreference.edit()) { - putBoolean(Constants.QUICK_CAPTURE, true) - apply() - } - DataHolder.quickCapture = true - DataHolder.hemoCubeTestData = HemoCubeTestData() - - val i = Intent( - requireContext().applicationContext, AssuranceControlsActivity::class.java - ) - startActivity(i) - } - - binding.downloadCSV.setOnClickListener { - showDownloadDialog(requireContext()) - } - //calling network change listener + @RequiresApi(Build.VERSION_CODES.P) + private fun initializeRequiredData() { + getDeviceId() + checkUnprocessedCSVData() checkNetworkStatus() - } // private fun getLocationIP() { // try { @@ -292,123 +254,55 @@ class HomeFragment : Fragment() { @RequiresApi(Build.VERSION_CODES.P) private fun checkNetworkStatus() { hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isConnected -> - // Toast.makeText(requireContext(),"connected"+isConnected+wasConnected, Toast.LENGTH_SHORT).show() - if(isConnected){ - binding.tvTitleNoInternet.text = "Please enter the user id and select blood group to start the test." - binding.internetIcon.setImageDrawable(AppCompatResources.getDrawable(requireContext(),R.drawable.internet)) - binding.internetNotAvailableCL.visibility = View.VISIBLE - }else{ - binding.internetIcon.setImageDrawable(AppCompatResources.getDrawable(requireContext(),R.drawable.off)) - binding.tvTitleNoInternet.text = getString(R.string.internet_not_available_please_enter_the_user_id_manually) - binding.internetNotAvailableCL.visibility = View.VISIBLE - } + updateInternetUIState(isConnected) + if (isConnected != wasConnected) { - if (isConnected) { - binding.tvTitleNoInternet.text = "Please enter the user id and select blood group to start the test." - //binding.internetAvailableCL.visibility = View.VISIBLE - binding.internetIcon.setImageDrawable(AppCompatResources.getDrawable(requireContext(),R.drawable.internet)) - binding.internetNotAvailableCL.visibility = View.VISIBLE - binding.pendingTest.visibility = View.GONE - setUserId() - // loadUserData() - // setSearch() - //checkForLocalDBData() - if (Constants.MOLBIO_INTEGRATION) { - checkForTokenAndUpdate() - } - // Now re-subscribe to allUserData - /* hemoCubeViewModel.allLocalData.observe(viewLifecycleOwner) { originalUserDataList -> - - Log.d("LOCAL_DB OBSERVE", "OBSERVE CALLED") - - val resultList = MolbioV2ResultRequest(mutableListOf()) - originalUserDataList.forEach { userData -> - Log.d( - ": USER DATA", - originalUserDataList.count().toString() + " : " + userData._id - ) - var accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString() - // Upload results after processing all userData to avoid duplicates and ensure all modifications are done - if(accessToken.isNotEmpty()) { - if (!userData.molbioFlag && isTokenAvailable && Constants.MOLBIO_INTEGRATION) { - val currentTimeFormatted = SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ssZZZZZ", - Locale.getDefault() - ).format(Calendar.getInstance().time) - val bufferIntensityThreshold = - Constants.BUFFER_INTENSITY_THRESHOLDS[userData.deviceId]?.toString() - ?: "defaultThreshold" // Handle possible nulls safely - resultList.results?.add( - MolbioV2Result( - rawData = userData, - analysisId = userData._id, - analysisDate = currentTimeFormatted, - analysisStatus = userData.classificationResult - ?: "defaultStatus", // Handle possible nulls - thresholds = bufferIntensityThreshold, - interpretation = userData.classificationResult - ?: "defaultInterpretation", // Handle possible nulls - testId = userData._id, - testTime = currentTimeFormatted, - collectionTime = currentTimeFormatted, - expiryTime = currentTimeFormatted - ) - ) - } - } - } - Log.d("USER DATA LIST SIZE", resultList.results?.count().toString()) - - resultList.results?.forEach { result -> - val userData = result.rawData - Log.d("UserData", userData.toString()) - if (userData != null) { - if (!userData.localFlag) { - hemoCubeViewModel.bulkAddResultTestToDb(userData) - - } - } - } - resultList.results?.forEach { result -> - result.rawData?.let { sanitizeDoubleValues(it) } - } - - // Then, check if there are any results to upload. - if (resultList.results?.isNotEmpty() == true) { - hemoCubeViewModel.uploadResult(resultList) - Log.d("resultcount1", "Uploading sanitized results") - } - - }*/ - if(Constants.MOLBIO_INTEGRATION){ - hemoCubeViewModel.sendDataToMolbio() - } - if(Constants.FIREBASE_INTEGRATION) { - hemoCubeViewModel.sendDataToFirebase() - } - - } else { - binding.tvTitleNoInternet.text = getString(R.string.internet_not_available_please_enter_the_user_id_manually) - // binding.internetAvailableCL.visibility = View.GONE - binding.internetIcon.setImageDrawable(AppCompatResources.getDrawable(requireContext(),R.drawable.off)) - binding.pendingTest.visibility = View.GONE - binding.internetNotAvailableCL.visibility = View.VISIBLE - setUserId() - } + handleConnectionStateChange(isConnected) wasConnected = isConnected - }else{ - if(!wasConnected){ - binding.internetIcon.setImageDrawable(AppCompatResources.getDrawable(requireContext(),R.drawable.off)) - binding.tvTitleNoInternet.text = getString(R.string.internet_not_available_please_enter_the_user_id_manually) - // binding.internetAvailableCL.visibility = View.GONE - binding.pendingTest.visibility = View.GONE - binding.internetNotAvailableCL.visibility = View.VISIBLE - setUserId() - } + } else if (!wasConnected) { + updateInternetUIState(false) + setUserId() } } } + private fun updateInternetUIState(isConnected: Boolean) { + binding.apply { + internetIcon.setImageDrawable( + AppCompatResources.getDrawable( + requireContext(), + if (isConnected) R.drawable.internet else R.drawable.off + ) + ) + tvTitleNoInternet.text = if (isConnected) { + "Please enter the user id and select blood group to start the test." + } else { + getString(R.string.internet_not_available_please_enter_the_user_id_manually) + } + internetNotAvailableCL.visibility = View.VISIBLE + } + } + + @RequiresApi(Build.VERSION_CODES.P) + private fun handleConnectionStateChange(isConnected: Boolean) { + binding.pendingTest.visibility = View.GONE + + if (isConnected) { + updateInternetUIState(true) + setUserId() + if (Constants.MOLBIO_INTEGRATION) { + checkForTokenAndUpdate() + hemoCubeViewModel.sendDataToMolbio() + } + if (Constants.FIREBASE_INTEGRATION) { + hemoCubeViewModel.sendDataToFirebase() + } + } else { + updateInternetUIState(false) + setUserId() + } + } + @RequiresApi(Build.VERSION_CODES.P) private fun checkForTokenAndUpdate() { var accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString() @@ -420,58 +314,63 @@ class HomeFragment : Fragment() { val target = File(requireContext().getExternalFilesDir(null), "HPOSDocuments") val file = File(target, "credentials.txt") //this file contains userID and password to communicate with API. - if (userID.isNotEmpty() && password.isNotEmpty()) { - Log.d("istoken", isTokenAvailable.toString()) - if (!isTokenAvailable) { - Log.d("istoken1", isTokenAvailable.toString()) - callLogin(userID, password) - // hemoCubeViewModel.login(createLoginRequestData(userID, password)) - - //isTokenAvailable = true - - } else if (isTokenAvailable) { - Log.d("istoken7", isTokenAvailable.toString()) - if (isTokenExpired(accessToken)) { - Log.d("istoken8", isTokenAvailable.toString()) + when { + userID.isNotEmpty() && password.isNotEmpty() -> { + Log.d("istoken", isTokenAvailable.toString()) + if (!isTokenAvailable) { + Log.d("istoken1", isTokenAvailable.toString()) callLogin(userID, password) - // hemoCubeViewModel.login(createLoginRequestData(userID, password)) - //hemoCubeViewModel.startPeriodicCheckUpdate() - }else{ - hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData()) + // hemoCubeViewModel.login(createLoginRequestData(userID, password)) + + //isTokenAvailable = true + + } else if (isTokenAvailable) { + Log.d("istoken7", isTokenAvailable.toString()) + if (isTokenExpired(accessToken)) { + Log.d("istoken8", isTokenAvailable.toString()) + callLogin(userID, password) + // hemoCubeViewModel.login(createLoginRequestData(userID, password)) + //hemoCubeViewModel.startPeriodicCheckUpdate() + }else{ + hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData()) + } + //isTokenAvailable = true + // hemoCubeViewModel.startPeriodicCheckUpdate() } - //isTokenAvailable = true - // hemoCubeViewModel.startPeriodicCheckUpdate() } - } else if (userID == "deviceIDAPI" && password == "devicePasswordAPI" && deviceId.isNotEmpty()) { - fetchDeviceCredentials() - } else if (file.exists()) {// change back without! - val encryptedString = file.readText() - val encryptionKey = - Settings.Secure.getString(context?.contentResolver, Settings.Secure.ANDROID_ID) - val decryptedMessage: String = Encryption.decrypt(encryptedString, encryptionKey) - val credentials = decryptedMessage.split("\n") - userID = credentials[0] - password = credentials[1] - Toast.makeText(context, "DECRYPTED: $credentials", Toast.LENGTH_SHORT).show() - if (!isTokenAvailable) { - callLogin(userID, password) - //hemoCubeViewModel.login(createLoginRequestData(userID, password)) + userID == "deviceIDAPI" && password == "devicePasswordAPI" && deviceId.isNotEmpty() -> { + fetchDeviceCredentials() } - else if (isTokenAvailable) { - //hemoCubeViewModel.startPeriodicCheckUpdate() - if (isTokenExpired(accessToken)) { + file.exists() -> {// change back without! + val encryptedString = file.readText() + val encryptionKey = + Settings.Secure.getString(context?.contentResolver, Settings.Secure.ANDROID_ID) + val decryptedMessage: String = Encryption.decrypt(encryptedString, encryptionKey) + val credentials = decryptedMessage.split("\n") + userID = credentials[0] + password = credentials[1] + Toast.makeText(context, "DECRYPTED: $credentials", Toast.LENGTH_SHORT).show() + if (!isTokenAvailable) { callLogin(userID, password) //hemoCubeViewModel.login(createLoginRequestData(userID, password)) - }else{ - hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData()) + } + else if (isTokenAvailable) { + //hemoCubeViewModel.startPeriodicCheckUpdate() + if (isTokenExpired(accessToken)) { + callLogin(userID, password) + //hemoCubeViewModel.login(createLoginRequestData(userID, password)) + }else{ + hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData()) + } } } - } else { - Toast.makeText( - requireContext(), - "Contact Help and get your device provision done", - Toast.LENGTH_SHORT - ).show() + else -> { + Toast.makeText( + requireContext(), + "Contact Help and get your device provision done", + Toast.LENGTH_SHORT + ).show() + } } hemoCubeViewModel.loginResponse.observe(viewLifecycleOwner) { response -> @@ -498,10 +397,12 @@ class HomeFragment : Fragment() { } is Result.Loading -> { - +//nothing } - else -> {} + else -> { + //nothing + } } } @@ -535,7 +436,9 @@ class HomeFragment : Fragment() { } } - else -> {} + else -> { + //nothing + } } } @@ -562,10 +465,12 @@ class HomeFragment : Fragment() { } is Result.Loading -> { - + //nothing } - else -> {} + else -> { + //nothing + } } } @@ -624,9 +529,11 @@ class HomeFragment : Fragment() { } is Result.Loading -> { + //nothing } else -> { + //nothing } } } @@ -670,10 +577,12 @@ class HomeFragment : Fragment() { } is Result.Loading -> { - +//nothing } - else -> {} + else -> { + //nothing + } } } @@ -682,7 +591,7 @@ class HomeFragment : Fragment() { private fun isTokenExpired(token: String): Boolean { - if (token.isNotEmpty()) { + return if (token.isNotEmpty()) { val parts = token.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() val decodedPayload = String(Base64.decode(parts[1], Base64.DEFAULT)) val jsonPayload = JSONObject(decodedPayload) @@ -690,9 +599,9 @@ class HomeFragment : Fragment() { val exp = jsonPayload.optLong("exp", 0) val currentTimeSeconds = System.currentTimeMillis() / 1000 - return exp <= currentTimeSeconds + exp <= currentTimeSeconds } else { - return false + false } } @@ -768,17 +677,20 @@ class HomeFragment : Fragment() { private fun unzip(zipFilePath: String, destDirectory: String) { val destDir = File(destDirectory) if (!destDir.exists()) { - destDir.mkdir() + val created = destDir.mkdirs() + if (!created) { + throw IOException("Failed to create directory: $destDir") + } } ZipInputStream(FileInputStream(zipFilePath)).use { zipIn -> var entry: ZipEntry? = zipIn.nextEntry while (entry != null) { val filePath = destDirectory + File.separator + entry.name - if (!entry.isDirectory) { + if (!entry.isDirectory()) { // Add parentheses for method call extractFile(zipIn, filePath) } else { val dir = File(filePath) - dir.mkdir() + dir.mkdirs() } zipIn.closeEntry() entry = zipIn.nextEntry @@ -815,27 +727,23 @@ class HomeFragment : Fragment() { // ) // findNavController().navigate(R.id.action_nav_home_to_mainActivity) if (userId.length >= 5 && bloodGroup.isNotEmpty() && age.isNotEmpty()) { - lifecycleScope.launch { + ioScope.launch { // Add user first, ensuring it's done before fetching the user - withContext(Dispatchers.IO) { hemoCubeViewModel.addUser( HemoCubeTestData( _id = userId, age = age, bloodGroup = bloodGroup, incubationTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() + resources.getString(R.string.DateTimeFormat), Locale.getDefault() ).format(Calendar.getInstance().time).toString() ) ) - } + // Now fetch the user after the addUser operation is complete - val user = withContext(Dispatchers.IO) { - hemoCubeViewModel.hemoCubeDao.getUserByID(userId) - } - - user?.let { + val user = hemoCubeViewModel.hemoCubeDao.getUserByID(userId) + user.let { DataHolder.selectedTest = UserData( sampleid = it.sampleid, _id = it._id, @@ -916,11 +824,11 @@ class HomeFragment : Fragment() { } ?: Log.e("fetchDeviceCredentials", "Failed to parse device data.") } else { - Log.e("fetchDeviceCredentials", "Document does not exist.") + Log.e("fetchDeviceCredentials", docNotExist) } } .addOnFailureListener { exception -> - Log.e("fetchDeviceCredentials", "Error fetching device data", exception) + Log.e("fetchDeviceCredentials", errorMsg, exception) } } catch (e: Exception) { Log.e("fetchDeviceCredentials", "Error in fetchDeviceCredentials", e) @@ -928,46 +836,46 @@ class HomeFragment : Fragment() { } - private fun loadUserData() { - try { - val dateFormat = SimpleDateFormat("yyyy-MM-dd") - val currentDate = Date() - val formattedDate = dateFormat.format(currentDate) - val query = Firebase.firestore.collection("patientData") - .whereGreaterThanOrEqualTo("createdAt", formattedDate) - .orderBy("createdAt", Query.Direction.DESCENDING) -// val query = Firebase.firestore.collection("patientData").whereEqualTo("testStatus", false) - query.get().addOnSuccessListener { - if (it.documents.isEmpty()) { - binding.pendingTest.visibility = View.VISIBLE - } else { - binding.pendingTest.visibility = View.GONE - } - } - val recyclerViewOptions = - FirestoreRecyclerOptions.Builder().setQuery(query, UserData::class.java) - .build() - - val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager - val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) - - rvAdapter = view?.let { - UserListAdapter( - requireContext(), - hemoCubeViewModel, - recyclerViewOptions, - it, - batLevel, - requireActivity() - ) - }!! - // binding.rvOrder.adapter = rvAdapter - - rvAdapter.startListening() - } catch (e: Exception) { - Firebase.crashlytics.recordException(e) - } - } +// private fun loadUserData() { +// try { +// val dateFormat = SimpleDateFormat("yyyy-MM-dd") +// val currentDate = Date() +// val formattedDate = dateFormat.format(currentDate) +// val query = Firebase.firestore.collection("patientData") +// .whereGreaterThanOrEqualTo("createdAt", formattedDate) +// .orderBy("createdAt", Query.Direction.DESCENDING) +//// val query = Firebase.firestore.collection("patientData").whereEqualTo("testStatus", false) +// query.get().addOnSuccessListener { +// if (it.documents.isEmpty()) { +// binding.pendingTest.visibility = View.VISIBLE +// } else { +// binding.pendingTest.visibility = View.GONE +// } +// } +// val recyclerViewOptions = +// FirestoreRecyclerOptions.Builder().setQuery(query, UserData::class.java) +// .build() +// +// val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager +// val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) +// +// rvAdapter = view?.let { +// UserListAdapter( +// requireContext(), +// hemoCubeViewModel, +// recyclerViewOptions, +// it, +// batLevel, +// requireActivity() +// ) +// }!! +// // binding.rvOrder.adapter = rvAdapter +// +// rvAdapter.startListening() +// } catch (e: Exception) { +// Firebase.crashlytics.recordException(e) +// } +// } private fun saveUserId(userId: String) { with(sharedPreference.edit()) { @@ -993,48 +901,48 @@ class HomeFragment : Fragment() { dialog.show() } - private fun getData(search: String?, field: String) { - val userSearchTrace = Firebase.performance.newTrace("user_search_trace") - userSearchTrace.start() - - search?.replaceFirstChar { - if (search.lowercase() - .startsWith(it.lowercase()) - ) it.titlecase(Locale.getDefault()) else it.toString() - - } - val currentDate = Date() - val dateFormat = SimpleDateFormat("yyyyMMdd") - val partition = dateFormat.format(currentDate) - val searchTerm = partition + search - val searchField = field + "Search" - val query = - Firebase.firestore.collection("patientData").orderBy(searchField).startAt(searchTerm) - .endAt(searchTerm + "\uf8ff") - query.get().addOnSuccessListener { - userSearchTrace.stop() - } - val recyclerViewOptions = - FirestoreRecyclerOptions.Builder().setQuery(query, UserData::class.java) - .build() - val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager - batLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) - - rvAdapter = view?.let { - UserListAdapter( - requireContext(), - hemoCubeViewModel, - recyclerViewOptions, - it, - batLevel, - requireActivity() - ) - }!! - // binding.rvOrder.adapter = rvAdapter - rvAdapter.startListening() - - userSearchTrace.stop() - } +// private fun getData(search: String?, field: String) { +// val userSearchTrace = Firebase.performance.newTrace("user_search_trace") +// userSearchTrace.start() +// +// search?.replaceFirstChar { +// if (search.lowercase() +// .startsWith(it.lowercase()) +// ) it.titlecase(Locale.getDefault()) else it.toString() +// +// } +// val currentDate = Date() +// val dateFormat = SimpleDateFormat("yyyyMMdd") +// val partition = dateFormat.format(currentDate) +// val searchTerm = partition + search +// val searchField = field + "Search" +// val query = +// Firebase.firestore.collection("patientData").orderBy(searchField).startAt(searchTerm) +// .endAt(searchTerm + "\uf8ff") +// query.get().addOnSuccessListener { +// userSearchTrace.stop() +// } +// val recyclerViewOptions = +// FirestoreRecyclerOptions.Builder().setQuery(query, UserData::class.java) +// .build() +// val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager +// batLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) +// +// rvAdapter = view?.let { +// UserListAdapter( +// requireContext(), +// hemoCubeViewModel, +// recyclerViewOptions, +// it, +// batLevel, +// requireActivity() +// ) +// }!! +// // binding.rvOrder.adapter = rvAdapter +// rvAdapter.startListening() +// +// userSearchTrace.stop() +// } // private fun setSearch() { // binding.searchProduct.setOnQueryTextListener(object : @@ -1079,7 +987,7 @@ class HomeFragment : Fragment() { // }) // } - private fun checkForLocalDBData() { + // private fun checkForLocalDBData() { // viewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> // val uploadDataVisibility = if (userDataList.isEmpty()) View.GONE else View.VISIBLE // binding.uploadData.visibility = uploadDataVisibility @@ -1096,7 +1004,7 @@ class HomeFragment : Fragment() { // if (bufferData.any { !it.localFlag }) View.VISIBLE else View.GONE // binding.uploadData.visibility = uploadDataVisibility // } - } +// } private fun checkUnprocessedCSVData() { hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> @@ -1110,36 +1018,36 @@ class HomeFragment : Fragment() { } } - private fun sanitizeDoubleValues(hemoCubeTestData: HemoCubeTestData): HemoCubeTestData { - hemoCubeTestData::class.java.declaredFields.forEach { field -> - if (field.type == Double::class.javaObjectType || field.type == Double::class.javaPrimitiveType) { - field.isAccessible = true - val value = field.get(hemoCubeTestData) as Double? - if (value != null && (value.isInfinite() || value.isNaN())) { - field.set(hemoCubeTestData, 0.0) // Replace with a suitable default value - } - } - } - return hemoCubeTestData - } +// private fun sanitizeDoubleValues(hemoCubeTestData: HemoCubeTestData): HemoCubeTestData { +// hemoCubeTestData::class.java.declaredFields.forEach { field -> +// if (field.type == Double::class.javaObjectType || field.type == Double::class.javaPrimitiveType) { +// field.isAccessible = true +// val value = field.get(hemoCubeTestData) as Double? +// if (value != null && (value.isInfinite() || value.isNaN())) { +// field.set(hemoCubeTestData, 0.0) // Replace with a suitable default value +// } +// } +// } +// return hemoCubeTestData +// } - private fun showUploadDialog(context: Context) { - val builder = AlertDialog.Builder(context) - builder.setTitle(R.string.upload_db_registration_title) - builder.setMessage(R.string.upload_db_registration_message) - - builder.setPositiveButton(R.string.upload) { dialog, _ -> -// uploadLocalDBData(dialog) - } - - builder.setNegativeButton(R.string.cancel) { dialog, _ -> - dialog.dismiss() - } - - val dialog = builder.create() - dialog.show() - } +// private fun showUploadDialog(context: Context) { +// val builder = AlertDialog.Builder(context) +// builder.setTitle(R.string.upload_db_registration_title) +// builder.setMessage(R.string.upload_db_registration_message) +// +// builder.setPositiveButton(R.string.upload) { _, _ -> +//// uploadLocalDBData(dialog) +// } +// +// builder.setNegativeButton(R.string.cancel) { dialog, _ -> +// dialog.dismiss() +// } +// +// val dialog = builder.create() +// dialog.show() +// } private fun showDownloadDialog(context: Context) { val builder = AlertDialog.Builder(context) @@ -1158,7 +1066,7 @@ class HomeFragment : Fragment() { dialog.show() } - private fun uploadLocalDBData(dialog: DialogInterface) { + // private fun uploadLocalDBData(dialog: DialogInterface) { // viewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> // if (userDataList.isEmpty()) { // dialog.dismiss() @@ -1216,7 +1124,7 @@ class HomeFragment : Fragment() { // } // dialog.dismiss() // } - } + // } private fun downloadLocalDBData(dialog: DialogInterface) { var csvDownloaded = false @@ -1306,19 +1214,19 @@ class HomeFragment : Fragment() { hemoCubeViewModel.downloadcertificate.removeObservers(viewLifecycleOwner) } - private fun downloadCsv() { - context?.let { context -> - val success = homeViewModel.getLocalUserDataForCsv(context) - if (success) { - // Provide feedback to the user if needed - Toast.makeText(context, "CSV file downloaded successfully", Toast.LENGTH_SHORT) - .show() - } else { - // Handle the case where CSV file generation failed - Toast.makeText(context, "Failed to download CSV file", Toast.LENGTH_SHORT).show() - } - } - } +// private fun downloadCsv() { +// context?.let { context -> +// val success = homeViewModel.getLocalUserDataForCsv(context) +// if (success) { +// // Provide feedback to the user if needed +// Toast.makeText(context, "CSV file downloaded successfully", Toast.LENGTH_SHORT) +// .show() +// } else { +// // Handle the case where CSV file generation failed +// Toast.makeText(context, "Failed to download CSV file", Toast.LENGTH_SHORT).show() +// } +// } +// } // private fun showDownloadDialog(context: Context) { // val builder = AlertDialog.Builder(context) @@ -1423,142 +1331,140 @@ class HomeFragment : Fragment() { return matchResult?.groups?.get(1)?.value ?: "" } - @SuppressLint("SuspiciousIndentation") - private fun checkForUpdate() { - try { - val db = Firebase.firestore - //val deviceId = deviceId - - val deviceRef = db.collection("deviceUpdate").document(Constants.DOCUMENT_ID_FOR_UPDATE) - - deviceRef.get().addOnSuccessListener { documentSnapshot -> - if (documentSnapshot.exists()) { - - val deviceData = - documentSnapshot.toObject(DeviceData::class.java) - - // deviceData?.let { data -> - - val deviceVersion = deviceData!!.deviceVersion - val deviceUpdateAvailableGlobal = deviceData.deviceUpdateAvailable - val updatePathGlobal = deviceData.updatePath +// @SuppressLint("SuspiciousIndentation") +// private fun checkForUpdate() { +// try { +// val db = Firebase.firestore +// //val deviceId = deviceId +// +// val deviceRef = db.collection("deviceUpdate").document(Constants.DOCUMENT_ID_FOR_UPDATE) +// +// deviceRef.get().addOnSuccessListener { documentSnapshot -> +// if (documentSnapshot.exists()) { +// +// val deviceData = +// documentSnapshot.toObject(DeviceData::class.java) +// +// // deviceData?.let { data -> +// +// val deviceVersion = deviceData!!.deviceVersion +// val deviceUpdateAvailableGlobal = deviceData.deviceUpdateAvailable +// val updatePathGlobal = deviceData.updatePath +// +// +// db.collection("devices").whereEqualTo("deviceId", deviceId).get() +// .addOnSuccessListener { documentSnapshotNew -> +// if (documentSnapshotNew.documents.isNotEmpty()) { +// documentSnapshotNew.documents.forEach { +// val documentIn = it.toObject(DeviceData::class.java) +// +// val globalUpdateIgnore = documentIn!!.globalUpdateIgnore +// val deviceUpdateAvailable = documentIn.deviceUpdateAvailable +// val globalUpdateDone = documentIn.globalUpdateDone +// val updatePath = documentIn.updatePath +// if (globalUpdateIgnore) { +// if (deviceUpdateAvailable) { +// val update = db.collection("devices").document(it.id) +// .update("deviceUpdateAvailable", false) +// update.addOnSuccessListener { +// Log.d( +// "HomeFragmentUpdate", +// "Device local update done" +// ) +// +// initiateUpdate(updatePath) +// }.addOnFailureListener { +// Log.e("fetchDeviceUpdate", "update fail.") +// } +// } else { +// Log.d( +// "HomeFragmentUpdate", +// "Device update not available" +// ) +// } +// } else { +// if (deviceUpdateAvailableGlobal && !globalUpdateDone) { +// val update = +// db.collection("devices").document(it.id) +// .update("globalUpdateDone", true) +// update.addOnSuccessListener { +// Log.d( +// "HomeFragmentUpdate", +// "Device global update done" +// ) +// +// initiateUpdate(updatePathGlobal) +// }.addOnFailureListener { +// Log.e( +// "fetchDeviceUpdate", +// "update fail." +// ) +// } +// } +// } +// } +// +// } else { +// Log.e("fetchDeviceUpdate", docNotExist) +// } +// }.addOnFailureListener { exception -> +// Log.e("fetchDeviceUpdate", errorMsg, exception) +// } +// +// +// // Toast.makeText(requireActivity()," true -version."+deviceVersion+"updatePath.."+updatePath,Toast.LENGTH_LONG).show() +// +// +// // Log for debugging +// Log.d( +// "fetchDeviceCredentials", +// "deviceVersion: $deviceVersion, Password: $deviceUpdateAvailableGlobal, updatePath: $updatePathGlobal" +// ) +// // ?: Log.e("fetchDeviceUpdate", "Failed to parse device data.") +// } else { +// Log.e("fetchDeviceUpdate", docNotExist) +// } +// } +// .addOnFailureListener { exception -> +// Log.e("fetchDeviceUpdate", errorMsg, exception) +// } +// } catch (e: Exception) { +// Log.e("fetchDeviceUpdate", "Error in fetchDeviceUpdate", e) +// } +// } - db.collection("devices").whereEqualTo("deviceId", deviceId).get() - .addOnSuccessListener { documentSnapshotNew -> - if (documentSnapshotNew.documents.isNotEmpty()) { - documentSnapshotNew.documents.forEach { - val documentIn = it.toObject(DeviceData::class.java) +// private fun initiateUpdate(url: String) { +// val apkUrl = url +// if (!isValidHttpUrl(apkUrl)) { +// return +// } +// +// val request = DownloadManager.Request(Uri.parse(apkUrl)) +// request.setTitle("App Update") +// request.setDescription("Downloading update...") +// request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) +// request.setDestinationInExternalFilesDir(requireActivity(), "Updates", "update.apk") +// +// val downloadManager = +// requireActivity().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager +// downloadId = downloadManager.enqueue(request) +// +// // Register a BroadcastReceiver to receive the download complete event +// val filter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE) +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { +// isRegistered = true +// requireActivity().registerReceiver(downloadReceiver, filter, RECEIVER_EXPORTED) +// } +// } - val globalUpdateIgnore = documentIn!!.globalUpdateIgnore - val deviceUpdateAvailable = documentIn.deviceUpdateAvailable - val globalUpdateDone = documentIn.globalUpdateDone - val updatePath = documentIn.updatePath - if (globalUpdateIgnore) { - if (deviceUpdateAvailable) { - val update = db.collection("devices").document(it.id) - .update("deviceUpdateAvailable", false) - update.addOnSuccessListener { - Log.d( - "HomeFragmentUpdate", - "Device local update done" - ) +// private fun extractApkUrl(responseBody: ResponseBody): String { +// return responseBody.string() +// } - initiateUpdate(updatePath) - }.addOnFailureListener { - Log.e("fetchDeviceUpdate", "update fail.") - } - } else { - Log.d( - "HomeFragmentUpdate", - "Device update not available" - ) - } - } else { - if (deviceUpdateAvailableGlobal) { - if (!globalUpdateDone) { - val update = - db.collection("devices").document(it.id) - .update("globalUpdateDone", true) - update.addOnSuccessListener { - Log.d( - "HomeFragmentUpdate", - "Device global update done" - ) - - initiateUpdate(updatePathGlobal) - }.addOnFailureListener { - Log.e( - "fetchDeviceUpdate", - "update fail." - ) - } - } - } - } - } - - } else { - Log.e("fetchDeviceUpdate", "Document does not exist.") - } - }.addOnFailureListener { exception -> - Log.e("fetchDeviceUpdate", "Error fetching device data", exception) - } - - - // Toast.makeText(requireActivity()," true -version."+deviceVersion+"updatePath.."+updatePath,Toast.LENGTH_LONG).show() - - - // Log for debugging - Log.d( - "fetchDeviceCredentials", - "deviceVersion: $deviceVersion, Password: $deviceUpdateAvailableGlobal, updatePath: $updatePathGlobal" - ) - // ?: Log.e("fetchDeviceUpdate", "Failed to parse device data.") - } else { - Log.e("fetchDeviceUpdate", "Document does not exist.") - } - } - .addOnFailureListener { exception -> - Log.e("fetchDeviceUpdate", "Error fetching device data", exception) - } - } catch (e: Exception) { - Log.e("fetchDeviceUpdate", "Error in fetchDeviceUpdate", e) - } - } - - - private fun initiateUpdate(url: String) { - val apkUrl = url - if (!isValidHttpUrl(apkUrl)) { - return - } - - val request = DownloadManager.Request(Uri.parse(apkUrl)) - request.setTitle("App Update") - request.setDescription("Downloading update...") - request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) - request.setDestinationInExternalFilesDir(requireActivity(), "Updates", "update.apk") - - val downloadManager = - requireActivity().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager - downloadId = downloadManager.enqueue(request) - - // Register a BroadcastReceiver to receive the download complete event - val filter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - isRegistered = true - requireActivity().registerReceiver(downloadReceiver, filter, RECEIVER_EXPORTED) - } - } - - private fun extractApkUrl(responseBody: ResponseBody): String { - return responseBody.string() - } - - private fun isValidHttpUrl(url: String): Boolean { - return url.startsWith("http://") || url.startsWith("https://") - } +// private fun isValidHttpUrl(url: String): Boolean { +// return url.startsWith("http://") || url.startsWith("https://") +// } private val downloadReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { @@ -1571,8 +1477,10 @@ class HomeFragment : Fragment() { private fun installApk() { val file = File(requireActivity().getExternalFilesDir("Updates"), "update.apk") - file.setReadable(true, false) // Ensure the file is readable - + //file.setReadable(true, false) // Ensure the file is readable + if (!file.setReadable(true, false)) { + throw SecurityException("Failed to set readable permission for update.apk") + } val pInfo = requireActivity().baseContext.packageManager.getPackageInfo( requireActivity().baseContext.packageName, 0 @@ -1611,7 +1519,7 @@ class HomeFragment : Fragment() { } private fun getPublicIpAddr(callback: (String) -> Unit) { - lifecycleScope.launch(Dispatchers.IO) { + ioScope.launch { try { val url = URL("https://api.ipify.org") val conn = url.openConnection() as HttpURLConnection @@ -1621,22 +1529,16 @@ class HomeFragment : Fragment() { val inputStream = conn.inputStream val ipAddress = inputStream.bufferedReader().use { it.readText() } inputStream.close() - withContext(Dispatchers.Main) { - callback(ipAddress) - } + callback(ipAddress) } else { - withContext(Dispatchers.Main) { - callback("fail") - } + callback("fail") } } finally { conn.disconnect() } } catch (e: Exception) { Log.e("getPublicIpAddr", e.toString()) - withContext(Dispatchers.Main) { - callback("fail") - } + callback("fail") } } } @@ -1699,24 +1601,24 @@ class HomeFragment : Fragment() { return diffMillis / (60 * 1000) // Convert milliseconds to minutes } - private fun isInternetAvailable(context: Context): Boolean { - val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - val network = connectivityManager.activeNetwork ?: return false - val activeNetwork = connectivityManager.getNetworkCapabilities(network) ?: return false - return when { - activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true - activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true - activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true - else -> false - } - } else { - @Suppress("DEPRECATION") - val networkInfo = connectivityManager.activeNetworkInfo ?: return false - @Suppress("DEPRECATION") - return networkInfo.isConnected - } - } +// private fun isInternetAvailable(context: Context): Boolean { +// val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { +// val network = connectivityManager.activeNetwork ?: return false +// val activeNetwork = connectivityManager.getNetworkCapabilities(network) ?: return false +// return when { +// activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true +// activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true +// activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true +// else -> false +// } +// } else { +// @Suppress("DEPRECATION") +// val networkInfo = connectivityManager.activeNetworkInfo ?: return false +// @Suppress("DEPRECATION") +// return networkInfo.isConnected +// } +// } } diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/SlideshowFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/SlideshowFragment.kt index 6c5eebe..8f954a4 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/SlideshowFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/SlideshowFragment.kt @@ -165,7 +165,7 @@ class PrefsFragment : PreferenceFragmentCompat(){ } } } else { - + //nothing } true } @@ -243,12 +243,12 @@ class PrefsFragment : PreferenceFragmentCompat(){ } - private fun switchCurrentServer(serverCode: String) { - Toast.makeText(requireContext(), "Switched to server: $serverCode", Toast.LENGTH_SHORT) - .show() - currentServerPreference.summary = "Current Server: $serverCode" - - } +// private fun switchCurrentServer(serverCode: String) { +// Toast.makeText(requireContext(), "Switched to server: $serverCode", Toast.LENGTH_SHORT) +// .show() +// currentServerPreference.summary = "Current Server: $serverCode" +// +// } private fun updateLanguage(context: Context, languageCode: String) { LanguageManager.persistLanguagePreference(context, languageCode) diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/LoginFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/LoginFragment.kt index 8a4b10a..b052a63 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/LoginFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/LoginFragment.kt @@ -13,17 +13,10 @@ package com.example.hpostesting.presentation.dashboard.ui -import com.example.hpostesting.util.SecureStorage import android.accounts.Account import android.accounts.AccountManager -import android.annotation.SuppressLint import android.content.Context import android.content.SharedPreferences -import android.location.Location -import android.location.LocationListener -import android.location.LocationManager -import android.net.ConnectivityManager -import android.net.NetworkCapabilities import android.os.Build import android.os.Bundle import android.util.Log @@ -38,14 +31,9 @@ import androidx.navigation.fragment.findNavController import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.util.AppInitializer +import com.example.hpostesting.util.SecureStorage import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.databinding.FragmentLoginBinding -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import java.net.HttpURLConnection -import java.net.URL -import java.util.Scanner class LoginFragment : Fragment() { @@ -210,106 +198,108 @@ class LoginFragment : Fragment() { } /** Check if we can get our location */ - @SuppressLint("MissingPermission") - fun checkLocation() { - // Get the location manager - val locationManager = requireActivity().getSystemService(Context.LOCATION_SERVICE) as LocationManager - val locationProviderWifi = LocationManager.NETWORK_PROVIDER - val locationProviderGPS = LocationManager.GPS_PROVIDER - val locationListenerNetwork: LocationListener - val locationListenerGPS: LocationListener - var gps_enabled = false - var network_enabled = false - - //check wifi - val connectivityManager = requireActivity().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - val mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI) - if (mWifi!!.isConnected) { - Log.d(TAG, "Wifi connected") - } - - //check gps and wifi availability - try { - gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) - } catch (ex: Exception) { - } - try { - network_enabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) - } catch (ex: Exception) { - } - if (!gps_enabled) { - Log.d(TAG, "GPS: Missing") - }else{ -// getPublicIpAddr { ipAddress -> -// // Do something with the ipAddress -// Log.d(TAG, "GPS: PRESENT"+ipAddress) + // @SuppressLint("MissingPermission") +// fun checkLocation() { +// // Get the location manager +// val locationManager = requireActivity().getSystemService(Context.LOCATION_SERVICE) as LocationManager +// val locationProviderWifi = LocationManager.NETWORK_PROVIDER +// val locationProviderGPS = LocationManager.GPS_PROVIDER +// val locationListenerNetwork: LocationListener +// val locationListenerGPS: LocationListener +// var gps_enabled = false +// var network_enabled = false +// +// //check wifi +// val connectivityManager = requireActivity().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager +// val mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI) +// if (mWifi!!.isConnected) { +// Log.d(TAG, "Wifi connected") +// } +// +// //check gps and wifi availability +// try { +// gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) +// } catch (ex: Exception) { +// //nothing +// } +// try { +// network_enabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) +// } catch (ex: Exception) { +// //nothing +// } +// if (!gps_enabled) { +// Log.d(TAG, "GPS: Missing") +// }else{ +//// getPublicIpAddr { ipAddress -> +//// // Do something with the ipAddress +//// Log.d(TAG, "GPS: PRESENT"+ipAddress) +//// } +// } +// if (!network_enabled) { +// Log.d(TAG, "Network: Missing") +// } +// +// /* Location change listeners */try { +// Log.d(TAG, "GPS: PRESENT TRy") +// // Define a listener that responds to gps location updates +// locationListenerGPS = object : LocationListener { +// override fun onLocationChanged(location: Location) { +// Log.d(TAG, "GPS: PRESENT loc") +// Log.d( +// TAG, +// "GPS: Latitude: " + location.latitude + ", Longitude = " + location.longitude +// ) +// } +// +// override fun onStatusChanged(provider: String, status: Int, extras: Bundle) { +// Log.d(TAG, "GP location found 1") +// } +// +// override fun onProviderEnabled(provider: String) { +// Log.d(TAG, "GP location found 2") +// } +// +// override fun onProviderDisabled(provider: String) { +// Log.d(TAG, "GP location found 3") +// } // } - } - if (!network_enabled) { - Log.d(TAG, "Network: Missing") - } - - /* Location change listeners */try { - Log.d(TAG, "GPS: PRESENT TRy") - // Define a listener that responds to gps location updates - locationListenerGPS = object : LocationListener { - override fun onLocationChanged(location: Location) { - Log.d(TAG, "GPS: PRESENT loc") - Log.d( - TAG, - "GPS: Latitude: " + location.latitude + ", Longitude = " + location.longitude - ) - } - - override fun onStatusChanged(provider: String, status: Int, extras: Bundle) { - Log.d(TAG, "GP location found 1") - } - - override fun onProviderEnabled(provider: String) { - Log.d(TAG, "GP location found 2") - } - - override fun onProviderDisabled(provider: String) { - Log.d(TAG, "GP location found 3") - } - } - locationManager.requestLocationUpdates(locationProviderGPS, 0, 0f, locationListenerGPS) - Log.d(TAG, "GPS: PRESENT Req") - } catch (e: Exception) { - Log.e(TAG, "Location Exception: " + e.message) - } - try { - // Define a listener that responds to wifi location updates - locationListenerNetwork = object : LocationListener { - override fun onLocationChanged(location: Location) { - Log.d( - TAG, - "NW: Latitude: " + location.latitude + ", Longitude = " + location.longitude - ) - } - - override fun onStatusChanged(provider: String, status: Int, extras: Bundle) { - Log.d(TAG, "location found 1") - } - - override fun onProviderEnabled(provider: String) { - Log.d(TAG, "location found 2") - } - - override fun onProviderDisabled(provider: String) { - Log.d(TAG, "location found 3") - } - } - locationManager.requestLocationUpdates( - locationProviderWifi, - 0, - 0f, - locationListenerNetwork - ) - } catch (e: Exception) { - Log.e(TAG, "NW Location Exception: " + e.message) - } - } +// locationManager.requestLocationUpdates(locationProviderGPS, 0, 0f, locationListenerGPS) +// Log.d(TAG, "GPS: PRESENT Req") +// } catch (e: Exception) { +// Log.e(TAG, "Location Exception: " + e.message) +// } +// try { +// // Define a listener that responds to wifi location updates +// locationListenerNetwork = object : LocationListener { +// override fun onLocationChanged(location: Location) { +// Log.d( +// TAG, +// "NW: Latitude: " + location.latitude + ", Longitude = " + location.longitude +// ) +// } +// +// override fun onStatusChanged(provider: String, status: Int, extras: Bundle) { +// Log.d(TAG, "location found 1") +// } +// +// override fun onProviderEnabled(provider: String) { +// Log.d(TAG, "location found 2") +// } +// +// override fun onProviderDisabled(provider: String) { +// Log.d(TAG, "location found 3") +// } +// } +// locationManager.requestLocationUpdates( +// locationProviderWifi, +// 0, +// 0f, +// locationListenerNetwork +// ) +// } catch (e: Exception) { +// Log.e(TAG, "NW Location Exception: " + e.message) +// } +// } // fun getPublicIpAddr(callback: (String) -> Unit) { // GlobalScope.launch(Dispatchers.IO) { // val url = URL("https://api.ipify.org") @@ -329,40 +319,40 @@ class LoginFragment : Fragment() { // } // } // } -private fun getPublicIpAddr(callback: (String) -> Unit) { - try { - GlobalScope.launch(Dispatchers.IO) { - val url = URL("https://api.ipify.org") - val conn = url.openConnection() as HttpURLConnection - try { - conn.connect() - if (conn.responseCode == HttpURLConnection.HTTP_OK) { - val scanner = Scanner(conn.inputStream) - scanner.useDelimiter("\\A") - if (scanner.hasNext()) { - val ipAddress = scanner.next() - callback(ipAddress) - } - } - } finally { - conn.disconnect() - } - } - }catch (e: Exception){ - Log.e(TAG,e.toString()) - } -} - @SuppressLint("NewApi") - private fun isInternetAvailable(): Boolean { - val connectivityManager = requireActivity().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - val network = connectivityManager.activeNetwork ?: return false - val networkCapabilities = connectivityManager.getNetworkCapabilities(network) ?: return false - return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) - } - - private fun checkUserName(userName: String): Boolean { - return userName.isNotEmpty() && userName.length >= 3 -} +//private fun getPublicIpAddr(callback: (String) -> Unit) { +// try { +// GlobalScope.launch(Dispatchers.IO) { +// val url = URL("https://api.ipify.org") +// val conn = url.openConnection() as HttpURLConnection +// try { +// conn.connect() +// if (conn.responseCode == HttpURLConnection.HTTP_OK) { +// val scanner = Scanner(conn.inputStream) +// scanner.useDelimiter("\\A") +// if (scanner.hasNext()) { +// val ipAddress = scanner.next() +// callback(ipAddress) +// } +// } +// } finally { +// conn.disconnect() +// } +// } +// }catch (e: Exception){ +// Log.e(TAG,e.toString()) +// } +//} +// @SuppressLint("NewApi") +// private fun isInternetAvailable(): Boolean { +// val connectivityManager = requireActivity().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager +// val network = connectivityManager.activeNetwork ?: return false +// val networkCapabilities = connectivityManager.getNetworkCapabilities(network) ?: return false +// return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) +// } +// +// private fun checkUserName(userName: String): Boolean { +// return userName.isNotEmpty() && userName.length >= 3 +//} private fun checkCenterName(centerName: String): Boolean { return centerName.isNotEmpty() && centerName.length >= 3 diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceActivity.kt index b8bc962..a0790d0 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceActivity.kt @@ -29,14 +29,13 @@ import android.os.Bundle import android.os.IBinder import android.util.Log import android.view.Menu -import android.view.MenuItem import android.widget.Toast import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.view.get -import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.presentation.utils.DeviceCommunicationHandler diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceFragment.kt index e67a9a8..f4b1f9b 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceinfo/DeviceFragment.kt @@ -89,6 +89,7 @@ class DeviceFragment : Fragment() { object : UsbServiceListener { @SuppressLint("SetTextI18n") override fun onUsbRead(data: ByteArray?) { + //nothing } override fun onUsbError(e: Exception?) { diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt index 684977e..898ad22 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionFragment.kt @@ -17,7 +17,6 @@ import android.content.Context import android.content.Intent import android.content.SharedPreferences import android.os.Bundle -import android.os.Environment import android.provider.Settings import android.util.Log import android.view.LayoutInflater @@ -27,20 +26,18 @@ import android.widget.Toast import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.lifecycle.MutableLiveData -import com.example.hpostesting.util.Result import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.encryption.Encryption -import com.example.hpostesting.presentation.utils.UsbServiceListener import com.example.hpostesting.presentation.dashboard.DashboardActivity -import com.google.android.gms.ads.identifier.AdvertisingIdClient +import com.example.hpostesting.presentation.utils.UsbServiceListener +import com.example.hpostesting.util.Result import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.ktx.Firebase import `in`.sminnovations.hpostesting.databinding.FragmentDeviceProvisionBinding import java.io.File -import java.io.FileOutputStream class DeviceProvisionFragment : Fragment() { private var resultData: String = "" @@ -175,7 +172,9 @@ class DeviceProvisionFragment : Fragment() { binding.btnSubmit.visibility = View.GONE } - else -> {} + else -> { + //Nothing + } } } viewModel.fireBaseUpload.observe(viewLifecycleOwner) { result -> @@ -193,8 +192,12 @@ class DeviceProvisionFragment : Fragment() { (activity as DeviceProvisionActivity).mService.sendAndListenToHemoCube( HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} - override fun onUsbError(e: Exception?) {} + override fun onUsbRead(data: ByteArray?) { + //nothing + } + override fun onUsbError(e: Exception?) { + //nothing + } }) } @@ -214,7 +217,9 @@ class DeviceProvisionFragment : Fragment() { } } - override fun onUsbError(e: Exception?) {} + override fun onUsbError(e: Exception?) { + //nothing + } }) } catch (e: Exception) { Firebase.crashlytics.recordException(e) diff --git a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt index 6ff2d46..7062774 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/deviceprovision/DeviceProvisionViewModel.kt @@ -59,7 +59,7 @@ class DeviceProvisionViewModel @Inject constructor( fun addDeviceProvisionDataToDb(data: DeviceData) { viewModelScope.launch { try { - when (val response = repository.getDeviceResponse(data)) { + when (repository.getDeviceResponse(data)) { is Response.Success -> { // Log.i("Testdb", "Data uploaded to Firestore successfully") fireBaseUpload.postValue("Successfully device response uploaded to firebase") @@ -70,7 +70,9 @@ class DeviceProvisionViewModel @Inject constructor( fireBaseUpload.postValue("Error") } - else -> {} + else -> { + //nothing + } } } catch (e: Exception) { // Log.e("Testdb", "Exception during data upload: ${e.message}") diff --git a/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsFragment.kt index c563b60..ed642df 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsFragment.kt @@ -103,10 +103,10 @@ class DiagnosticsFragment : Fragment() { val additionalDetails = AdditionalDetails( batteryLevel = batteryLevel, - batteryCapacity = batteryCapacity!!, - batteryMaxCapacity = batteryMaxCapacity!!, + batteryCapacity = batteryCapacity, + batteryMaxCapacity = batteryMaxCapacity, batteryTemperature = batteryTemperature, - batteryVoltage = batteryVoltage!! + batteryVoltage = batteryVoltage ) if(Constants.MOLBIO_INTEGRATION){ diagnosticsViewModel.deviceDiagnostics( @@ -149,7 +149,7 @@ class DiagnosticsFragment : Fragment() { response.data.data?.let { diagnosticsData -> - val batteryLevel = diagnosticsData.additionalDetails?.batteryLevel + diagnosticsData.additionalDetails?.batteryLevel } } else { @@ -169,9 +169,12 @@ class DiagnosticsFragment : Fragment() { ).show() } is Result.Loading -> { + //nothing } - else -> {} + else -> { + // nothing + } } } @@ -203,6 +206,7 @@ class DiagnosticsFragment : Fragment() { HemoCubeCommands.DIAGNOSTICS_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) { + //nothing } override fun onUsbError(e: Exception?) { @@ -216,6 +220,7 @@ class DiagnosticsFragment : Fragment() { HemoCubeCommands.READ_DAC_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) { + //nothing } override fun onUsbError(e: Exception?) { @@ -229,6 +234,7 @@ class DiagnosticsFragment : Fragment() { HemoCubeCommands.LOAD_DAC_VALUES, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) { + //nothing } override fun onUsbError(e: Exception?) { @@ -380,10 +386,8 @@ class DiagnosticsFragment : Fragment() { if (!ledDataMap.containsKey(ledName)) { ledDataMap[ledName] = mutableListOf() } - if ((ledDataMap[ledName]?.size ?: 0) < 7) { - if(xValue != 0.0){ - ledDataMap[ledName]?.add(xValue to yValue) - } + if ((ledDataMap[ledName]?.size ?: 0) < 7 && xValue != 0.0) { + ledDataMap[ledName]?.add(xValue to yValue) } // ledDataMap[ledName]?.add(xValue to yValue) } diff --git a/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsViewModel.kt index 465eb6b..4b4de95 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/diagnostics/DiagnosticsViewModel.kt @@ -46,7 +46,7 @@ class DiagnosticsViewModel @Inject constructor( fun addDiagnosticsDataToDb(data: DiagnosticsData) { viewModelScope.launch { try { - when (val response = repository.addDiagnostics(data)) { + when (repository.addDiagnostics(data)) { is Response.Success -> { // Log.i("Testdb", "Data uploaded to Firestore successfully") fireBaseUpload.postValue("Success") @@ -57,7 +57,9 @@ class DiagnosticsViewModel @Inject constructor( fireBaseUpload.postValue("Error") } - else -> {} + else -> { + //nothing + } } } catch (e: Exception) { // Log.e("Testdb", "Exception during data upload: ${e.message}") diff --git a/app/src/main/java/com/example/hpostesting/presentation/hb_test/HBTestFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/hb_test/HBTestFragment.kt index dec381c..a87b098 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hb_test/HBTestFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hb_test/HBTestFragment.kt @@ -27,14 +27,12 @@ import androidx.lifecycle.MutableLiveData import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.DataHolder import com.example.hpostesting.data.constant.HemoCubeCommands -import com.example.hpostesting.data.model.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.presentation.utils.UsbServiceListener import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.ktx.Firebase import `in`.sminnovations.hpostesting.R -import `in`.sminnovations.hpostesting.databinding.FragmentAutoDacBinding import `in`.sminnovations.hpostesting.databinding.FragmentHbTestBinding import java.text.SimpleDateFormat import java.util.Calendar @@ -193,6 +191,7 @@ class HBTestFragment : Fragment() { HemoCubeCommands.START_BUFFER_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) { + //nothing } override fun onUsbError(e: Exception?) { @@ -206,6 +205,7 @@ class HBTestFragment : Fragment() { HemoCubeCommands.START_SAMPLE, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) { + //nothing } override fun onUsbError(e: Exception?) { @@ -219,6 +219,7 @@ class HBTestFragment : Fragment() { HemoCubeCommands.PRINT_COMMAND, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) { + //nothing } override fun onUsbError(e: Exception?) { @@ -251,7 +252,7 @@ class HBTestFragment : Fragment() { if (stringData.contains("SNE")) { val slData = stringData.split(" ") if (slData.size > 1) { - val hardwareId = slData[1].trim() + ///val hardwareId = slData[1].trim() deviceId = extractV2HardwareId(resultData).toString() hBTestViewModel.messages.postValue("Place buffer and click below button to start test") // with(sharedPreferences.edit()) { diff --git a/app/src/main/java/com/example/hpostesting/presentation/hb_test/HBTestViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/hb_test/HBTestViewModel.kt index bf8b04b..13aa04e 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hb_test/HBTestViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hb_test/HBTestViewModel.kt @@ -60,7 +60,9 @@ class HBTestViewModel @Inject constructor( hemoCubeDao.updateTest(testDetails) } - else -> {} + else -> { + //nothing + } } } catch (e: Exception) { fireBaseUpload.postValue("Error") @@ -70,7 +72,7 @@ class HBTestViewModel @Inject constructor( fun addAutoDacDataToDb(data: DiagnosticsData) { viewModelScope.launch { try { - when (val response = repository.addDiagnostics(data)) { + when (repository.addDiagnostics(data)) { is Response.Success -> { fireBaseUpload.postValue("Success") } diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt index 61b9449..1c2ffc5 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt @@ -52,6 +52,11 @@ import kotlin.random.Random @Suppress("MemberVisibilityCanBePrivate") class HemoCubeFragment : Fragment() { + private val sickleCellDisease = "Sickle Cell Disease" + private val regEx = "\\s+(?=LB|LS)" + private val sickleCellTrait = "Sickle Cell Trait" + private val positiveBoderLine = "Positive for Sickle Cell. HPLC for Confirmation" + private val negativeBorderLine = "Negative Borderline" private var positiveBoderLine10mm1=Constants.positiveBoderLine10mm1 private var positiveBoderLine10mm2=Constants.positiveBoderLine10mm2 private var negativeBoderLine10mm1=Constants.negativeBoderLine10mm1 @@ -334,7 +339,7 @@ class HemoCubeFragment : Fragment() { hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result -> if (result == "Success") { uploadedToCloud = true - var accessToken = sharedPreferences.getString(Constants.ACCESS_TOKEN, "").toString() + //var accessToken = sharedPreferences.getString(Constants.ACCESS_TOKEN, "").toString() showToast(R.string.test_upload) if (Constants.MOLBIO_INTEGRATION) { hemoCubeViewModel.resultUpload.observe(viewLifecycleOwner) { @@ -366,7 +371,9 @@ class HemoCubeFragment : Fragment() { handleReadingFinish() } - else -> {} + else -> { + //nothing + } } } } else { @@ -394,7 +401,7 @@ class HemoCubeFragment : Fragment() { hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable -> apply { DataHolder.hemoCubeTestData?.let { - currentDeviceData?.coefficients?.let { coefficients -> + currentDeviceData?.coefficients?.let { _ -> // val coefficient1 = coefficients[0] // val coefficient2 = coefficients[1] // val result = coefficient1 * coefficient2 @@ -480,32 +487,32 @@ class HemoCubeFragment : Fragment() { } } - private fun showBufferAlertDialog() { - val title = "WARNING" - val message = getString(R.string.do_exist) - val negativeText = getString(R.string.no) - val positiveText = getString(R.string.yes) - - UIUtils.createAlertDialog(requireContext(), - title, - message, - negativeText, - positiveText, - object : MyDialogListener { - override fun onClickNegativeButton() { - startBufferProcess() - } - - override fun onClickPositiveButton() { - activity?.runOnUiThread { -// binding.btnPlacebuffer.visibility = View.GONE - binding.btnSamplestart.visibility = View.VISIBLE - binding.tvSubtitle4.text = getString(R.string.place_sample) - } - //isUsingExistingBuffer = true - } - }) - } +// private fun showBufferAlertDialog() { +// val title = "WARNING" +// val message = getString(R.string.do_exist) +// val negativeText = getString(R.string.no) +// val positiveText = getString(R.string.yes) +// +// UIUtils.createAlertDialog(requireContext(), +// title, +// message, +// negativeText, +// positiveText, +// object : MyDialogListener { +// override fun onClickNegativeButton() { +// startBufferProcess() +// } +// +// override fun onClickPositiveButton() { +// activity?.runOnUiThread { +//// binding.btnPlacebuffer.visibility = View.GONE +// binding.btnSamplestart.visibility = View.VISIBLE +// binding.tvSubtitle4.text = getString(R.string.place_sample) +// } +// //isUsingExistingBuffer = true +// } +// }) +// } private fun listenToHemoCube() { DataHolder.hemoCubeTestData = DataHolder.selectedTest?.toHemoCubeTestData() @@ -559,6 +566,7 @@ class HemoCubeFragment : Fragment() { HemoCubeCommands.LOAD_DAC_VALUES, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) { + //nothing } override fun onUsbError(e: Exception?) { @@ -854,7 +862,7 @@ class HemoCubeFragment : Fragment() { this.testStatusCode = TestStatus.FIRST_GAIN_PRINT_COMPLETED.code hemoCubeViewModel.messages.postValue("First air reading completed") - val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) + val resultLines = currentResultData.split(regEx.toRegex()) DataHolder.hemoCubeTestData?.apply { led1Air1 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led2Air1 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! @@ -872,7 +880,7 @@ class HemoCubeFragment : Fragment() { this.testStatusCode = TestStatus.SECOND_EMPTY_AIR_PRINT_COMPLETED.code hemoCubeViewModel.messages.postValue("Second air reading completed") - val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) + val resultLines = currentResultData.split(regEx.toRegex()) DataHolder.hemoCubeTestData?.apply { led1Air2 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led2Air2 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! @@ -890,7 +898,7 @@ class HemoCubeFragment : Fragment() { this.testStatusCode = TestStatus.FIRST_GAIN_PRINT_COMPLETED.code hemoCubeViewModel.messages.postValue("1.3X gain data gathered") - val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) + val resultLines = currentResultData.split(regEx.toRegex()) DataHolder.hemoCubeTestData?.apply { led1Gain1 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led2Gain1 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! @@ -909,7 +917,7 @@ class HemoCubeFragment : Fragment() { this.testStatusCode = TestStatus.SECOND_GAIN_PRINT_COMPLETED.code hemoCubeViewModel.messages.postValue("2X gain data gathered") - val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) + val resultLines = currentResultData.split(regEx.toRegex()) DataHolder.hemoCubeTestData?.apply { led1Gain2 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led2Gain2 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! @@ -928,7 +936,7 @@ class HemoCubeFragment : Fragment() { this.testStatusCode = TestStatus.FORTH_GAIN_PRINT_COMPLETED.code hemoCubeViewModel.messages.postValue("7.6X gain data gathered") - val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) + val resultLines = currentResultData.split(regEx.toRegex()) DataHolder.hemoCubeTestData?.apply { led1Gain4 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led2Gain4 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! @@ -1006,7 +1014,7 @@ class HemoCubeFragment : Fragment() { getString(R.string.data_collected_processing_data) ) - val resultLines = currentResultData.split("\\s+(?=LB|LS)".toRegex()) + val resultLines = currentResultData.split(regEx.toRegex()) var bufferIntensity = resultLines[1].split(' ')[1].trim() led1BufferForDevice = if (isUsingExistingBuffer) { sharedPreferences.getString(Constants.BUFFER_VALUE_1, "")?.toDoubleOrNull()!! @@ -1288,13 +1296,13 @@ class HemoCubeFragment : Fragment() { constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(0)?.get(1) fittedAbs4 = gradient?.times(led4Average)?.plus(constant!!)!! - val slope1 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(1)?.get(0) - val intercept1 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(1)?.get(1) - val calculatedHb1 = (led1Average - intercept1!!) / slope1!! + // val slope1 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(1)?.get(0) + // val intercept1 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(1)?.get(1) + //val calculatedHb1 = (led1Average - intercept1!!) / slope1!! - val slope2 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(3)?.get(0) - val intercept = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(3)?.get(1) - val calculatedHb2 = (led2Average - intercept!!) / slope2!! + // val slope2 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(3)?.get(0) + // val intercept = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(3)?.get(1) + //val calculatedHb2 = (led2Average - intercept!!) / slope2!! val slope3 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(2)?.get(0) val intercept3 = Constants.DEVICE_HB_PARAMETERS[deviceHardwareId]?.get(2)?.get(1) @@ -1438,13 +1446,13 @@ class HemoCubeFragment : Fragment() { fun reclassifyWithBorderlineMethod2(deviceRatio: Double?, deviceRatioClass: String?, led2Average: Double?): String { try { if (deviceRatio != null && led2Average != null) { - if (deviceRatioClass == "Negative Borderline") { + if (deviceRatioClass == negativeBorderLine) { return if (led2Average >= 0.15) "Borderline. Normal" else "Borderline. Sickle Cell Trait" } - if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") { + if (deviceRatioClass == positiveBoderLine) { return if (led2Average >= 0.19) "Borderline. Sickle Cell Trait" else @@ -1467,41 +1475,57 @@ class HemoCubeFragment : Fragment() { // hemoCubeViewModel.messages.postValue("post classification checks") if (deviceRatio != null && borderlineMetric != null) { if(cuvetteSize == "10mm"){ - if (deviceRatioClass == "Negative Borderline") { - if (borderlineMetric < negativeBoderLine10mm1){//1.34 - return "Sickle Cell Trait" - }else if(borderlineMetric > negativeBoderLine10mm2){ - return "Normal" - }else if(borderlineMetric > negativeBoderLine10mm1 && borderlineMetric < negativeBoderLine10mm2){ - return "Negative borderline. Confirm with HPLC" + if (deviceRatioClass == negativeBorderLine) { + when { + borderlineMetric < negativeBoderLine10mm1 -> {//1.34 + return sickleCellTrait + } + borderlineMetric > negativeBoderLine10mm2 -> { + return "Normal" + } + borderlineMetric > negativeBoderLine10mm1 && borderlineMetric < negativeBoderLine10mm2 -> { + return "Negative borderline. Confirm with HPLC" + } } } - if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") { - if (borderlineMetric < positiveBoderLine10mm1){//1.34 - return "Sickle Cell Disease" - }else if(borderlineMetric > positiveBoderLine10mm2){ - return "Sickle Cell Trait" - }else if(borderlineMetric > positiveBoderLine10mm1 && borderlineMetric < positiveBoderLine10mm2){ - return "Positive for Sickle Cell. Confirm with HPLC" + if (deviceRatioClass == positiveBoderLine) { + when { + borderlineMetric < positiveBoderLine10mm1 -> {//1.34 + return sickleCellDisease + } + borderlineMetric > positiveBoderLine10mm2 -> { + return sickleCellTrait + } + borderlineMetric > positiveBoderLine10mm1 && borderlineMetric < positiveBoderLine10mm2 -> { + return "Positive for Sickle Cell. Confirm with HPLC" + } } } }else if(cuvetteSize == "2mm"){ - if (deviceRatioClass == "Negative Borderline") { - if (borderlineMetric < negativeBoderLine2mm1){//1.34 - return "Sickle Cell Trait" - }else if(borderlineMetric > negativeBoderLine2mm2){ - return "Normal" - }else if(borderlineMetric > negativeBoderLine2mm1 && borderlineMetric < negativeBoderLine2mm2){ - return "Negative borderline. Confirm with HPLC" + if (deviceRatioClass == negativeBorderLine) { + when { + borderlineMetric < negativeBoderLine2mm1 -> {//1.34 + return sickleCellTrait + } + borderlineMetric > negativeBoderLine2mm2 -> { + return "Normal" + } + borderlineMetric > negativeBoderLine2mm1 && borderlineMetric < negativeBoderLine2mm2 -> { + return "Negative borderline. Confirm with HPLC" + } } } - if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") { - if (borderlineMetric < positiveBoderLine2mm1){//1.34 - return "Sickle Cell Disease" - }else if(borderlineMetric > positiveBoderLine2mm2){ - return "Sickle Cell Trait" - }else if(borderlineMetric > positiveBoderLine2mm1 && borderlineMetric < positiveBoderLine2mm2){ - return "Positive for Sickle Cell. Confirm with HPLC" + if (deviceRatioClass == positiveBoderLine) { + when { + borderlineMetric < positiveBoderLine2mm1 -> {//1.34 + return sickleCellDisease + } + borderlineMetric > positiveBoderLine2mm2 -> { + return sickleCellTrait + } + borderlineMetric > positiveBoderLine2mm1 && borderlineMetric < positiveBoderLine2mm2 -> { + return "Positive for Sickle Cell. Confirm with HPLC" + } } } } @@ -1522,13 +1546,13 @@ class HemoCubeFragment : Fragment() { return "Normal" } if (roundedRatio in 0.237..0.242) - return "Negative Borderline" + return negativeBorderLine if (roundedRatio in 0.242..0.318) - return "Sickle Cell Trait" + return sickleCellTrait if (roundedRatio >= 0.318 && roundedRatio < 0.356) - return "Positive for Sickle Cell. HPLC for Confirmation" + return positiveBoderLine if (roundedRatio in 0.356..0.7) - return "Sickle Cell Disease" + return sickleCellDisease } else { return "Invalid" } @@ -1548,16 +1572,16 @@ class HemoCubeFragment : Fragment() { return "Normal" } if (ratio in negativeBorderlineMin10mm..negativeBorderlineMax10mm){ - return "Negative Borderline" + return negativeBorderLine } if (ratio in sickleCellTraitMin10mm..sickleCellTraitMax10mm){ - return "Sickle Cell Trait" + return sickleCellTrait } if (ratio in positiveForSickleCellMin10mm..positiveForSickleCellMax10mm){//0.36 - return "Positive for Sickle Cell. HPLC for Confirmation" + return positiveBoderLine } if (ratio in sickleCellDiseaseMin10mm..sickleCellDiseaseMax10mm){ - return "Sickle Cell Disease" + return sickleCellDisease } }else if(cuvetteSize == "2mm"){ if (ratio in normalMin2mm..normalMax2mm) { @@ -1565,16 +1589,16 @@ class HemoCubeFragment : Fragment() { return "Normal" } if (ratio in negativeBorderlineMin2mm..negativeBorderlineMax2mm){ - return "Negative Borderline" + return negativeBorderLine } if (ratio in sickleCellTraitMin2mm..sickleCellTraitMax2mm){ - return "Sickle Cell Trait" + return sickleCellTrait } if (ratio in positiveForSickleCellMin2mm..positiveForSickleCellMax2mm){//0.36 - return "Positive for Sickle Cell. HPLC for Confirmation" + return positiveBoderLine } if (ratio in sickleCellDiseaseMin2mm..sickleCellDiseaseMax2mm){ - return "Sickle Cell Disease" + return sickleCellDisease } } @@ -1674,7 +1698,9 @@ class HemoCubeFragment : Fragment() { (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.CHECK_CUVETTE_COMMAND, object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} + override fun onUsbRead(data: ByteArray?) { + //nothing + } override fun onUsbError(e: Exception?) { hemoCubeViewModel.progressBar.postValue(false) @@ -1688,7 +1714,9 @@ class HemoCubeFragment : Fragment() { // } (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.START_BUFFER_COMMAND, object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} + override fun onUsbRead(data: ByteArray?) { + //nothing + } override fun onUsbError(e: Exception?) { hemoCubeViewModel.progressBar.postValue(false) @@ -1701,7 +1729,9 @@ class HemoCubeFragment : Fragment() { (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.START_SAMPLE, object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} + override fun onUsbRead(data: ByteArray?) { + //nothing + } override fun onUsbError(e: Exception?) { hemoCubeViewModel.progressBar.postValue(false) @@ -1715,7 +1745,9 @@ class HemoCubeFragment : Fragment() { (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.FIRST_GAIN_COMMAND, object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} + override fun onUsbRead(data: ByteArray?) { + //nothing + } override fun onUsbError(e: Exception?) { hemoCubeViewModel.progressBar.postValue(false) @@ -1728,7 +1760,9 @@ class HemoCubeFragment : Fragment() { (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.SECOND_GAIN_COMMAND, object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} + override fun onUsbRead(data: ByteArray?) { + //nothing + } override fun onUsbError(e: Exception?) { hemoCubeViewModel.progressBar.postValue(false) @@ -1736,25 +1770,29 @@ class HemoCubeFragment : Fragment() { }) } - private fun sendThirdGainCommand() { - hemoCubeViewModel.progressBar.postValue(true) - - (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.THIRD_GAIN_COMMAND, - object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} - - override fun onUsbError(e: Exception?) { - hemoCubeViewModel.progressBar.postValue(false) - } - }) - } +// private fun sendThirdGainCommand() { +// hemoCubeViewModel.progressBar.postValue(true) +// +// (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.THIRD_GAIN_COMMAND, +// object : UsbServiceListener { +// override fun onUsbRead(data: ByteArray?) { +// //nothing +// } +// +// override fun onUsbError(e: Exception?) { +// hemoCubeViewModel.progressBar.postValue(false) +// } +// }) +// } private fun sendForthGainCommand() { hemoCubeViewModel.progressBar.postValue(true) (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.FORTH_GAIN_COMMAND, object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} + override fun onUsbRead(data: ByteArray?) { + //nothing + } override fun onUsbError(e: Exception?) { hemoCubeViewModel.progressBar.postValue(false) @@ -1766,7 +1804,9 @@ class HemoCubeFragment : Fragment() { (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.CHECK_TEMP_COMMAND, object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} + override fun onUsbRead(data: ByteArray?) { + //nothing + } override fun onUsbError(e: Exception?) { hemoCubeViewModel.progressBar.postValue(false) @@ -1778,7 +1818,9 @@ class HemoCubeFragment : Fragment() { (activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.PRINT_COMMAND, object : UsbServiceListener { - override fun onUsbRead(data: ByteArray?) {} + override fun onUsbRead(data: ByteArray?) { + //nothing + } override fun onUsbError(e: Exception?) { hemoCubeViewModel.progressBar.postValue(false) diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt index b7e44a3..cbd8839 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt @@ -25,11 +25,8 @@ import androidx.lifecycle.viewModelScope import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.PeriodicWorkRequestBuilder 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.DataHolder import com.example.hpostesting.data.dao.HemoCubeBufferDao import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.datasource.LocalFileDataSource @@ -50,7 +47,11 @@ import com.example.hpostesting.data.model.updates.DeviceUpdateRequest import com.example.hpostesting.data.repository.Repository import com.example.hpostesting.domain.CheckUpdateWorker import com.example.hpostesting.domain.LogFileManager +import com.example.hpostesting.util.CsvWriter +import com.example.hpostesting.util.NetworkStatusLiveData +import com.example.hpostesting.util.Result import dagger.hilt.android.lifecycle.HiltViewModel +import `in`.sminnovations.hpostesting.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import okhttp3.Headers @@ -72,17 +73,18 @@ class HemoCubeViewModel @Inject constructor( private val repository: Repository, private val logFileManager: LogFileManager, private val localFileDataSource: LocalFileDataSource, - context: Context, + private val contextV: Context ) : ViewModel() { + private val successMsg = "Data uploaded to Firestore successfully" private var testUpload: Boolean = false var isServiceConnected = false val progressBar = MutableLiveData(false) private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() val messages = MutableLiveData() private val sharedPreference = - context.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) + contextV.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) - private val workManager = WorkManager.getInstance(context) + private val workManager = WorkManager.getInstance(contextV) // init { // startPeriodicCheckUpdate() @@ -103,7 +105,7 @@ class HemoCubeViewModel @Inject constructor( // 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 = NetworkStatusLiveData(contextV) val allUserData = hemoCubeDao.getAll() val allLocalData = hemoCubeDao.getAll() val allPendingUserToUpload = hemoCubeDao.getPendingUser() @@ -119,7 +121,7 @@ class HemoCubeViewModel @Inject constructor( private val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter -> - context.registerReceiver(null, ifilter) + contextV.registerReceiver(null, ifilter) } fun uploadHemoCubeResultToDatabase( @@ -149,7 +151,7 @@ class HemoCubeViewModel @Inject constructor( } // addResultTestToDb(quickCapture,isOnline) testDetails?.testTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() + contextV.resources.getString(R.string.DateTimeFormat), Locale.getDefault() ).format(Calendar.getInstance().time) testDetails?.localFlag = false hemoCubeDao.updateTest(testDetails!!) @@ -178,7 +180,7 @@ class HemoCubeViewModel @Inject constructor( } fireBaseUpload.postValue("Success") testDetails.reportUploadTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() + contextV.resources.getString(R.string.DateTimeFormat), Locale.getDefault() ).format(Calendar.getInstance().time) val currentTimeFormatted = SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssZZZZZ", @@ -306,15 +308,12 @@ class HemoCubeViewModel @Inject constructor( } } - - fun sendDataToFirebase() = viewModelScope.launch ( Dispatchers.IO ) { + fun sendDataToFirebase() = viewModelScope.launch (Dispatchers.IO) { val pendingData = hemoCubeDao.getFirebasePending() pendingData.forEach{ userData -> - if (userData != null) { - if (!userData.localFlag && userData.testStatus == true) { - bulkAddResultTestToDb(userData) - } + if (!userData.localFlag && userData.testStatus == true) { + bulkAddResultTestToDb(userData) } } if(testUpload){ @@ -361,7 +360,7 @@ class HemoCubeViewModel @Inject constructor( fun uploadLogs() = viewModelScope.launch { uploadLogs.postValue(Result.Loading()) - val logFile = logFileManager.createLogFile().let { file -> + logFileManager.createLogFile().let { file -> val requestBody = file?.asRequestBody("multipart/form-data".toMediaTypeOrNull()) val multipartFile = requestBody?.let { MultipartBody.Part.createFormData("logFile", file?.name, it) } @@ -386,7 +385,7 @@ class HemoCubeViewModel @Inject constructor( when (val response = repository.addTestToDatabaseforBufferCheck(bufferCheckData)) { is Response.Success -> { - Log.i("Testdb", "Data uploaded to Firestore successfully") + Log.i("Testdb", successMsg) fireBaseUpload.postValue("Success") bufferCheckData.localFlag = true hemoCubeBufferDao.insertAll(bufferCheckData) @@ -398,8 +397,6 @@ class HemoCubeViewModel @Inject constructor( bufferCheckData.localFlag = true hemoCubeBufferDao.insertAll(bufferCheckData) } - - else -> {} } } catch (e: Exception) { Log.e("Testdb", "Exception during data upload: ${e.message}") @@ -414,7 +411,7 @@ class HemoCubeViewModel @Inject constructor( fun bulkAddResultKitTestToDb(bufferCheckData: BufferCheckData) { viewModelScope.launch { bufferCheckData.reportUploadTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() + contextV.resources.getString(R.string.DateTimeFormat), Locale.getDefault() ).format(Calendar.getInstance().time) when (repository.addTestToDatabaseforBufferCheck(bufferCheckData)) { is Response.Success -> { @@ -443,7 +440,7 @@ class HemoCubeViewModel @Inject constructor( testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString() testDetails?.location = DataHolder.location testDetails?.testTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() + contextV.resources.getString(R.string.DateTimeFormat), Locale.getDefault() ).format(Calendar.getInstance().time) testDetails?.appVersion = DataHolder.hemoCubeTestData?.appVersion testDetails?.deviceId = DataHolder.hemoCubeTestData?.deviceId @@ -505,10 +502,10 @@ class HemoCubeViewModel @Inject constructor( testDetails!!.quickCapture = quickCapture testDetails.testStatus = true testDetails.reportUploadTime = SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss", Locale.getDefault() + contextV.resources.getString(R.string.DateTimeFormat), Locale.getDefault() ).format(Calendar.getInstance().time) val currentTimeFormatted = SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ssZZZZZ", + contextV.resources.getString(R.string.DateTimeFormat), Locale.getDefault() ).format(Calendar.getInstance().time) if(quickCapture){ @@ -519,7 +516,7 @@ class HemoCubeViewModel @Inject constructor( putInt(Constants.KIT_COUNT, kitCount.plus(1)) apply() } - Log.i("Testdb", "Data uploaded to Firestore successfully") + Log.i("Testdb", successMsg) fireBaseUpload.postValue("Success") testDetails.localFlag = true hemoCubeDao.updateTest(testDetails) @@ -531,7 +528,9 @@ class HemoCubeViewModel @Inject constructor( hemoCubeDao.updateTest(testDetails) } - else -> {} + else -> { + //nothing + } } }else{ when (val response = repository.addTestToDatabase(testDetails)) { @@ -542,7 +541,7 @@ class HemoCubeViewModel @Inject constructor( putInt(Constants.KIT_COUNT, kitCount.plus(1)) apply() } - Log.i("Testdb", "Data uploaded to Firestore successfully") + Log.i("Testdb", successMsg) fireBaseUpload.postValue("Success") if (Constants.MOLBIO_INTEGRATION) { @@ -577,8 +576,6 @@ class HemoCubeViewModel @Inject constructor( fireBaseUpload.postValue("Error") hemoCubeDao.updateTest(testDetails) } - - else -> {} } } @@ -645,7 +642,7 @@ class HemoCubeViewModel @Inject constructor( when (val response = repository.addTestToDatabaseforBufferCheck(bufferCheckData)) { is Response.Success -> { - Log.i("Testdb", "Data uploaded to Firestore successfully") + Log.i("Testdb", successMsg) fireBaseUpload.postValue("Success") } @@ -653,8 +650,6 @@ class HemoCubeViewModel @Inject constructor( Log.e("Testdb", "Error uploading data to Firestore: $response") fireBaseUpload.postValue("Error") } - - else -> {} } } catch (e: Exception) { Log.e("Testdb", "Exception during data upload: ${e.message}") diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemocubeActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemocubeActivity.kt index 8cde0d2..046c789 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemocubeActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemocubeActivity.kt @@ -304,11 +304,9 @@ open class HemocubeActivity : AppCompatActivity() { // } override fun onBackPressed() { val fragment = supportFragmentManager.findFragmentById(R.id.fghemocube) - if (fragment is HemoCubeFragment) { - if (fragment.handleBackButtonPress()) { - // If the fragment handled the back press, return to avoid calling super.onBackPressed - return - } + if (fragment is HemoCubeFragment && fragment.handleBackButtonPress()) { + // If the fragment handled the back press, return to avoid calling super.onBackPressed + return } // If the fragment did not handle the back press, call the superclass method super.onBackPressed() diff --git a/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalFragment.kt index 59f147d..5525b54 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/usb_teminal/UsbTerminalFragment.kt @@ -68,6 +68,7 @@ class UsbTerminalFragment : Fragment() { command, object : UsbServiceListener { override fun onUsbRead(data: ByteArray?) { + //nothing } override fun onUsbError(e: Exception?) { diff --git a/app/src/main/java/com/example/hpostesting/presentation/utils/DeviceCommunicationHandler.kt b/app/src/main/java/com/example/hpostesting/presentation/utils/DeviceCommunicationHandler.kt index 3c57ae6..9cc2798 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/utils/DeviceCommunicationHandler.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/utils/DeviceCommunicationHandler.kt @@ -15,6 +15,6 @@ package com.example.hpostesting.presentation.utils import com.example.hpostesting.data.constant.HemoCubeCommands -interface DeviceCommunicationHandler { +fun interface DeviceCommunicationHandler { fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener) } diff --git a/app/src/main/java/com/example/hpostesting/presentation/utils/NatsManager.kt b/app/src/main/java/com/example/hpostesting/presentation/utils/NatsManager.kt index e294693..db249f9 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/utils/NatsManager.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/utils/NatsManager.kt @@ -26,16 +26,9 @@ import io.nats.client.NKey import io.nats.client.Nats import io.nats.client.Options import io.nats.client.support.SSLUtils -import java.io.FileInputStream import java.io.IOException import java.nio.charset.StandardCharsets import java.security.GeneralSecurityException -import java.security.KeyStore -import java.security.SecureRandom -import java.security.cert.CertificateFactory -import javax.net.ssl.KeyManagerFactory -import javax.net.ssl.SSLContext -import javax.net.ssl.TrustManagerFactory class NatsManager(datacollector: DashboardActivity) { @@ -46,41 +39,41 @@ class NatsManager(datacollector: DashboardActivity) { var connect = false var sharedPreferences = datacollector.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) - private fun createSSLContext(): SSLContext { - val keyStorePassword = "prime24".toCharArray() // Change as necessary - val clientCertPath = "/storage/sdcard0/Download/client.p12" - - // Load client certificate and key - val keyStore = KeyStore.getInstance("PKCS12") - FileInputStream(clientCertPath).use { keyStoreInputStream -> - keyStore.load(keyStoreInputStream, keyStorePassword) - } - val caCertPath = - "/storage/sdcard0/Android/data/in.sminnovations.hpostesting.quality/files/NATS/clientCertificate/client-cert.pem" - val caCert = FileInputStream(caCertPath).use { inputStream -> - val certificateFactory = CertificateFactory.getInstance("X.509") - certificateFactory.generateCertificate(inputStream) - } - - val trustStore = KeyStore.getInstance(KeyStore.getDefaultType()).apply { - load(null, null) // Initialize the keystore - setCertificateEntry("caCert", caCert) // Add the CA certificate - } - - // Initialize key manager factory - val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()) - kmf.init(keyStore, keyStorePassword) - - // Initialize trust manager factory - val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) - tmf.init(trustStore) - - // Initialize SSLContext - val sslContext = SSLContext.getInstance("TLS") - sslContext.init(kmf.keyManagers, tmf.trustManagers, SecureRandom()) - - return sslContext - } +// private fun createSSLContext(): SSLContext { +// val keyStorePassword = "prime24".toCharArray() // Change as necessary +// val clientCertPath = "/storage/sdcard0/Download/client.p12" +// +// // Load client certificate and key +// val keyStore = KeyStore.getInstance("PKCS12") +// FileInputStream(clientCertPath).use { keyStoreInputStream -> +// keyStore.load(keyStoreInputStream, keyStorePassword) +// } +// val caCertPath = +// "/storage/sdcard0/Android/data/in.sminnovations.hpostesting.quality/files/NATS/clientCertificate/client-cert.pem" +// val caCert = FileInputStream(caCertPath).use { inputStream -> +// val certificateFactory = CertificateFactory.getInstance("X.509") +// certificateFactory.generateCertificate(inputStream) +// } +// +// val trustStore = KeyStore.getInstance(KeyStore.getDefaultType()).apply { +// load(null, null) // Initialize the keystore +// setCertificateEntry("caCert", caCert) // Add the CA certificate +// } +// +// // Initialize key manager factory +// val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()) +// kmf.init(keyStore, keyStorePassword) +// +// // Initialize trust manager factory +// val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) +// tmf.init(trustStore) +// +// // Initialize SSLContext +// val sslContext = SSLContext.getInstance("TLS") +// sslContext.init(kmf.keyManagers, tmf.trustManagers, SecureRandom()) +// +// return sslContext +// } @RequiresApi(Build.VERSION_CODES.O) fun connect() { diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 6eecf46..7958ed9 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -307,5 +307,6 @@ Calibrate the device Cuvette Present , Please Remove Cuvette And Try Again Cuvette Absent,Now You Can Submit + yyyy-MM-dd HH:mm:ss \ No newline at end of file diff --git a/app/src/main/res/values-kn/strings.xml b/app/src/main/res/values-kn/strings.xml index c44b312..bc3cd34 100644 --- a/app/src/main/res/values-kn/strings.xml +++ b/app/src/main/res/values-kn/strings.xml @@ -213,7 +213,7 @@ ಇನ್ಕ್ಯುಬೇಷನ್ ಪ್ರಾರಂಭಿಸಿ ಬಫರ್ ಚೆಕ್ ಮಾಡಿ - ಬ್ಯಾಟರಿ ಸ್ತರ 40% ಕ್ಕಿಂತ ಕಡಿಮೆಯಾಗಿದೆ, ಟೆಸ್ಟ್ ಮುಂದುವರಿಸಲು ದಯವಿಟ್ಟು ಡಿವೈಸ ಚಾರ್ಜ್ ಮಾಡಿ + ಬ್ಯಾಟರಿ ಸ್ತರ 20% ಕ್ಕಿಂತ ಕಡಿಮೆಯಾಗಿದೆ, ಟೆಸ್ಟ್ ಮುಂದುವರಿಸಲು ದಯವಿಟ್ಟು ಡಿವೈಸ ಚಾರ್ಜ್ ಮಾಡಿ ಈ ಬಳಕೆದಾರನ ಮೇಲೆ ಟೆಸ್ಟ್ ಮುಗಿದಿದೆ 15 ನಿಮಿಷಗಳ ಇನ್ಕ್ಯೂಬೇಷನ್ ಇನ್ನು ಪೂರ್ತಿ ಆಗಿಲ್ಲ್ಲ ಇನ್ಕ್ಯೂಬೇಷನ್ 30 ನಿಮಿಷಗಳನ್ನು ದಾಟಿದೆ, ಇನ್ನೊಮ್ಮೆ ಇನ್ಕ್ಯೂಬೇಷನ್ ಮಾಡಬೇಕಾಗಿದೆ @@ -306,6 +306,7 @@ ಸಾಧನವನ್ನು ಮಾಪನಾಂಕ ಮಾಡಿ Cuvette Present , Please Remove Cuvette And Try Again Cuvette Absent,Now You Can Submit + yyyy-MM-dd HH:mm:ss diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1b1ce43..89e6f41 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -219,7 +219,7 @@ All registered user are tested successfully Incubate Check Buffer - Battery level is low than 40%, please charge the device to continue testing + Battery level is low than 20%, please charge the device to continue testing Test has been already conducted for this user Incubation has not completed 15 minutes Incubation crossed 30 minutes, need to repeat the incubation @@ -307,5 +307,6 @@ Calibrate Device Cuvette Present , Please Remove Cuvette And Try Again Cuvette Absent,Now You Can Submit + yyyy-MM-dd HH:mm:ss \ No newline at end of file diff --git a/build.gradle b/build.gradle index 8401daa..8b26154 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ buildscript { kotlin_version = '1.8.21' } dependencies { - classpath 'com.android.tools.build:gradle:8.4.0' + classpath 'com.android.tools.build:gradle:8.5.0' classpath 'com.google.gms:google-services:4.4.1' classpath 'com.google.firebase:firebase-appdistribution-gradle:4.1.0' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fcc8245..1255ef3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -14,6 +14,6 @@ #Mon Mar 04 17:08:24 IST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists