Compare commits

..

5 Commits

Author SHA1 Message Date
smileomi18@gmail.com
a25402fc26 production errors 2023-09-12 13:21:40 +05:30
smileomi18@gmail.com
388af0adf6 production errors 2023-09-12 13:04:57 +05:30
smileomi18@gmail.com
57a0c2103a production errors 2023-09-12 12:58:56 +05:30
smileomi18@gmail.com
057abbd87c Calculated ratio error code added 2023-09-07 13:51:07 +05:30
mohamedkaif356
c3775eeea1 Error code added 2023-09-07 13:31:02 +05:30
35 changed files with 654 additions and 1850 deletions

43
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="app/src/main/res/drawable/ic_baseline_auto_graph_24.xml" value="0.1555" />
<entry key="app/src/main/res/drawable/ic_baseline_cancel_24.xml" value="0.1965" />
<entry key="app/src/main/res/drawable/ic_baseline_check_circle_24.xml" value="0.243" />
<entry key="app/src/main/res/drawable/ic_baseline_dot_24.xml" value="0.1785" />
<entry key="app/src/main/res/drawable/ic_baseline_file_download_24.xml" value="0.243" />
<entry key="app/src/main/res/drawable/ic_baseline_home_24.xml" value="0.243" />
<entry key="app/src/main/res/drawable/ic_baseline_new_label_24.xml" value="0.243" />
<entry key="app/src/main/res/drawable/ic_baseline_usb_24.xml" value="0.157" />
<entry key="app/src/main/res/drawable/ic_baseline_usb_off_24.xml" value="0.157" />
<entry key="app/src/main/res/drawable/progressbar_drawable.xml" value="0.1885" />
<entry key="app/src/main/res/drawable/result_background_green.xml" value="0.243" />
<entry key="app/src/main/res/drawable/result_background_red.xml" value="0.1785" />
<entry key="app/src/main/res/drawable/result_background_tellow.xml" value="0.1785" />
<entry key="app/src/main/res/font/inter_bold.xml" value="0.33487179487179486" />
<entry key="app/src/main/res/layout/activity_main.xml" value="0.165" />
<entry key="app/src/main/res/layout/activity_splash.xml" value="0.24375" />
<entry key="app/src/main/res/layout/activity_test_right.xml" value="0.24375" />
<entry key="app/src/main/res/layout/fragment_graph.xml" value="0.19791666666666666" />
<entry key="app/src/main/res/layout/fragment_test_right_exp_reference.xml" value="0.25" />
<entry key="app/src/main/res/layout/fragment_test_right_exp_sample.xml" value="0.24583333333333332" />
<entry key="app/src/main/res/layout/fragment_test_right_exp_scanner.xml" value="0.24583333333333332" />
<entry key="app/src/main/res/layout/fragment_test_right_process.xml" value="0.24375" />
<entry key="app/src/main/res/layout/fragment_test_right_results.xml" value="0.30512820512820515" />
<entry key="app/src/main/res/layout/table_item.xml" value="0.22407407407407406" />
<entry key="app/src/main/res/menu/menu.xml" value="0.25" />
<entry key="app/src/main/res/menu/my_menu.xml" value="0.25" />
<entry key="app/src/main/res/mipmap-anydpi-v26/hpos_icon.xml" value="0.1505" />
<entry key="app/src/main/res/mipmap-anydpi-v26/hpos_icon_round.xml" value="0.1505" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

2
app/.gitignore vendored
View File

@@ -1,3 +1,3 @@
/build
/google-services*
/google-services.json
/idea

View File

@@ -18,8 +18,8 @@ android {
applicationId "in.sminnovations.hpostesting"
minSdk 21
targetSdk 34
versionCode 20
versionName "2.1.21"
versionCode 2
versionName "2.0.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -70,9 +70,6 @@ dependencies {
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
implementation 'com.google.android.things:androidthings:1.0'
implementation 'com.google.firebase:firebase-appdistribution:16.0.0-beta10'
implementation("com.google.firebase:firebase-appdistribution-api-ktx:16.0.0-beta10")
// Testing
testImplementation 'junit:junit:4.13.2'

View File

@@ -13,8 +13,11 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-feature android:name="android.hardware.usb.host" />
<uses-permission android:name="android.permission.USB_PERMISSION" />
<application
android:name="com.example.hpostesting.HPOSTestingApplication"
android:allowBackup="true"
@@ -27,14 +30,12 @@
android:theme="@style/Theme.HPOSTesting"
tools:targetApi="31">
<activity
android:name="com.example.hpostesting.presentation.hemocube.HemocubeActivity"
android:exported="false"
android:name="com.example.hpostesting.presentation.BloodCollectingMethodActivity"
android:exported="true"
android:noHistory="true"
android:parentActivityName="com.example.hpostesting.presentation.MainActivity"
android:theme="@style/Theme.HPOS.NoActionBar"
android:windowSoftInputMode="adjustPan" />
android:theme="@style/Theme.HPOS.NoActionBar" />
<activity
android:name="com.example.hpostesting.presentation.buffercheck.HemocubeBufferCheckActivity"
android:name="com.example.hpostesting.presentation.hemocube.HemocubeActivity"
android:exported="false"
android:noHistory="true"
android:parentActivityName="com.example.hpostesting.presentation.MainActivity"
@@ -98,10 +99,9 @@
</activity>
<activity
android:name="com.journeyapps.barcodescanner.CaptureActivity"
android:screenOrientation="portrait"
android:screenOrientation="fullSensor"
android:stateNotNeeded="true"
tools:replace="android:screenOrientation" />
</application>
</manifest>

View File

@@ -15,8 +15,6 @@ import javax.inject.Singleton
@HiltAndroidApp
class HPOSTestingApplication: Application() {
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
override fun onCreate() {
super.onCreate()
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)

View File

@@ -47,20 +47,6 @@ object Constants {
"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",
)
const val password = "SMI@12345"
@@ -69,4 +55,8 @@ object Constants {
const val KIT_COUNT = "KitCount"
const val BUFFER_VALUE_1 = "BufferValue1"
const val BUFFER_VALUE_2 = "BufferValue2"
const val BLOOD_COLLECTING_METHOD = "bloodCollectingMethod"
const val VENOUS_BLOOD = "venousBlood"
const val FINGER_PRICK_BLOOD = "fingerPrickBlood"
}

View File

@@ -9,18 +9,15 @@ import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
@Dao
interface HemoCubeDao {
@Query("SELECT * from hemo_cube_test_table")
@Query("SELECT * from HemocubeTest_table")
fun getAll(): LiveData<List<HemoCubeTestData>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(hemoCubeTestData: HemoCubeTestData)
@Query("SELECT * FROM hemo_cube_test_table WHERE _id = :id")
@Query("SELECT * FROM hemocubetest_table WHERE _id = :id")
suspend fun getUserByID(id: String): HemoCubeTestData
@Query("DELETE FROM hemo_cube_test_table WHERE _id = :id")
@Query("DELETE FROM hemocubetest_table WHERE _id = :id")
suspend fun deleteById(id: String)
@Query("UPDATE hemo_cube_test_table SET localFlag = :newValue WHERE _id = :id")
suspend fun updateFieldById(id: String, newValue: Boolean)
}

View File

@@ -1,19 +0,0 @@
package com.example.hpostesting.data.model.patient
data class BufferCheckData(
var kitno: String = "",
var deviceId: String? = "",
var appVersion:String? = "",
var deviceSerialNumber: String = "",
var deviceType: String = "HEMOCUBE",
var resultData: String = "",
var led1Buffer: Double? = null,
var led2Buffer: Double? = null,
var led1Sample: Double? = null,
var led2Sample: Double? = null,
var led1Average: Double? = null,
var led2Average: Double? = null,
var deviceRatio: Double? = null,
var calculatedRatio: Double? = null,
var classificationResult: String = ""
)

View File

@@ -3,7 +3,7 @@ package com.example.hpostesting.data.model.patient
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "hemo_cube_test_table")
@Entity(tableName = "HemocubeTest_table")
data class HemoCubeTestData(
@PrimaryKey
var _id: String = "",
@@ -29,6 +29,5 @@ data class HemoCubeTestData(
var led1Average: Double? = null,
var led2Average: Double? = null,
var deviceRatio: Double? = null,
var calculatedRatio: Double? = null,
var classificationResult: String = ""
var calculatedRatio: Double? = null
)

View File

@@ -9,7 +9,6 @@ data class UserData(
@PrimaryKey
var _id: String = "",
var name: String = "",
var incubationTime: String = "",
var birthYear: String = "",
var userImageURL: String = "",
var location: Location? = null,

View File

@@ -1,19 +1,24 @@
package com.example.hpostesting.data.repository
import android.content.Context
import android.net.Uri
import androidx.room.Room
import com.example.hpostesting.data.dao.MyDatabase
import com.example.hpostesting.data.model.PendingUploads
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.android.datatransport.runtime.dagger.Provides
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.google.firebase.storage.ktx.storage
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext
import java.io.File
import javax.inject.Singleton
class DatabaseRepository : Repository {
@@ -35,6 +40,7 @@ class DatabaseRepository : Repository {
}
}
suspend fun addTestToDatabase(data: UserData?): Response<String> {
return try {
val userdata = db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
@@ -46,20 +52,13 @@ class DatabaseRepository : Repository {
db.collection("testData").add(data!!).await()
Response.Success(data!!._id)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
}
suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response<String> {
return try {
db.collection("buffers").add(data!!).await()
Response.Success(data!!.kitno)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
}
suspend fun uploadFileToStorage(patientID: String, filePath: String): Response<Boolean> {
try {
@@ -68,8 +67,9 @@ class DatabaseRepository : Repository {
val riversRef = storage.reference.child("$patientID/${file.lastPathSegment}")
riversRef.putFile(file).await()
return Response.Success(true)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
e.printStackTrace()
return Response.Error(e)
}
}
@@ -81,7 +81,7 @@ class DatabaseRepository : Repository {
Response.Success(true)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
e.printStackTrace()
Response.Error(e)
}
}
@@ -100,7 +100,7 @@ class DatabaseRepository : Repository {
pendingList
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
e.printStackTrace()
pendingList
}
}
@@ -111,7 +111,7 @@ class DatabaseRepository : Repository {
Response.Success(true)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
e.printStackTrace()
Response.Error(e)
}
}
@@ -120,6 +120,7 @@ class DatabaseRepository : Repository {
return db.collection("devices").get().await().toObjects(DeviceData::class.java)
}
suspend fun getDeviceDataById(deviceId: String): DeviceData? {
val querySnapshot = db.collection("devices").get().await()
val allDeviceDataList = querySnapshot.toObjects(DeviceData::class.java)
@@ -127,4 +128,7 @@ class DatabaseRepository : Repository {
// Find the DeviceData object with the specified deviceId
return allDeviceDataList.find { it.deviceId == deviceId }
}
}

View File

@@ -0,0 +1,57 @@
package com.example.hpostesting.presentation
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import com.example.hpostesting.presentation.testRight.TestRightActivity
import `in`.sminnovations.hpostesting.databinding.ActivityBloodCollectingMethodBinding
class BloodCollectingMethodActivity : AppCompatActivity() {
private lateinit var binding: ActivityBloodCollectingMethodBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityBloodCollectingMethodBinding.inflate(layoutInflater)
setContentView(binding.root)
init()
}
private fun init() {
setSupportActionBar(binding.toolbar)
binding.btnGo.setOnClickListener {
DataHolder.usbConnected.observe(this) {
if (it) {
if (binding.venousBloodRadioButton.isChecked) {
moveToNext(Constants.VENOUS_BLOOD)
} else {
moveToNext(Constants.FINGER_PRICK_BLOOD)
}
} else {
Toast.makeText(this, "No Device Connected", Toast.LENGTH_SHORT).show()
}
}
}
}
private fun moveToNext(bloodCollectingMethod: String) {
DataHolder.deviceType.observe(this) { deviceType ->
when (deviceType) {
Constants.DEVICE_TYPE_HOMOCUBE -> {
val intent = Intent(applicationContext, HemocubeActivity::class.java)
intent.putExtra(Constants.BLOOD_COLLECTING_METHOD, bloodCollectingMethod)
startActivity(intent)
}
Constants.DEVICE_TYPE_TEST_RIGHT -> {
val intent = Intent(applicationContext, TestRightActivity::class.java)
intent.putExtra(Constants.BLOOD_COLLECTING_METHOD, bloodCollectingMethod)
startActivity(intent)
}
}
}
}
}

View File

@@ -11,8 +11,6 @@ import androidx.appcompat.app.AppCompatActivity
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.dashboard.DashboardActivity
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
@@ -67,36 +65,35 @@ class KitScanActivity : AppCompatActivity() {
// putString(Constants.BUFFER_VALUE_2, "")
// apply()
// }
// }
try {
if (checkHemoCubeKitData()) {
if (checkHemoCubeKitData()) {
try {
DataHolder.selectedTest!!.kitSerial =
sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
moveToNext()
} else {
// Handle the case when checkHemoCubeKitData() returns false
with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "")
putInt(Constants.KIT_COUNT, 0)
putString(Constants.BUFFER_VALUE_1, "")
putString(Constants.BUFFER_VALUE_2, "")
apply()
}
} catch (e: NullPointerException) {
// Handle the NullPointerException here
e.printStackTrace() // You can log the exception for debugging
FirebaseCrashlytics.getInstance().recordException(e)
val errorMessage = "An error occurred: ${e.message}"
val rootView = findViewById<View>(android.R.id.content)
Snackbar.make(rootView, errorMessage, Snackbar.LENGTH_LONG).show()
// Optionally, show a user-friendly error message to the user
// Toast.makeText(applicationContext, "An error occurred", Toast.LENGTH_SHORT).show()
}
} else {
with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "")
putInt(Constants.KIT_COUNT, 0)
putString(Constants.BUFFER_VALUE_1, "")
putString(Constants.BUFFER_VALUE_2, "")
apply()
}
} catch (e: NullPointerException) {
// Handle the NullPointerException here
e.printStackTrace() // You can log the exception for debugging
FirebaseCrashlytics.getInstance().recordException(e)
val errorMessage = "An error occurred: ${e.message}"
val rootView = findViewById<View>(android.R.id.content)
Snackbar.make(rootView, errorMessage, Snackbar.LENGTH_LONG).show()
// Optionally, show a user-friendly error message to the user
// Toast.makeText(applicationContext, "An error occurred", Toast.LENGTH_SHORT).show()
}
}
binding.nameEditText.setText("SMI/SC/")
setSupportActionBar(binding.toolbar)
@@ -108,33 +105,7 @@ class KitScanActivity : AppCompatActivity() {
binding.btnGo.setOnClickListener {
val serialNumber = binding.nameEditText.text.toString().trim()
if (serialNumber.isNotEmpty() && isSerialValid(serialNumber)) {
if (DataHolder.selectedTest == null) {
with(sharedPreference.edit()) {
putString(
Constants.KIT_NUMBER, binding.nameEditText.text.toString()
)
putInt(Constants.KIT_COUNT, 1)
apply()
}
Toast.makeText(
applicationContext,
"Kit number is updated, Please Select user before starting test",
Toast.LENGTH_SHORT
).show()
val i = Intent(applicationContext, DashboardActivity::class.java)
startActivity(i)
finish()
}
} else {
Toast.makeText(this, "Invalid KIT Number", Toast.LENGTH_LONG).show()
return@setOnClickListener
}
if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid(
serialNumber
)
) {
if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid(serialNumber)) {
DataHolder.kitSerial = binding.nameEditText.text.toString()
DataHolder.selectedTest?.kitSerial = binding.nameEditText.text.toString()
with(sharedPreference.edit()) {
@@ -151,9 +122,8 @@ class KitScanActivity : AppCompatActivity() {
private fun checkHemoCubeKitData(): Boolean {
return sharedPreference.getString(Constants.KIT_NUMBER, "")
?.isNotBlank() == true && sharedPreference.getInt(
Constants.KIT_COUNT, 0
) > 0 && sharedPreference.getInt(Constants.KIT_COUNT, 0) < 35
?.isNotBlank() == true && sharedPreference.getInt(Constants.KIT_COUNT, 0) > 0
&& sharedPreference.getInt(Constants.KIT_COUNT, 0) < 35
}
private fun isSerialValid(s: String): Boolean {
@@ -165,20 +135,8 @@ class KitScanActivity : AppCompatActivity() {
}
private fun moveToNext() {
DataHolder.deviceType.observe(this) { deviceType ->
when (deviceType) {
Constants.DEVICE_TYPE_HOMOCUBE -> {
val i = Intent(applicationContext, HemocubeActivity::class.java)
startActivity(i)
}
Constants.DEVICE_TYPE_TEST_RIGHT -> {
val i = Intent(applicationContext, TestRightActivity::class.java)
startActivity(i)
}
}
}
val i = Intent(applicationContext, BloodCollectingMethodActivity::class.java)
startActivity(i)
}
private fun startScanningNow() {

View File

@@ -20,7 +20,6 @@ import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.test.TestType
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.google.android.gms.location.*
import com.google.android.material.snackbar.Snackbar
import com.google.firebase.crashlytics.FirebaseCrashlytics
@@ -86,10 +85,17 @@ class MainActivity : AppCompatActivity() {
}
}
if (DataHolder.selectedTest == null) {
startActivity(Intent(this, DashboardActivity::class.java))
finish()
}
// val crashButton = Button(this)
// crashButton.text = "Test Crash"
// crashButton.setOnClickListener {
// throw RuntimeException("Test Crash") // Force a crash
// }
//
// addContentView(crashButton, ViewGroup.LayoutParams(
// ViewGroup.LayoutParams.MATCH_PARENT,
// ViewGroup.LayoutParams.WRAP_CONTENT))
}
private fun checkAndUpdateUsbConnection() {
@@ -155,14 +161,12 @@ class MainActivity : AppCompatActivity() {
DataHolder.selectedTestType = TestType.SICKLECERT
val i = Intent(applicationContext, KitScanActivity::class.java)
startActivity(i)
finish()
}
binding.cvItem2.setOnClickListener {
DataHolder.selectedTestType = TestType.SICKLEFIND
val i = Intent(applicationContext, KitScanActivity::class.java)
startActivity(i)
finish()
}
DataHolder.usbConnected.observe(this) {
@@ -246,29 +250,28 @@ class MainActivity : AppCompatActivity() {
// }
fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
location?.let {
if (DataHolder.selectedTest != null) {
fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
location?.let {
DataHolder.selectedTest!!.location =
UserData.Location(location.latitude, location.longitude)
} else {
startActivity(Intent(this, DashboardActivity::class.java))
finish()
DataHolder.location =
UserData.Location(location.latitude, location.longitude)
} ?: run {
requestLocationUpdates()
}
DataHolder.location =
UserData.Location(location.latitude, location.longitude)
} ?: run {
requestLocationUpdates()
}.addOnFailureListener { exception: Exception ->
// Handle the exception here
exception.printStackTrace()
FirebaseCrashlytics.getInstance().recordException(exception)
// Display an error message to the user using a Snackbar
val errorMessage = "An error occurred: ${exception.message}"
val rootView = findViewById<View>(android.R.id.content)
Snackbar.make(rootView, errorMessage, Snackbar.LENGTH_LONG).show()
}
}.addOnFailureListener { exception: Exception ->
// Handle the exception here
exception.printStackTrace()
FirebaseCrashlytics.getInstance().recordException(exception)
// Display an error message to the user using a Snackbar
val errorMessage = "An error occurred: ${exception.message}"
val rootView = findViewById<View>(android.R.id.content)
Snackbar.make(rootView, errorMessage, Snackbar.LENGTH_LONG).show()
}

View File

@@ -1,10 +1,6 @@
package com.example.hpostesting.presentation.adapter
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Context
import android.content.Context.INPUT_METHOD_SERVICE
import android.view.inputmethod.InputMethodManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -14,30 +10,17 @@ import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.UserItemViewBinding
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import android.widget.AutoCompleteTextView
import androidx.core.content.ContextCompat.getSystemService
import androidx.core.content.getSystemService
import androidx.fragment.app.FragmentActivity
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.firestore.FirebaseFirestore
class UserListAdapter(
private val context: Context,
private val hemoCubeViewModel: HemoCubeViewModel,
options: FirestoreRecyclerOptions<UserData>,
private val view: View,
private val batLevel: Int,
private val requireActivity: FragmentActivity
) : FirestoreRecyclerAdapter<UserData, UserListAdapter.OrderItemViewHolder>(options) {
private val view: View
) :
FirestoreRecyclerAdapter<UserData, UserListAdapter.OrderItemViewHolder>(options) {
class OrderItemViewHolder(val binding: UserItemViewBinding) :
RecyclerView.ViewHolder(binding.root)
@@ -53,21 +36,6 @@ class UserListAdapter(
holder.binding.apply {
userName.text = "Name: ${model.name}"
userId.text = "User ID:${model._id}"
if (model.incubationTime == "") {
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)!!
)
}"
btnBlood.visibility = View.GONE
}
Glide.with(view).load(model.userImageURL).into(userImage)
if (model.testStatus!!) {
teststatus.text = "Test concluded"
@@ -75,129 +43,7 @@ class UserListAdapter(
} else {
teststatus.text = "Test is Pending"
}
holder.binding.btnBlood.setOnClickListener {
val view: View? = requireActivity.currentFocus
// 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
// 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)
val builder = AlertDialog.Builder(context)
.setView(dialogView)
.setTitle("Add Blood Group")
val etBloodGroup = dialogView.findViewById<AutoCompleteTextView>(R.id.et_blood_group)
builder.setPositiveButton("OK") { dialog, which ->
val bloodGroup = etBloodGroup.text.toString()
if (bloodGroup.equals("Select Blood Group") || bloodGroup.isNullOrBlank()) {
etBloodGroup.error = "Please enter your blood group"
Toast.makeText(
context,
"Please enter your blood group",
Toast.LENGTH_SHORT
).show()
} else {
// Check if hemoCubeViewModel and testDetails are not null
val db: FirebaseFirestore = FirebaseFirestore.getInstance()
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 {
Toast.makeText(
context,
"Blood group updated successfully",
Toast.LENGTH_SHORT
).show()
btnBlood.visibility = View.GONE
}
.addOnFailureListener { e ->
Toast.makeText(
context,
"Failed to update blood group: ${e.message}",
Toast.LENGTH_SHORT
).show()
}
} catch (e: IndexOutOfBoundsException) {
// Handle the case where no documents are found for the specified ID
Toast.makeText(
context,
"No user data found for the specified ID",
Toast.LENGTH_SHORT
).show()
}
}
.addOnFailureListener { e ->
Toast.makeText(
context,
"Error fetching user data: ${e.message}",
Toast.LENGTH_SHORT
).show()
}
}
// Handle the selected blood group here
}
builder.setNegativeButton("Cancel") { dialog, which ->
dialog.dismiss()
}
val alertDialog = builder.create()
alertDialog.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()
// }
// }
// }
// }
}
userCard.setOnClickListener {
if (batLevel < 40) {
Toast.makeText(
view.context,
"Battery level is low than 40%, please charge the device to continue testing",
Toast.LENGTH_SHORT
).show()
return@setOnClickListener
}
if (model.testStatus != null) {
if (model.testStatus!!) {
Toast.makeText(
@@ -206,47 +52,11 @@ class UserListAdapter(
Toast.LENGTH_SHORT
).show()
} else {
if (model.incubationTime != "") {
if (isBetween15And30Minutes(model.incubationTime) < 15) {
Toast.makeText(
view.context,
"Incubation has not completed 15 minutes",
Toast.LENGTH_SHORT
).show()
} else if (isBetween15And30Minutes(model.incubationTime) > 30) {
Toast.makeText(
view.context,
"Incubation crossed 30 minutes, need to repeat the incubation",
Toast.LENGTH_SHORT
).show()
} else {
DataHolder.selectedTest = model
view.findNavController()
.navigate(R.id.action_nav_home_to_mainActivity)
}
} else {
Toast.makeText(
view.context,
"Incubation not started for this user",
Toast.LENGTH_SHORT
).show()
}
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)
}
}

View File

@@ -1,344 +0,0 @@
package com.example.hpostesting.presentation.buffercheck
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import kotlin.math.log10
class HemoCubeBufferCheckFragment : Fragment() {
private lateinit var binding: FragmentHemoCubeReferenceBinding
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences
private var currentDeviceData: DeviceData? = null
private var resultData: String = ""
private var kitno: String = ""
private var isOnline = false
private val messages = MutableLiveData<String>()
private var isTestOngoing = false
private var startListening = MutableLiveData(false)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View {
binding = FragmentHemoCubeReferenceBinding.inflate(inflater, container, false)
sharedPreferences =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViews()
observeViewModel()
}
private fun initViews() {
binding.nameEditText.setText("SMI/SC/")
binding.btnGo.setOnClickListener {
val serialNumber = binding.nameEditText.text.toString().trim()
if (serialNumber.isNotEmpty() && isSerialValid(serialNumber)) {
kitno = serialNumber
listenToHemoCube()
startBufferProcess()
} else {
Toast.makeText(context, "Invalid KIT Number", Toast.LENGTH_LONG).show()
return@setOnClickListener
}
activity?.runOnUiThread {
binding.tvSubtitle2.visibility = View.GONE
binding.etAbhaId.visibility = View.GONE
binding.tvTitle.visibility = View.GONE
binding.tvTitle2.visibility = View.GONE
binding.btnGo.visibility = View.GONE
}
}
activity?.runOnUiThread {
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
}
binding.btnSubmit.setOnClickListener {
}
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
}
private fun observeViewModel() {
hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) {
currentDeviceData = it
}
hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
if (isNetworkAvailable) {
hemoCubeViewModel.getDeviceData(sharedPreferences.getString(Constants.USER_ID, ""))
} else {
Toast.makeText(
requireContext(), "No internet connection avaiable", Toast.LENGTH_SHORT
).show()
}
isOnline = isNetworkAvailable
}
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
showToast("Kit result uploaded successfully")
}
if (result == "Local") {
showToast("Kit result uploading failed, note it down manually")
}
binding.progressBar.visibility = View.GONE
}
messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it
}
}
private fun listenToHemoCube() {
if (DataHolder.hemoCubeTestData == null) {
DataHolder.hemoCubeTestData = DataHolder.selectedTest?.toHemoCubeTestData()
}
val fullReadOutput = StringBuilder()
startListening.postValue(true)
try {
(activity as HemocubeBufferCheckActivity).mService.listenToHemoCube(object :
UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
fullReadOutput.append(stringData)
handleUsbData(stringData, fullReadOutput)
}
}
override fun onUsbError(e: Exception?) {
}
})
} catch (e: Exception) {
showToast("test is going on")
Firebase.crashlytics.recordException(e)
}
}
private fun handleUsbData(stringData: String, fullReadOutput: StringBuilder) {
if (stringData.contains("#")) {
messages.postValue(stringData)
isTestOngoing = true
}
resultData += fullReadOutput.toString()
when {
stringData.contains("#Buffer Completed") -> showStartSampleDialog()
stringData.contains("#Sample Completed") -> {
activity?.runOnUiThread {
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
}
fetchResult()
}
stringData.contains("RESULT") || resultData.contains("REND") -> {
var validString: String
val results: List<String>
if (stringData.contains("RESULT")) {
validString = isValidResult(stringData)
if (validString.isEmpty()) {
results = resultData.split("\n")
validString = parseResult(results)
}
} else {
results = resultData.split("\n")
validString = parseResult(results)
}
if (validString.isNotEmpty()) {
handleValidResult(validString)
}
}
}
}
private fun showStartSampleDialog() {
activity?.runOnUiThread {
UIUtils.createAlertDialog(requireContext(),
"Start Sample",
"Do you want to start sample reading?",
getString(R.string.no),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
listenToHemoCube()
startSampleProcess()
}
})
}
}
private fun handleValidResult(validString: String) {
try {
val result = validString.split(" ")
if (result.size == 8) {
val deviceSerialNo = result[2]
val led1BufferForDevice = result[3].toDoubleOrNull()
val led2BufferForDevice = result[4].toDoubleOrNull()
val led1Sample = result[5].toDoubleOrNull()
val led2Sample = result[6].toDoubleOrNull()
val led1Average = log10(led1BufferForDevice?.div(led1Sample!!) ?: 0.0)
val led2Average = log10(led2BufferForDevice?.div(led2Sample!!) ?: 0.0)
val deviceRatio = led1Average / led2Average
val calculatedRatio = 0.14
val classificationResult = findResult(calculatedRatio)
messages.postValue(classificationResult)
val bufferData = BufferCheckData(
kitno = kitno,
led1Buffer = led1BufferForDevice,
led2Buffer = led2BufferForDevice,
led1Average = led1Average,
led2Average = led2Average,
led1Sample = led1Sample,
led2Sample = led2Sample,
deviceRatio = deviceRatio,
calculatedRatio = calculatedRatio,
classificationResult = classificationResult,
deviceSerialNumber = deviceSerialNo
)
hemoCubeViewModel.uploadHemoCubeResultToDatabaseforbuffercheckN(bufferData)
}
} catch (e: Exception) {
Toast.makeText(
requireContext(), "Error while processing device data", Toast.LENGTH_SHORT
).show()
Firebase.crashlytics.recordException(e)
}
}
private fun findResult(calculatedRatio: Double?): String {
try {
if (calculatedRatio != null) {
if (calculatedRatio < 0.085) return "Kit Failed"
if (calculatedRatio in 0.085..0.155) return "Kit Passed"
if (calculatedRatio in 0.155..0.175) return "Kit Failed"
if (calculatedRatio in 0.175..0.22) return "Kit Failed"
if (calculatedRatio in 0.22..0.25) return "Kit Failed"
if (calculatedRatio in 0.25..0.35) return "Kit Failed"
if (calculatedRatio > 0.35) return "Kit Failed"
} else {
return "NULL"
}
} catch (e: Exception) {
showToast("error while performing classification")
Firebase.crashlytics.recordException(e)
return "ERROR"
}
return "NULL"
}
private fun showToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
private fun startBufferProcess() {
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startBuffer,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
}
})
}
private fun startSampleProcess() {
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startSample,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
}
})
}
private fun fetchResult() {
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.getSample,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
}
})
}
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 parseResult(frames: List<String>): String {
val lines = mutableListOf<String>()
for (frame in frames.reversed()) {
if (frame.contains("REND") || frame.contains("RESULT")) lines += frame
if (frame.contains("RESULT")) {
break
}
}
val line = lines.reversed().joinToString("").trim()
if (line.contains("RESULT") && line.split(" ").size == 8) {
return line
}
return ""
}
private fun isSerialValid(s: String): Boolean {
if (s.length != 17) {
binding.nameEditText.error = getString(R.string.invalid_kit)
return false
}
return true
}
private fun isValidResult(line: String): String {
return if (line.contains("RESULT") && line.split(" ").size == 8) {
line
} else {
""
}
}
}

View File

@@ -1,164 +0,0 @@
package com.example.hpostesting.presentation.buffercheck
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.ServiceConnection
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.os.IBinder
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.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityHemocubeBinding
@AndroidEntryPoint
open class HemocubeBufferCheckActivity : AppCompatActivity() {
private lateinit var binding: ActivityHemocubeBinding
private val viewModel by viewModels<HemoCubeViewModel>()
private var myMenu: Menu? = null
private lateinit var mDriver: UsbSerialDriver
private var mConnection: UsbDeviceConnection? = null
lateinit var mService: UsbService
private val TAG = "HemoCube"
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
synchronized(this) {
val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
device?.apply {
connectUsb(true)
DataHolder.usbConnected.postValue(true)
}
} else {
DataHolder.usbConnected.postValue(true)
}
}
}
}
private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as UsbService.UsbServiceBinder
mService = binder.getService()
viewModel.isServiceConnected = true
mConnection.let { mService.connect(mDriver, mConnection!!) }
moveToNext()
}
override fun onServiceDisconnected(arg0: ComponentName) {
viewModel.isServiceConnected = false
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHemocubeBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.myToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
setupListener()
connectUsb(false)
}
private fun setupListener() {
DataHolder.usbConnected.observe(this) {
Log.d("USB OBSERVE", "HemoCube called -> $it")
if (it) {
myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24)
} else {
myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
Toast.makeText(this, "Device is Disconnected", Toast.LENGTH_SHORT).show()
}
}
}
open fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager
val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager)
if (availableDrivers.isEmpty()) {
Toast.makeText(this, "No device found", Toast.LENGTH_SHORT).show()
} else {
mDriver = availableDrivers[0]
mConnection = manager.openDevice(mDriver.device)
if (mConnection == null) {
requestUserPermission(manager, mDriver.device)
} else {
setupService()
}
}
}
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
PendingIntent.getBroadcast(
this, 0, Intent(Constants.HOMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
)
} else {
PendingIntent.getBroadcast(
this,
0,
Intent(Constants.HOMOCUBE_USB_PERMISSION),
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
)
}
val filter = IntentFilter(Constants.HOMOCUBE_USB_PERMISSION)
registerReceiver(broadcastReceiver, filter)
manager.requestPermission(device, mPendingIntent)
}
private fun setupService() {
val intent = Intent(this, UsbService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return
supportFragmentManager.beginTransaction().replace(binding.fghemocube.id, HemoCubeBufferCheckFragment())
.commit()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.my_menu, menu)
return true
}
override fun onDestroy() {
super.onDestroy()
if (viewModel.isServiceConnected) {
mService.disconnect()
unbindService(connection)
viewModel.isServiceConnected = false
}
}
}

View File

@@ -2,7 +2,6 @@ package com.example.hpostesting.presentation.dashboard
import android.os.Bundle
import android.view.Menu
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.drawerlayout.widget.DrawerLayout
import androidx.navigation.findNavController
@@ -11,12 +10,6 @@ import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.navigation.NavigationView
import com.google.firebase.appdistribution.FirebaseAppDistribution
import com.google.firebase.appdistribution.FirebaseAppDistributionException
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.crashlytics.ktx.crashlytics
//import com.google.firebase.appdistribution.FirebaseAppDistribution
//import com.google.firebase.appdistribution.FirebaseAppDistributionException
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
@@ -32,6 +25,7 @@ class DashboardActivity : AppCompatActivity() {
binding = ActivityDashboardBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.appBarDashboard.toolbar)
val drawerLayout: DrawerLayout = binding.drawerLayout
@@ -59,37 +53,4 @@ class DashboardActivity : AppCompatActivity() {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
override fun onResume() {
super.onResume()
val firebaseAppDistribution = FirebaseAppDistribution.getInstance()
firebaseAppDistribution.updateIfNewReleaseAvailable()
.addOnProgressListener { updateProgress ->
Toast.makeText(
this,
"${updateProgress.updateStatus}. ${updateProgress.apkBytesDownloaded / 1048576} /${updateProgress.apkFileTotalBytes / 1048576} MB",
Toast.LENGTH_SHORT
).show()
}
.addOnFailureListener { e ->
// (Optional) Handle errors.
if (e is FirebaseAppDistributionException) {
when (e.errorCode) {
FirebaseAppDistributionException.Status.NOT_IMPLEMENTED -> {
// SDK did nothing. This is expected when building for Play.
}
else -> {
// Handle other errors.
Toast.makeText(this, "AppDistribution error, status: ${e.errorCode}", Toast.LENGTH_SHORT).show()
}
}
FirebaseCrashlytics.getInstance().recordException(e)
}
}
.addOnSuccessListener {
Toast.makeText(this, "App Update: Success!", Toast.LENGTH_SHORT).show()
}
}
}

View File

@@ -1,12 +1,12 @@
package com.example.hpostesting.presentation.dashboard
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.hpostesting.presentation.buffercheck.HemocubeBufferCheckActivity
import androidx.lifecycle.ViewModelProvider
//import com.example.hpostesting.presentation.dashboard.ui.gallery.GalleryViewModel
import `in`.sminnovations.hpostesting.databinding.FragmentGalleryBinding
class GalleryFragment : Fragment() {
@@ -32,9 +32,6 @@ class GalleryFragment : Fragment() {
// galleryViewModel.text.observe(viewLifecycleOwner) {
//// textView.text = it
// }
binding.btnSubmit.setOnClickListener {
startActivity(Intent(requireContext(), HemocubeBufferCheckActivity::class.java))
}
return root
}

View File

@@ -2,11 +2,8 @@ package com.example.hpostesting.presentation.dashboard
import android.app.AlertDialog
import android.content.Context
import android.content.Context.BATTERY_SERVICE
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import android.os.BatteryManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -19,20 +16,15 @@ import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.KitScanActivity
import com.example.hpostesting.presentation.adapter.UserListAdapter
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.testRight.TestRightViewModel
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 dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@AndroidEntryPoint
@@ -42,9 +34,6 @@ class HomeFragment : Fragment() {
private val viewModel: TestRightViewModel by activityViewModels()
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var rvAdapter: UserListAdapter
private var batLevel: Int = 0 // Initialize with a default value, or obtain the actual battery level
private lateinit var sharedPreference: SharedPreferences
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
@@ -58,16 +47,17 @@ class HomeFragment : Fragment() {
return super.onCreateView(inflater, container, savedInstanceState)
}
sharedPreference =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
sharedPreference = requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
DataHolder.selectedTest = null
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.allUserData.observe(viewLifecycleOwner) { userData ->
if (userData.isNotEmpty()) {
}
deleteIncompleteRegistrations(userData)
}
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData ->
@@ -86,36 +76,13 @@ class HomeFragment : Fragment() {
setUserId()
}
}
hemoCubeViewModel.fireBaseBulkUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
Toast.makeText(
requireContext(),
"Test Results Uploaded Successfully",
Toast.LENGTH_SHORT
).show()
}
if (result == "Error") {
Toast.makeText(requireContext(), "Test Results Upload Failed", Toast.LENGTH_SHORT)
.show()
}
}
binding.btnLogout.setOnClickListener {
logoutUser(requireContext())
}
binding.uploadData.setOnClickListener {
showUploadDialog(requireContext())
}
binding.btnNewKit.setOnClickListener {
with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "")
putInt(Constants.KIT_COUNT, 0)
apply()
}
startActivity(Intent(requireContext(), KitScanActivity::class.java))
requireActivity().finish()
}
}
private fun setUserId() {
binding.btnSubmit.setOnClickListener {
val userId = binding.userId.text.toString()
@@ -130,49 +97,28 @@ 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 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<UserData>().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)
}
val recyclerViewOptions =
FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java)
.build()
rvAdapter = UserListAdapter(recyclerViewOptions, binding.root)
binding.rvOrder.adapter = rvAdapter
rvAdapter.startListening()
}
private fun saveUserId(userId: String) {
with(sharedPreference.edit()) {
putString(Constants.USER_ID, userId)
apply()
}
}
private fun logoutUser(context: Context) {
val builder = AlertDialog.Builder(context)
builder.setTitle("Log Out")
@@ -189,9 +135,8 @@ class HomeFragment : Fragment() {
val dialog = builder.create()
dialog.show()
}
private fun getData(search: String?, field: String) {
search?.replaceFirstChar {
val capitalizedSearch = search?.replaceFirstChar {
if (search.lowercase()
.startsWith(it.lowercase())
) it.titlecase(Locale.getDefault()) else it.toString()
@@ -202,16 +147,10 @@ class HomeFragment : Fragment() {
val recyclerViewOptions =
FirestoreRecyclerOptions.Builder<UserData>().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())
}!!
rvAdapter = UserListAdapter(recyclerViewOptions, binding.root)
binding.rvOrder.adapter = rvAdapter
rvAdapter.startListening()
}
private fun setSearch() {
binding.searchProduct.setOnQueryTextListener(object :
androidx.appcompat.widget.SearchView.OnQueryTextListener {
@@ -223,16 +162,13 @@ class HomeFragment : Fragment() {
binding.aadharIdRadioButton.isChecked -> "aadharId"
else -> null
}
field?.let { getData(query, it) }
false
} else {
loadUserData()
false
}
}
override fun onQueryTextChange(query: String?): Boolean {
return if (!query.isNullOrEmpty()) {
val field = when {
@@ -250,7 +186,6 @@ class HomeFragment : Fragment() {
}
})
}
private fun checkForLocalDBData() {
viewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
val uploadDataVisibility = if (userDataList.isEmpty()) View.GONE else View.VISIBLE
@@ -258,11 +193,10 @@ class HomeFragment : Fragment() {
}
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
val uploadDataVisibility = if (userDataList.any { !it.localFlag }) View.VISIBLE else View.GONE
val uploadDataVisibility = if (userDataList.isEmpty()) View.GONE else View.VISIBLE
binding.uploadData.visibility = uploadDataVisibility
}
}
private fun showUploadDialog(context: Context) {
val builder = AlertDialog.Builder(context)
builder.setTitle(R.string.upload_db_registration_title)
@@ -291,19 +225,28 @@ class HomeFragment : Fragment() {
}
dialog.dismiss()
Toast.makeText(
requireContext(), R.string.upload_success_message, Toast.LENGTH_SHORT
requireContext(),
R.string.upload_success_message,
Toast.LENGTH_SHORT
).show()
}
}
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
userDataList.forEach { userData ->
if (!userData.localFlag) {
if (userDataList.isEmpty()) {
dialog.dismiss()
} else {
userDataList.forEach { userData ->
userData.localFlag = true
hemoCubeViewModel.bulkAddResultTestToDb(userData)
}
dialog.dismiss()
Toast.makeText(
requireContext(),
R.string.upload_success_message,
Toast.LENGTH_SHORT
).show()
}
dialog.dismiss()
}
}
@@ -317,7 +260,7 @@ class HomeFragment : Fragment() {
private fun deleteHemoCubeIncompleteRegistrations(userDataList: List<HemoCubeTestData>) {
userDataList.forEach { userData ->
if (userData.testTime?.isEmpty() == true) {
if (userData.testTime?.isEmpty() == false) {
hemoCubeViewModel.deleteById(userData._id)
}
}

View File

@@ -9,7 +9,6 @@ import androidx.lifecycle.ViewModelProvider
import com.example.hpostesting.presentation.dashboard.ui.slideshow.SlideshowViewModel
import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding
class SlideshowFragment : Fragment() {
private var _binding: FragmentSlideshowBinding? = null
@@ -21,7 +20,7 @@ class SlideshowFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
savedInstanceState: Bundle?
): View {
val slideshowViewModel =
ViewModelProvider(this).get(SlideshowViewModel::class.java)
@@ -29,12 +28,6 @@ class SlideshowFragment : Fragment() {
_binding = FragmentSlideshowBinding.inflate(inflater, container, false)
val root: View = binding.root
val pInfo = requireActivity().packageManager.getPackageInfo(
requireActivity().packageName, 0
)
val version = pInfo.versionName
binding.textSlideshow.text = version
// val textView: TextView = binding.textSlideshow
// slideshowViewModel.text.observe(viewLifecycleOwner) {
// textView.text = it

View File

@@ -4,14 +4,12 @@ import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
@@ -23,10 +21,11 @@ import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.BuildConfig
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import kotlinx.coroutines.Dispatchers
@@ -40,15 +39,13 @@ class HemoCubeFragment : Fragment() {
private lateinit var binding: FragmentHemoCubeReferenceBinding
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences
val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
private var isOnline = false
private var currentDeviceData: DeviceData? = null
private var resultData: String = ""
private var isUsingExistingBuffer = false
private var isTestOngoing = false
private var startListening = MutableLiveData<Boolean>(false)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
binding = FragmentHemoCubeReferenceBinding.inflate(inflater, container, false)
sharedPreferences =
@@ -65,106 +62,86 @@ class HemoCubeFragment : Fragment() {
private fun initViews() {
binding.btnSubmit.setOnClickListener {
// val bloodGroupText = binding.etBloodGroup.text.toString()
// if (bloodGroupText.isEmpty()) {
// binding.etBloodGroup.error = "Please enter your blood group"
// } else {
activity?.runOnUiThread {
binding.progressBar.visibility = View.VISIBLE
}
hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "")
)
// }
val bloodGroupText = binding.etBloodGroup.text.toString()
if (bloodGroupText.isEmpty()) {
binding.etBloodGroup.error = "Please enter your blood group"
} else {
fetchResult()
}
}
if (isTestOngoing) {
// binding.btnKit.visibility = View.GONE
// binding.btnKit.isEnabled = false
// binding.btnKit.isClickable = false
binding.btnKit.visibility = View.GONE
binding.btnKit.isEnabled = false
binding.btnKit.isClickable = false
}
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
binding.btnKit.setOnClickListener {
if (isTestOngoing) {
val title = "WARNING"
val message = "There is a on going test, do you want to stop it"
val negativeText = getString(R.string.no)
val positiveText = "Yes"
binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}"
Log.e("nametext",binding.tvName.text.toString())
UIUtils.createAlertDialog(requireContext(),
title,
message,
negativeText,
positiveText,
object : MyDialogListener {
override fun onClickNegativeButton() {
// binding.btnKit.setOnClickListener {
// if (isTestOngoing) {
// val title = "WARNING"
// val message = "There is a on going test, do you want to stop it"
// val negativeText = getString(R.string.no)
// val positiveText = "Yes"
//
// UIUtils.createAlertDialog(requireContext(),
// title,
// message,
// negativeText,
// positiveText,
// object : MyDialogListener {
// override fun onClickNegativeButton() {
//
// }
//
// override fun onClickPositiveButton() {
// resetKitCount()
// val intent = Intent(context, KitScanActivity::class.java)
// startActivity(intent)
// (activity as HemocubeActivity).finish()
// }
// })
// } else {
// resetKitCount()
// val intent = Intent(context, KitScanActivity::class.java)
// startActivity(intent)
// (activity as HemocubeActivity).finish()
// }
// }
}
override fun onClickPositiveButton() {
resetKitCount()
val intent = Intent(context, KitScanActivity::class.java)
startActivity(intent)
(activity as HemocubeActivity).finish()
}
})
}
}
}
// private suspend fun checkBloodGroup() {
// binding.apply {
// val bloodGroup = etBloodGroup.text.toString()
// if (bloodGroup.isEmpty()) {
// etBloodGroup.error = "Please enter your blood group"
// } else {
// val db: FirebaseFirestore = Firebase.firestore
// val userdata = db.collection("patientData")
// .whereEqualTo("_id", hemoCubeViewModel.testDetails?._id).get().await()
// if (userdata.documents.isNotEmpty()) {
// db.collection("patientData").document(userdata.documents[0].id)
// .update("bloodGroup", bloodGroup)
// withContext(Dispatchers.Main) {
// val i = Intent(
// requireContext().applicationContext, DashboardActivity::class.java
// )
// startActivity(i)
// (activity as HemocubeActivity).finish()
// }
// }
// }
// }
// }
private suspend fun checkBloodGroup() {
binding.apply {
val bloodGroup = etBloodGroup.text.toString()
if (bloodGroup.isEmpty()) {
etBloodGroup.error = "Please enter your blood group"
} else {
val db: FirebaseFirestore = Firebase.firestore
val userdata = db.collection("patientData")
.whereEqualTo("_id", hemoCubeViewModel.testDetails?._id).get().await()
if (userdata.documents.isNotEmpty()) {
db.collection("patientData").document(userdata.documents[0].id)
.update("bloodGroup", bloodGroup)
withContext(Dispatchers.Main) {
val i = Intent(
requireContext().applicationContext, DashboardActivity::class.java
)
startActivity(i)
(activity as HemocubeActivity).finish()
}
}
}
}
}
private fun observeViewModel() {
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
showToast("Test Results Uploaded Successfully")
val i = Intent(
requireContext().applicationContext, DashboardActivity::class.java
)
startActivity(i)
(activity as HemocubeActivity).finish()
lifecycleScope.launch {
checkBloodGroup()
}
}
if (result == "Local") {
showToast("Internet not available, test details stored locally")
startActivity(Intent(requireActivity(), DashboardActivity::class.java))
}
if (result == "Error") {
showToast("Error uploading data, test details stored locally")
startActivity(Intent(requireActivity(), DashboardActivity::class.java))
}
binding.progressBar.visibility = View.GONE
}
@@ -173,41 +150,17 @@ class HemoCubeFragment : Fragment() {
hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) {
currentDeviceData = it
showToast(calculateRatio(0.17).toString())
}
hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
apply {
DataHolder.hemoCubeTestData?.let {
currentDeviceData?.coefficients?.let { coefficients ->
val coefficient1 = coefficients[0]
val coefficient2 = coefficients[1]
val result = coefficient1 * coefficient2
// showToast("coefficients: $coefficient1, $coefficient2")
}
}
isOnline = isNetworkAvailable
}
isOnline = isNetworkAvailable
}
hemoCubeViewModel.messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it
}
// startListening.observe(viewLifecycleOwner) {
// if (it) {
// lifecycleScope.launch {
// delay(1000)
// if (binding.tvSubtitle4.text.toString().isEmpty()) {
// (activity as HemocubeActivity).reconnectDevice()
// if (isBufferValueAvailable()) {
// showBufferAlertDialog()
// } else {
// listenToHemoCube()
// startBufferProcess()
// }
// }
// }
// }
// }
}
private fun checkAndStartProcess() {
@@ -265,26 +218,19 @@ class HemoCubeFragment : Fragment() {
hemoCubeViewModel.progressBar.postValue(true)
val fullReadOutput = StringBuilder()
startListening.postValue(true)
try {
(activity as HemocubeActivity).mService.listenToHemoCube(object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
fullReadOutput.append(stringData)
handleUsbData(stringData, fullReadOutput)
}
(activity as HemocubeActivity).mService.listenToHemoCube(object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
fullReadOutput.append(stringData)
handleUsbData(stringData, fullReadOutput)
}
}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
} catch (e: Exception) {
showToast("test is going on")
Firebase.crashlytics.recordException(e)
}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun handleUsbData(stringData: String, fullReadOutput: StringBuilder) {
@@ -296,15 +242,12 @@ class HemoCubeFragment : Fragment() {
resultData += fullReadOutput.toString()
when {
stringData.contains("ERROR 500") -> showError500Dialog()
stringData.contains("ERROR 501") -> showError501Dialog()
stringData.contains("#Buffer Completed") -> showStartSampleDialog()
stringData.contains("#Sample Completed") -> {
activity?.runOnUiThread {
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
}
fetchResult()
}
stringData.contains("RESULT") || resultData.contains("REND") -> {
@@ -327,70 +270,6 @@ class HemoCubeFragment : Fragment() {
}
}
private fun showError() {
activity?.runOnUiThread {
UIUtils.createAlertDialog(requireContext(),
"Device Error",
"Something is wrong with the device, please disconnect and reconnect the device and test the user again",
getString(R.string.noo),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
startActivity(Intent(requireActivity(), DashboardActivity::class.java))
}
})
}
}
private fun showError500Dialog() {
UIUtils.createAlertDialog(requireContext(),
"BUFFER ERROR",
"Do you want to continue with existing buffer?",
getString(R.string.noo),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
listenToHemoCube()
startBufferProcess()
}
})
}
fun handleBackButtonPress() {
if (isTestOngoing) {
// If the test is ongoing, don't allow the back button action
// You can optionally show a message to the user indicating why the back button is disabled
// For example, show a Toast or Snackbar.
showToast("Test is ongoing. Cannot go back.")
} else {
// If the test is not ongoing, you can trigger the back action of the hosting activity
activity?.onBackPressed()
}
}
private fun showError501Dialog() {
UIUtils.createAlertDialog(requireContext(),
"SAMPLE ERROR",
"Do you want to continue with Sample?",
getString(R.string.noo),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
listenToHemoCube()
startSampleProcess()
}
})
}
private fun showStartSampleDialog() {
activity?.runOnUiThread {
UIUtils.createAlertDialog(requireContext(),
@@ -402,8 +281,7 @@ class HemoCubeFragment : Fragment() {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
listenToHemoCube()
startSampleProcess()
}
})
}
@@ -412,97 +290,188 @@ class HemoCubeFragment : Fragment() {
private fun handleValidResult(validString: String, fullReadOutput: String) {
try {
val result = validString.split(" ")
if (result.size == 8) {
val deviceSerialNo = result[2]
val led1BufferForDevice = if (isUsingExistingBuffer) {
sharedPreferences.getString(Constants.BUFFER_VALUE_1, "")?.toDoubleOrNull()
} else {
result[3].toDoubleOrNull()
}
val led2BufferForDevice = if (isUsingExistingBuffer) {
sharedPreferences.getString(Constants.BUFFER_VALUE_2, "")?.toDoubleOrNull()
} else {
result[4].toDoubleOrNull()
}
val pInfo = requireActivity().packageManager.getPackageInfo(
requireActivity().packageName, 0
if (result.size != 8) return
val deviceSerialNo = result[2]
val led1BufferForDevice =
getLedBufferValue(isUsingExistingBuffer, Constants.BUFFER_VALUE_1, result[3])
val led2BufferForDevice =
getLedBufferValue(isUsingExistingBuffer, Constants.BUFFER_VALUE_2, result[4])
val version = BuildConfig.VERSION_NAME
val led1Sample = result[5].toDoubleOrNull()
val led2Sample = result[6].toDoubleOrNull()
val led1Average = calculateAverage(led1BufferForDevice, led1Sample)
val led2Average = calculateAverage(led2BufferForDevice, led2Sample)
val deviceRatio = led1Average / led2Average
val calculatedRatio = calculateRatio(deviceRatio)
val isBufferValid = validateBuffer(led1BufferForDevice, led2BufferForDevice)
val isSampleValid =
validateSample(led1Sample, led1BufferForDevice, led2Sample, led2BufferForDevice)
val isCalculatedRatioValid = validateCalculatedRatio(deviceRatio)
when {
!isBufferValid -> showError(
"Buffer error",
"Check for Empty curved, disconnected and reconnect the device, and please retest this sample again with a new blank"
)
val version = pInfo.versionName
val led1Sample = result[5].toDoubleOrNull()
val led2Sample = result[6].toDoubleOrNull()
val led1Average = log10(led1BufferForDevice?.div(led1Sample!!) ?: 0.0)
val led2Average = log10(led2BufferForDevice?.div(led2Sample!!) ?: 0.0)
val deviceRatio = led1Average / led2Average
// if (led1BufferForDevice!! > 20000 && led1BufferForDevice < 24000 && led2BufferForDevice!! > 20000 && led2BufferForDevice < 24000) {
// if (led1Sample!! < led1BufferForDevice && led1Sample < 24000 && led2Sample!! < led2BufferForDevice && led2Sample < 24000) {
// if (deviceRatio < 0.08) {
// if (deviceRatio > 1.07) {
//
// }
// }
// }
// }
DataHolder.hemoCubeTestData?.apply {
!isSampleValid -> showError(
"Sample error",
"Check for Empty curved, disconnected and reconnect the device, and please retest this sample again with a new blank"
)
deviceId = deviceSerialNo
led1Buffer = led1BufferForDevice
led2Buffer = led2BufferForDevice
appVersion = version
this.led1Sample = led1Sample
this.led2Sample = led2Sample
this.led1Average = led1Average
this.led2Average = led2Average
this.deviceRatio = deviceRatio
this.calculatedRatio = calculateRatio(deviceRatio)
this.classificationResult = findResult(calculatedRatio)
hemoCubeViewModel.messages.postValue(this.classificationResult)
this.resultData = fullReadOutput
if (!isUsingExistingBuffer) {
with(sharedPreferences.edit()) {
putString(Constants.BUFFER_VALUE_1, led1Buffer.toString())
putString(Constants.BUFFER_VALUE_2, led2Buffer.toString())
apply()
}
}
!validateBloodVolume(led1Average, led2Average) -> {
showError(
"Low Blood Volume",
"Please retest this sample with a higher volume of blood"
)
}
!validateHighBloodVolume(led1Average, led2Average) -> {
showError(
"High Blood Volume",
"Please retest this sample by diluting the sample in the buffer"
)
}
!isCalculatedRatioValid -> showError(
"calculated Ratio error",
"Check for Empty curved, disconnected and reconnect the device, and please retest this sample again with a new blank"
)
else -> processValidData(
deviceSerialNo,
led1BufferForDevice,
led2BufferForDevice,
version,
led1Sample,
led2Sample,
led1Average,
led2Average,
deviceRatio,
fullReadOutput,
calculatedRatio
)
}
} catch (e: Exception) {
Toast.makeText(
requireContext(),
"Error while processing device data",
Toast.LENGTH_SHORT
).show()
Firebase.crashlytics.recordException(e)
} catch (_: Exception) {
// handle exception or log it if necessary
}
}
private fun findResult(calculatedRatio: Double?): String {
try {
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 "NULL"
}
} catch (e: Exception) {
showToast("error while performing classification")
Firebase.crashlytics.recordException(e)
return "ERROR"
private fun getLedBufferValue(
usingExistingBuffer: Boolean, bufferConstant: String, resultValue: String
): Double? {
return if (usingExistingBuffer) {
sharedPreferences.getString(bufferConstant, "")?.toDoubleOrNull()
} else {
resultValue.toDoubleOrNull()
}
return "NULL"
}
private fun calculateAverage(bufferForDevice: Double?, sample: Double?): Double {
return log10(bufferForDevice?.div(sample ?: 1.0) ?: 0.0)
}
private fun validateBuffer(led1Buffer: Double?, led2Buffer: Double?): Boolean {
return led1Buffer!! in 20001.0..23999.0 && led2Buffer!! in 20001.0..23999.0
}
private fun validateSample(
sample1: Double?, buffer1: Double?, sample2: Double?, buffer2: Double?
): Boolean {
return sample1 != null && sample1 < buffer1!! && sample1 < 24000 && sample2 != null && sample2 < buffer2!! && sample2 < 24000
}
private fun validateBloodVolume(average1: Double, average2: Double): Boolean {
return average1 > 0.08 && average2 > 0.08
}
private fun validateCalculatedRatio(deviceRatio: Double): Boolean {
return deviceRatio > 0.08 && deviceRatio < 0.3
}
private fun validateHighBloodVolume(average1: Double, average2: Double): Boolean {
return average1 < 1.07 && average2 < 1.07
}
private fun showError(title: String, message: String) {
customErrorDialogBox(title, message)
}
private fun processValidData(
deviceId: String,
led1Buffer: Double?,
led2Buffer: Double?,
appVersion: String,
led1Sample: Double?,
led2Sample: Double?,
led1Average: Double,
led2Average: Double,
deviceRatio: Double,
resultData: String,
calculatedRatio: Double
) {
val threshold =
if ((activity as HemocubeActivity).bloodCollectingMethod == Constants.FINGER_PRICK_BLOOD) 0.05 else 0.06
if (led1Average > threshold) {
DataHolder.hemoCubeTestData?.apply {
this.deviceId = deviceId
this.led1Buffer = led1Buffer
this.led2Buffer = led2Buffer
this.appVersion = appVersion
this.led1Sample = led1Sample
this.led2Sample = led2Sample
this.led1Average = led1Average
this.led2Average = led2Average
this.deviceRatio = deviceRatio
this.calculatedRatio = calculatedRatio
this.resultData = resultData
if (!isBufferValueAvailable()) {
with(sharedPreferences.edit()) {
putString(Constants.BUFFER_VALUE_1, led1Buffer.toString())
putString(Constants.BUFFER_VALUE_2, led2Buffer.toString())
apply()
}
}
hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "")
)
}
} else {
showError(
"Low Blood Volume",
"Please repeat the test with 10 µl of blood added to 1 ml of buffer"
)
}
}
private fun customErrorDialogBox(title: String, message: String) {
activity?.runOnUiThread {
MaterialAlertDialogBuilder(requireContext()).setTitle(title).setMessage(message)
.setPositiveButton("OK") { dialog, _ ->
if (title == "Buffer error" || title == "Sample error") {
with(sharedPreferences.edit()) {
putString(Constants.BUFFER_VALUE_1, "")
putString(Constants.BUFFER_VALUE_2, "")
apply()
}
finishTestingActivity()
} else {
finishTestingActivity()
}
dialog.dismiss()
}.show()
}
}
private fun finishTestingActivity() {
val i = Intent(requireContext().applicationContext, DashboardActivity::class.java)
startActivity(i)
(activity as HemocubeActivity).finish()
}
private fun showToast(message: String) {

View File

@@ -12,9 +12,9 @@ import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.data.repository.DatabaseRepository
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -34,8 +34,7 @@ class HemoCubeViewModel @Inject constructor(
val progressBar = MutableLiveData(false)
val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
val messages = MutableLiveData<String>()
private val sharedPreference: SharedPreferences =
context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
private val sharedPreference: SharedPreferences = context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
// Get the device ID of the device you want to retrieve data for (e.g., the first device in the list)
@@ -45,7 +44,6 @@ class HemoCubeViewModel @Inject constructor(
val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData
val fireBaseUpload = MutableLiveData<String>()
val fireBaseBulkUpload = MutableLiveData<String>()
fun uploadHemoCubeResultToDatabase(isOnline: Boolean, testStatus: Boolean, kitSerial: String?) =
viewModelScope.launch {
if (kitSerial != null) {
@@ -55,10 +53,8 @@ class HemoCubeViewModel @Inject constructor(
try {
if (isOnline) {
parseData()
addResultTestToDb()
} else {
parseData()
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
@@ -70,18 +66,11 @@ class HemoCubeViewModel @Inject constructor(
}
}
fun uploadHemoCubeResultToDatabaseforbuffercheckN(bufferCheckData: BufferCheckData) =
viewModelScope.launch {
addResultTestToDbforbuffercheck(bufferCheckData)
}
fun getDeviceData(deviceId: String?) = viewModelScope.launch {
deviceData.postValue(deviceId?.let { repository.getDeviceDataById(it) })
}
private fun parseData() {
private fun addResultTestToDb() {
testDetails?.deviceRatio = DataHolder.hemocubeResult
testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString()
testDetails?.location = DataHolder.location
@@ -90,8 +79,7 @@ class HemoCubeViewModel @Inject constructor(
).format(Calendar.getInstance().time)
testDetails?.appVersion = DataHolder.hemoCubeTestData?.appVersion
testDetails?.deviceId = DataHolder.hemoCubeTestData?.deviceId
testDetails?.deviceSerialNumber =
sharedPreference.getString(Constants.USER_ID, "").toString()
testDetails?.deviceSerialNumber = sharedPreference.getString(Constants.USER_ID, "").toString()
testDetails?.kitSerial = sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
testDetails?.led1Buffer = DataHolder.hemoCubeTestData?.led1Buffer
testDetails?.led2Buffer = DataHolder.hemoCubeTestData?.led2Buffer
@@ -101,10 +89,7 @@ class HemoCubeViewModel @Inject constructor(
testDetails?.led2Average = DataHolder.hemoCubeTestData?.led2Average
testDetails?.deviceRatio = DataHolder.hemoCubeTestData?.deviceRatio
testDetails?.calculatedRatio = DataHolder.hemoCubeTestData?.calculatedRatio
testDetails?.classificationResult = DataHolder.hemoCubeTestData?.classificationResult!!
}
private fun addResultTestToDb() {
viewModelScope.launch {
try {
testDetails!!.reportUploadTime = SimpleDateFormat(
@@ -115,42 +100,21 @@ class HemoCubeViewModel @Inject constructor(
is Response.Success -> {
val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0)
with(sharedPreference.edit()) {
putInt(Constants.KIT_COUNT, kitCount.plus(1))
putInt(Constants.KIT_COUNT, kitCount.plus(1) ?: 0)
apply()
}
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
testDetails.localFlag = true
hemoCubeDao.insertAll(testDetails)
}
is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response")
Log.e("Testdb", "Error uploading data to Firestore: ${response}")
fireBaseUpload.postValue("Error")
hemoCubeDao.insertAll(testDetails)
}
}
} catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Error")
}
}
}
private fun addResultTestToDbforbuffercheck(bufferCheckData: BufferCheckData) {
viewModelScope.launch {
try {
when (val response = repository.addTestToDatabaseforBufferCheck(bufferCheckData)) {
is Response.Success -> {
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
}
is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
else -> {
Log.e("Testdb", "Unknown response from repository: $response")
fireBaseUpload.postValue("Unknown")
}
}
} catch (e: Exception) {
@@ -167,21 +131,14 @@ class HemoCubeViewModel @Inject constructor(
).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(userData)) {
is Response.Success -> {
fireBaseBulkUpload.postValue("Success")
updateLocalFlag(userData._id)
fireBaseUpload.postValue("Success")
}
else -> {
fireBaseBulkUpload.postValue("Error")
}
else -> {}
}
}
}
private fun updateLocalFlag(userId: String) = viewModelScope.launch {
hemoCubeDao.updateFieldById(id = userId, true)
}
fun deleteById(userId: String) = viewModelScope.launch {
hemoCubeDao.deleteById(id = userId)
}

View File

@@ -1,6 +1,5 @@
package com.example.hpostesting.presentation.hemocube
import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.ComponentName
@@ -8,7 +7,6 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.ServiceConnection
import android.content.SharedPreferences
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
@@ -19,14 +17,10 @@ import android.view.Menu
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContentProviderCompat.requireContext
import androidx.core.content.ContextCompat
import androidx.core.view.get
import androidx.navigation.fragment.findNavController
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.dashboard.ui.LoginFragment
import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber
@@ -35,17 +29,19 @@ import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityHemocubeBinding
@AndroidEntryPoint
open class HemocubeActivity : AppCompatActivity() {
class HemocubeActivity : AppCompatActivity() {
private lateinit var binding: ActivityHemocubeBinding
private val viewModel by viewModels<HemoCubeViewModel>()
private var myMenu: Menu? = null
private lateinit var sharedPreference: SharedPreferences
private lateinit var mDriver: UsbSerialDriver
private var mConnection: UsbDeviceConnection? = null
lateinit var mService: UsbService
private val TAG = "HemoCube"
var bloodCollectingMethod = ""
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
@@ -83,15 +79,13 @@ open class HemocubeActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
binding = ActivityHemocubeBinding.inflate(layoutInflater)
setContentView(binding.root)
bloodCollectingMethod = intent.getStringExtra(Constants.BLOOD_COLLECTING_METHOD).toString()
setSupportActionBar(binding.myToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
setupListener()
connectUsb(false)
applicationContext.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
}
@SuppressLint("SuspiciousIndentation")
private fun setupListener() {
DataHolder.usbConnected.observe(this) {
Log.d("USB OBSERVE", "HemoCube called -> $it")
@@ -101,13 +95,12 @@ open class HemocubeActivity : AppCompatActivity() {
} else {
myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
logoutUser()
Toast.makeText(this, "Device is Disconnected", Toast.LENGTH_SHORT).show()
}
}
}
open fun connectUsb(permissionGranted: Boolean) {
private fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager
val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager)
@@ -128,13 +121,15 @@ open class HemocubeActivity : AppCompatActivity() {
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
mPendingIntent = PendingIntent.getBroadcast(
this, 0, Intent(Constants.HOMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
val mPendingIntent: PendingIntent = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
PendingIntent.getBroadcast(
this,
0,
Intent(Constants.HOMOCUBE_USB_PERMISSION),
PendingIntent.FLAG_MUTABLE
)
} else {
mPendingIntent = PendingIntent.getBroadcast(
PendingIntent.getBroadcast(
this,
0,
Intent(Constants.HOMOCUBE_USB_PERMISSION),
@@ -147,39 +142,24 @@ open class HemocubeActivity : AppCompatActivity() {
manager.requestPermission(device, mPendingIntent)
}
fun setupService() {
private fun setupService() {
val intent = Intent(this, UsbService::class.java)
// startService(intent)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
open fun reconnectDevice() {
mService.disconnect()
unbindService(connection)
viewModel.isServiceConnected = false
connectUsb(true)
}
private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return
if (supportFragmentManager.isDestroyed)
return
supportFragmentManager.beginTransaction().replace(binding.fghemocube.id, HemoCubeFragment())
.commit()
supportFragmentManager.beginTransaction()
.replace(binding.fghemocube.id, HemoCubeFragment()).commit()
}
override fun onBackPressed() {
val fragment = supportFragmentManager.findFragmentById(R.id.fghemocube)
if (fragment is HemoCubeFragment) {
fragment.handleBackButtonPress()
} else {
super.onBackPressed()
}
}
fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
if (!isFinishing) onBackPressed()
if (!isFinishing)
onBackPressed()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
@@ -195,16 +175,4 @@ open class HemocubeActivity : AppCompatActivity() {
viewModel.isServiceConnected = false
}
}
private fun logoutUser() {
val intent = Intent(this, DashboardActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
finish()
}
}

View File

@@ -1,5 +0,0 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#000000" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/black" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hpostesting.presentation.BloodCollectingMethodActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:theme="@style/Theme.HPOS.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.HPOS.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<TextView
android:id="@+id/tv_title"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/select_blood_collecting_method"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/app_bar_layout" />
<RadioGroup
android:id="@+id/bloodTypeRadioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title">
<RadioButton
android:id="@+id/venousBloodRadioButton"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/venous_blood" />
<RadioButton
android:id="@+id/fingerPrickBloodRadioButton"
style="@style/title1_1"
android:checked="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/finger_prick_blood" />
</RadioGroup>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/go"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bloodTypeRadioGroup" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_parent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:titleTextColor="#FFFFFF"
android:elevation="4dp"
app:menu="@menu/my_menu"
android:theme="@style/ToolbarTheme"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<FrameLayout
android:id="@+id/fg_hc_buffer_check"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/my_toolbar"
app:layout_constraintBottom_toBottomOf="parent"
tools:context=".presentation.buffercheck.HemocubeBufferCheckActivity">
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.KitScanActivity">
tools:context="com.example.hpostesting.presentation.KitScanActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:padding="16dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_blood_group"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<AutoCompleteTextView
android:id="@+id/et_blood_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/select_blood_group"
android:inputType="none"
android:labelFor="@id/til_blood_group"
app:simpleItems="@array/blood_group" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>

View File

@@ -4,21 +4,19 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hpostesting.presentation.dashboard.GalleryFragment">
tools:context=".presentation.dashboard.GalleryFragment">
<Button
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
<TextView
android:id="@+id/text_gallery"
style="@style/title1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/check_buffer"
android:textColor="@color/white"
android:layout_margin="24dp"
android:textAlignment="center"
android:textSize="20sp"
android:text="@string/to_be_launched_in_next_version_of_the_app"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,187 +0,0 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.hpostesting.presentation.buffercheck.HemoCubeBufferCheckFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_parent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_title"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/Instructions"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_subtitle2"
style="@style/title2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/step4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<!-- <TextView-->
<!-- android:id="@+id/tv_subtitle3"-->
<!-- style="@style/title2"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="24dp"-->
<!-- android:layout_marginTop="16dp"-->
<!-- android:text="@string/step5"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />-->
<TextView
android:id="@+id/tv_name"
style="@style/title2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_submit" />
<TextView
android:id="@+id/tv_subtitle4"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:gravity="center"
android:textColor="@color/red"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />
<!-- <Button-->
<!-- android:visibility="gone"-->
<!-- android:id="@+id/btn_samplestart"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="16dp"-->
<!-- android:layout_marginTop="24dp"-->
<!-- android:clickable="false"-->
<!-- android:text="@string/Start_Sample"-->
<!-- android:textColor="@color/white"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/til_blood_group" />-->
<!-- <Button-->
<!-- android:id="@+id/btn_placebuffer"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="16dp"-->
<!-- android:layout_marginTop="24dp"-->
<!-- android:clickable="false"-->
<!-- android:text="@string/place_buffer"-->
<!-- android:textColor="@color/white"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/btn_submit" />-->
<Button
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/submit"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />
<!-- <com.google.android.material.textfield.TextInputLayout-->
<!-- android:id="@+id/til_blood_group"-->
<!-- style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="24dp"-->
<!-- android:layout_marginTop="16dp"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/tv_subtitle4">-->
<!-- <AutoCompleteTextView-->
<!-- android:id="@+id/et_blood_group"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:hint="@string/select_blood_group"-->
<!-- android:inputType="none"-->
<!-- android:labelFor="@id/til_blood_group"-->
<!-- app:simpleItems="@array/blood_group" />-->
<!-- </com.google.android.material.textfield.TextInputLayout>-->
<!-- <Button-->
<!-- android:id="@+id/btn_kit"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_margin="10dp"-->
<!-- android:text="@string/new_kit"-->
<!-- android:textColor="@color/white"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent" />-->
<!-- <Button-->
<!-- android:id="@+id/btn_buffer"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/new_buffer"-->
<!-- android:textColor="@color/white"-->
<!-- android:layout_margin="10dp"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintEnd_toStartOf="@id/btn_kit"/>-->
<!-- <Button-->
<!-- android:id="@+id/btn_read"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/read"-->
<!-- android:layout_margin="16dp"-->
<!-- android:clickable="false"-->
<!-- app:layout_constraintTop_toBottomOf="@id/btn_set_reference"-->
<!-- app:layout_constraintStart_toStartOf="parent" />-->
<!-- </androidx.constraintlayout.widget.ConstraintLayout>-->
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:elevation="12dp"
android:indeterminate="true"
android:indeterminateDrawable="@drawable/progressbar_drawable"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -27,32 +27,22 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/step4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<!-- <TextView-->
<!-- android:id="@+id/tv_subtitle3"-->
<!-- style="@style/title2"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="24dp"-->
<!-- android:layout_marginTop="16dp"-->
<!-- android:text="@string/step5"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />-->
<TextView
android:visibility="gone"
android:id="@+id/tv_name"
android:id="@+id/tv_subtitle3"
style="@style/title2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/step5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints" />
app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />
<TextView
android:id="@+id/tv_subtitle4"
@@ -63,90 +53,12 @@
android:layout_marginTop="16dp"
android:gravity="center"
android:textColor="@color/red"
android:textSize="18sp"
android:textSize="22sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_abha_id" />
<!-- <Button-->
<!-- android:visibility="gone"-->
<!-- android:id="@+id/btn_samplestart"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="16dp"-->
<!-- android:layout_marginTop="24dp"-->
<!-- android:clickable="false"-->
<!-- android:text="@string/Start_Sample"-->
<!-- android:textColor="@color/white"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/til_blood_group" />-->
<!-- <Button-->
<!-- android:id="@+id/btn_placebuffer"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="16dp"-->
<!-- android:layout_marginTop="24dp"-->
<!-- android:clickable="false"-->
<!-- android:text="@string/place_buffer"-->
<!-- android:textColor="@color/white"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/btn_submit" />-->
<TextView
android:id="@+id/tv_title2"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="48dp"
android:text="@string/enter_kit_serial_number_manually"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/et_abha_id"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toStartOf="@id/btn_go"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title2">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/name_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLength="17"
android:inputType="text"
android:hint="@string/serial_number" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/go"
app:cornerRadius="16dp"
app:layout_constraintBottom_toBottomOf="@id/et_abha_id"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@id/et_abha_id"
app:layout_constraintTop_toTopOf="@id/et_abha_id" />
app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" />
<Button
android:visibility="gone"
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -157,51 +69,52 @@
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />
app:layout_constraintTop_toBottomOf="@id/til_blood_group" />
<!-- <com.google.android.material.textfield.TextInputLayout-->
<!-- android:id="@+id/til_blood_group"-->
<!-- style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="24dp"-->
<!-- android:layout_marginTop="16dp"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/tv_subtitle4">-->
<!-- <AutoCompleteTextView-->
<!-- android:id="@+id/et_blood_group"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:hint="@string/select_blood_group"-->
<!-- android:inputType="none"-->
<!-- android:labelFor="@id/til_blood_group"-->
<!-- app:simpleItems="@array/blood_group" />-->
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_blood_group"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4">
<!-- </com.google.android.material.textfield.TextInputLayout>-->
<AutoCompleteTextView
android:id="@+id/et_blood_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/select_blood_group"
android:inputType="none"
android:labelFor="@id/til_blood_group"
app:simpleItems="@array/blood_group" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/btn_kit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/new_kit"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<!-- <Button-->
<!-- android:id="@+id/btn_kit"-->
<!-- android:id="@+id/btn_buffer"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_margin="10dp"-->
<!-- android:text="@string/new_kit"-->
<!-- android:text="@string/new_buffer"-->
<!-- android:textColor="@color/white"-->
<!-- android:layout_margin="10dp"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent" />-->
<!-- <Button-->
<!-- android:id="@+id/btn_buffer"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/new_buffer"-->
<!-- android:textColor="@color/white"-->
<!-- android:layout_margin="10dp"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintEnd_toStartOf="@id/btn_kit"/>-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintEnd_toStartOf="@id/btn_kit"/>-->
<!-- <Button-->
<!-- android:id="@+id/btn_read"-->
@@ -229,6 +142,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -194,27 +194,6 @@
app:layout_constraintTop_toBottomOf="@+id/radioGroup"
tools:listitem="@layout/user_item_view"/>
<TextView
android:id="@+id/label"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/new_kit"
app:layout_constraintBottom_toTopOf="@+id/btnNewKit"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnNewKit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:backgroundTint="@color/primary"
android:contentDescription="@string/new_kit"
android:src="@drawable/ic_add"
app:elevation="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -72,25 +72,6 @@
app:layout_constraintTop_toBottomOf="@id/userId"
tools:text="Test Status: Completed"/>
<Button
android:id="@+id/btn_startIncubation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:text="@string/start_incubation"
android:visibility="gone"
android:textColor="@color/white"
app:layout_constraintStart_toEndOf="@+id/btn_blood"
app:layout_constraintBottom_toBottomOf="@+id/btn_blood" />
<Button
android:id="@+id/btn_blood"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:text="@string/blood_group"
android:textColor="@color/white"
app:layout_constraintEnd_toStartOf="@+id/btn_startIncubation"
app:layout_constraintTop_toBottomOf="@id/teststatus" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -112,8 +112,6 @@
<string name="sickle_cert">Sickle Cert</string>
<string name="sickle_find">Sickle Find</string>
<string name="submit">Submit</string>
<string name="place_buffer">Start Buffer</string>
<string name="Start_Sample">Start Sample</string>
<string name="new_kit">New Kit</string>
<string name="new_buffer">New Buffer</string>
<string name="name_error_2">Invalid character, Allowed characters are Letters, Numbers and ( ) _ - , . only</string>
@@ -192,7 +190,8 @@
<string name="test_completed">Test Completed</string>
<string name="select_blood_group">Select Blood Group</string>
<string name="all_registered_user_are_tested_successfully">All registered user are tested successfully</string>
<string name="start_incubation">Incubate</string>
<string name="check_buffer">Check Buffer</string>
<string name="venous_blood">Venous Blood</string>
<string name="finger_prick_blood">Finger Prick Blood</string>
<string name="select_blood_collecting_method">Select blood collecting method</string>
</resources>