Compare commits

...

2 Commits

Author SHA1 Message Date
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
9 changed files with 338 additions and 116 deletions

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"
@@ -26,6 +29,11 @@
android:supportsRtl="true"
android:theme="@style/Theme.HPOSTesting"
tools:targetApi="31">
<activity
android:name="com.example.hpostesting.presentation.BloodCollectingMethodActivity"
android:exported="true"
android:noHistory="true"
android:theme="@style/Theme.HPOS.NoActionBar" />
<activity
android:name="com.example.hpostesting.presentation.hemocube.HemocubeActivity"
android:exported="false"

View File

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

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

@@ -10,8 +10,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.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanIntentResult
import com.journeyapps.barcodescanner.ScanOptions
@@ -107,22 +105,10 @@ class KitScanActivity : AppCompatActivity() {
}
private fun moveToNext() {
DataHolder.deviceType.observe(this) { deviceType ->
when (deviceType) {
Constants.DEVICE_TYPE_HOMOCUBE -> {
val i = Intent(applicationContext, HemocubeActivity::class.java)
val i = Intent(applicationContext, BloodCollectingMethodActivity::class.java)
startActivity(i)
}
Constants.DEVICE_TYPE_TEST_RIGHT -> {
val i = Intent(applicationContext, TestRightActivity::class.java)
startActivity(i)
}
}
}
}
private fun startScanningNow() {
val options = ScanOptions()
options.setDesiredBarcodeFormats(ScanOptions.QR_CODE)

View File

@@ -21,6 +21,7 @@ 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.android.material.dialog.MaterialAlertDialogBuilder
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
@@ -43,7 +44,6 @@ class HemoCubeFragment : Fragment() {
private var resultData: String = ""
private var isUsingExistingBuffer = false
private var isTestOngoing = false
private var bloodGroup: String = ""
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
@@ -242,8 +242,6 @@ 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 {
@@ -272,38 +270,6 @@ class HemoCubeFragment : Fragment() {
}
}
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()
}
})
}
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(),
@@ -324,45 +290,146 @@ class HemoCubeFragment : Fragment() {
private fun handleValidResult(validString: String, fullReadOutput: String) {
try {
val result = validString.split(" ")
if (result.size == 8) {
if (result.size != 8) return
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 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 = 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) {
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"
)
!isSampleValid -> showError(
"Sample error",
"Check for Empty curved, disconnected and reconnect the device, and please retest this sample again with a new blank"
)
!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 (_: Exception) {
// handle exception or log it if necessary
}
}
private fun getLedBufferValue(
usingExistingBuffer: Boolean, bufferConstant: String, resultValue: String
): Double? {
return if (usingExistingBuffer) {
sharedPreferences.getString(bufferConstant, "")?.toDoubleOrNull()
} else {
resultValue.toDoubleOrNull()
}
}
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 {
deviceId = deviceSerialNo
led1Buffer = led1BufferForDevice
led2Buffer = led2BufferForDevice
appVersion = version
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 = calculateRatio(deviceRatio)
this.resultData = fullReadOutput
this.calculatedRatio = calculatedRatio
this.resultData = resultData
if (!isBufferValueAvailable()) {
with(sharedPreferences.edit()) {
putString(Constants.BUFFER_VALUE_1, led1Buffer.toString())
@@ -374,12 +441,37 @@ class HemoCubeFragment : Fragment() {
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"
)
}
}
} catch (_: Exception) {
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

@@ -3,7 +3,6 @@ package com.example.hpostesting.presentation.hemocube
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.ContentValues.TAG
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
@@ -11,29 +10,23 @@ import android.content.ServiceConnection
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
import androidx.appcompat.app.AppCompatActivity
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.testRight.TestRightExpReference
import com.example.hpostesting.presentation.testRight.TestRightExpSample
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import com.example.hpostesting.presentation.testRight.UsbService
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationCallback
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
import `in`.sminnovations.hpostesting.databinding.ActivityMainBinding
@AndroidEntryPoint
class HemocubeActivity : AppCompatActivity() {
@@ -47,6 +40,8 @@ class HemocubeActivity : AppCompatActivity() {
private val TAG = "HemoCube"
var bloodCollectingMethod = ""
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
@@ -84,6 +79,7 @@ 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()
@@ -91,12 +87,14 @@ class HemocubeActivity : AppCompatActivity() {
}
private fun setupListener() {
DataHolder.usbConnected.observe(this){
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)
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)
myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
Toast.makeText(this, "Device is Disconnected", Toast.LENGTH_SHORT).show()
}
}
@@ -123,16 +121,15 @@ 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(
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),
@@ -169,6 +166,7 @@ class HemocubeActivity : AppCompatActivity() {
menuInflater.inflate(R.menu.my_menu, menu)
return true
}
override fun onDestroy() {
super.onDestroy()
if (viewModel.isServiceConnected) {

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

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

@@ -190,5 +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="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>