Compare commits

...

9 Commits

Author SHA1 Message Date
chandrashekhar reddy
8b363bd4b2 Changes 2024-09-10 17:08:35 +05:30
mohamedkaif356
dfa678df82 Merge remote-tracking branch 'origin/Hb_HemoCube' into Hb_HemoCube 2023-09-07 08:13:09 +05:30
mohamedkaif356
28d9bedffe Flush Buffer value 2023-09-07 08:12:57 +05:30
smileomi18@gmail.com
07b57137a0 APP VERSION added 2023-09-06 11:51:58 +05:30
smileomi18@gmail.com
5e4c2b613a Merge remote-tracking branch 'origin/Hb_HemoCube' into Hb_HemoCube 2023-09-06 11:47:31 +05:30
mohamedkaif356
ade2d2459e Start Sample Manually 2023-09-05 15:48:38 +05:30
smileomi18@gmail.com
cdb7853c59 APP VERSION added 2023-09-05 13:51:25 +05:30
mohamedkaif356
179ef54a59 HB Equation Added 2023-09-04 12:42:11 +05:30
mohamedkaif356
90ef4ddd92 HB implementation 2023-08-30 14:23:15 +05:30
27 changed files with 951 additions and 153 deletions

1
.idea/misc.xml generated
View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="DesignSurface"> <component name="DesignSurface">
<option name="filePathToZoomLevelMap"> <option name="filePathToZoomLevelMap">

Binary file not shown.

View File

@@ -4,15 +4,15 @@
"type": "APK", "type": "APK",
"kind": "Directory" "kind": "Directory"
}, },
"applicationId": "com.example.hpos", "applicationId": "in.sminnovations.hpostesting",
"variantName": "release", "variantName": "release",
"elements": [ "elements": [
{ {
"type": "SINGLE", "type": "SINGLE",
"filters": [], "filters": [],
"attributes": [], "attributes": [],
"versionCode": 1, "versionCode": 2,
"versionName": "1.0", "versionName": "2.0.1",
"outputFile": "app-release.apk" "outputFile": "app-release.apk"
} }
], ],

View File

@@ -27,7 +27,14 @@
android:theme="@style/Theme.HPOSTesting" android:theme="@style/Theme.HPOSTesting"
tools:targetApi="31"> tools:targetApi="31">
<activity <activity
android:name="com.example.hpostesting.presentation.hemocube.HemocubeActivity" android:name="com.example.hpostesting.presentation.hemocube.HemoCubeActivity"
android:exported="false"
android:noHistory="true"
android:parentActivityName="com.example.hpostesting.presentation.MainActivity"
android:theme="@style/Theme.HPOS.NoActionBar"
android:windowSoftInputMode="adjustPan" />
<activity
android:name="com.example.hpostesting.presentation.hemocube.hb.HBHemoCubeActivity"
android:exported="false" android:exported="false"
android:noHistory="true" android:noHistory="true"
android:parentActivityName="com.example.hpostesting.presentation.MainActivity" android:parentActivityName="com.example.hpostesting.presentation.MainActivity"

View File

@@ -1,6 +1,7 @@
package com.example.hpostesting.data package com.example.hpostesting.data
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.model.patient.HBHemoCubeTestData
import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.test.TestRightDeviceConstants import com.example.hpostesting.data.model.test.TestRightDeviceConstants
@@ -23,8 +24,8 @@ object DataHolder {
val intensityReferenceArray = ArrayList<Double>() val intensityReferenceArray = ArrayList<Double>()
var selectedTest: UserData? = null var selectedTest: UserData? = null
var hemoCubeTestData: HemoCubeTestData? = null var hemoCubeTestData: HemoCubeTestData? = null
var HbHemoCubeTestData: HBHemoCubeTestData? = null
var kitSerial: String = "" var kitSerial: String = ""
var location: UserData.Location? = null var location: UserData.Location? = null
var testExp: Boolean = true var testExp: Boolean = true
var hemocubeResult: Double? = null
} }

View File

@@ -55,4 +55,7 @@ object Constants {
const val KIT_COUNT = "KitCount" const val KIT_COUNT = "KitCount"
const val BUFFER_VALUE_1 = "BufferValue1" const val BUFFER_VALUE_1 = "BufferValue1"
const val BUFFER_VALUE_2 = "BufferValue2" const val BUFFER_VALUE_2 = "BufferValue2"
const val HB_BUFFER_VALUE_1 = "HBBufferValue1"
const val HB_KIT_NUMBER = "HBKitNumber"
} }

View File

@@ -4,5 +4,5 @@ enum class HemoCubeCommands(val command: String) {
startBuffer("B\r"), startBuffer("B\r"),
getBuffer("Q\r"), getBuffer("Q\r"),
startSample("S\r"), startSample("S\r"),
getSample("P\r"), getSample("R\r"),
} }

View File

@@ -0,0 +1,24 @@
package com.example.hpostesting.data.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.example.hpostesting.data.model.patient.HBHemoCubeTestData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
@Dao
interface HBHemoCubeDao {
@Query("SELECT * from HBHemoCubeTest_table")
fun getAll(): LiveData<List<HBHemoCubeTestData>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(hbHemoCubeTestData: HBHemoCubeTestData)
@Query("SELECT * FROM HBHemoCubeTest_table WHERE _id = :id")
suspend fun getUserByID(id: String): HBHemoCubeTestData
@Query("DELETE FROM HBHemoCubeTest_table WHERE _id = :id")
suspend fun deleteById(id: String)
}

View File

@@ -1,19 +1,22 @@
package com.example.hpostesting.data.dao package com.example.hpostesting.data.dao
import android.content.Context
import androidx.room.Database import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.room.TypeConverters import androidx.room.TypeConverters
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.HBHemoCubeTestData
import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.google.android.datatransport.runtime.dagger.Provides import com.example.hpostesting.data.model.patient.UserData
import javax.inject.Singleton
@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 3, exportSchema = false) @Database(
entities = [UserData::class, HemoCubeTestData::class, DeviceData::class, HBHemoCubeTestData::class],
version = 3,
exportSchema = false
)
@TypeConverters(Converters::class) @TypeConverters(Converters::class)
abstract class MyDatabase : RoomDatabase() { abstract class MyDatabase : RoomDatabase() {
abstract fun userDao(): UserDao abstract fun userDao(): UserDao
abstract fun hemoCubeDao(): HemoCubeDao abstract fun hemoCubeDao(): HemoCubeDao
abstract fun hbHemoCubeDao(): HBHemoCubeDao
} }

View File

@@ -14,6 +14,8 @@ data class DeviceData(
var deviceType: String = "", var deviceType: String = "",
@get:PropertyName("coefficients") @set:PropertyName("coefficients") @get:PropertyName("coefficients") @set:PropertyName("coefficients")
var coefficients: List<Double> = emptyList(), var coefficients: List<Double> = emptyList(),
@get:PropertyName("hbCoefficients") @set:PropertyName("hbCoefficients")
var hbCoefficients: List<Double> = emptyList(),
@get:PropertyName("calibratedAt") @set:PropertyName("calibratedAt") @get:PropertyName("calibratedAt") @set:PropertyName("calibratedAt")
var calibratedAt: String = "" var calibratedAt: String = ""
) )

View File

@@ -0,0 +1,28 @@
package com.example.hpostesting.data.model.patient
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "HBHemoCubeTest_table")
data class HBHemoCubeTestData(
@PrimaryKey
var _id: String = "",
var name: String = "",
var birthYear: String = "",
var userImageURL: String = "",
var location: UserData.Location? = null,
var reportUploadTime: String? = "",
var testType: String? = "HB EST",
var testTime: String? = "",
var testStatus: Boolean? = false,
var localFlag: Boolean = false,
var deviceId: String? = "",
var deviceSerialNumber: String = "",
var deviceType: String = "HEMOCUBE",
var kitSerial: String = "",
var resultData: String = "",
var led1Buffer: Double? = null,
var led1Sample: Double? = null,
var led1Average: Double? = null,
var hbEstimation: Double? = null
)

View File

@@ -28,5 +28,6 @@ data class HemoCubeTestData(
var led1Average: Double? = null, var led1Average: Double? = null,
var led2Average: Double? = null, var led2Average: Double? = null,
var deviceRatio: Double? = null, var deviceRatio: Double? = null,
var calculatedRatio: Double? = null var calculatedRatio: Double? = null,
var appVersion: String? = ""
) )

View File

@@ -45,3 +45,12 @@ fun UserData.toHemoCubeTestData() = HemoCubeTestData(
testStatus = testStatus, testStatus = testStatus,
location = location location = location
) )
fun UserData.toHBHemoCubeTestData() = HBHemoCubeTestData(
_id = _id,
name = name,
birthYear = birthYear,
userImageURL = userImageURL,
testStatus = testStatus,
location = location
)

View File

@@ -2,5 +2,6 @@ package com.example.hpostesting.data.model.test
enum class TestType { enum class TestType {
SICKLECERT, SICKLECERT,
SICKLEFIND SICKLEFIND,
HB
} }

View File

@@ -1,24 +1,18 @@
package com.example.hpostesting.data.repository package com.example.hpostesting.data.repository
import android.content.Context
import android.net.Uri 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.PendingUploads
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HBHemoCubeTestData
import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.google.android.datatransport.runtime.dagger.Provides
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import com.google.firebase.storage.ktx.storage import com.google.firebase.storage.ktx.storage
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.tasks.await import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext
import java.io.File import java.io.File
import javax.inject.Singleton
class DatabaseRepository : Repository { class DatabaseRepository : Repository {
@@ -27,14 +21,31 @@ class DatabaseRepository : Repository {
suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String> { suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String> {
return try { return try {
val userdata = db.collection("patientData").whereEqualTo("_id", data!!._id).get().await() val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) { if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach { userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true) db.collection("patientData").document(it.id).update("testStatus", true)
} }
} }
db.collection("testData").add(data!!).await() db.collection("testData").add(data).await()
Response.Success(data!!._id) Response.Success(data._id)
} catch (e: Exception) {
Response.Error(e)
}
}
suspend fun addTestToDatabase(data: HBHemoCubeTestData?): Response<String> {
return try {
val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true)
}
}
db.collection("testData").add(data).await()
Response.Success(data._id)
} catch (e: Exception) { } catch (e: Exception) {
Response.Error(e) Response.Error(e)
} }
@@ -43,43 +54,29 @@ class DatabaseRepository : Repository {
suspend fun addTestToDatabase(data: UserData?): Response<String> { suspend fun addTestToDatabase(data: UserData?): Response<String> {
return try { return try {
val userdata = db.collection("patientData").whereEqualTo("_id", data!!._id).get().await() val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) { if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach { userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true) db.collection("patientData").document(it.id).update("testStatus", true)
} }
} }
db.collection("testData").add(data!!).await() db.collection("testData").add(data).await()
Response.Success(data!!._id) Response.Success(data._id)
} catch (e: Exception) { } catch (e: Exception) {
Response.Error(e) Response.Error(e)
} }
} }
suspend fun uploadFileToStorage(patientID: String, filePath: String): Response<Boolean> { suspend fun uploadFileToStorage(patientID: String, filePath: String): Response<Boolean> {
try { return try {
val file = Uri.fromFile(File(filePath)) val file = Uri.fromFile(File(filePath))
val riversRef = storage.reference.child("$patientID/${file.lastPathSegment}") val riversRef = storage.reference.child("$patientID/${file.lastPathSegment}")
riversRef.putFile(file).await() riversRef.putFile(file).await()
return Response.Success(true)
} catch (e: Exception) {
e.printStackTrace()
return Response.Error(e)
}
}
suspend fun addToPendingQueue(pendingUploads: PendingUploads): Response<Boolean> {
return try {
db.collection("pendingUploads").document(pendingUploads.pendingId).set(pendingUploads)
.await()
Response.Success(true) Response.Success(true)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
Response.Error(e) Response.Error(e)
@@ -130,5 +127,4 @@ class DatabaseRepository : Repository {
} }
} }

View File

@@ -3,6 +3,7 @@ package com.example.hpostesting.domain.di
import android.app.Application import android.app.Application
import android.content.Context import android.content.Context
import androidx.room.Room import androidx.room.Room
import com.example.hpostesting.data.dao.HBHemoCubeDao
import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.dao.MyDatabase import com.example.hpostesting.data.dao.MyDatabase
import com.example.hpostesting.data.dao.UserDao import com.example.hpostesting.data.dao.UserDao
@@ -44,6 +45,12 @@ object AppModule {
return myDatabase.hemoCubeDao() return myDatabase.hemoCubeDao()
} }
@Provides
@Singleton
fun provideMyHBHemo(myDatabase: MyDatabase): HBHemoCubeDao {
return myDatabase.hbHemoCubeDao()
}
@Provides @Provides
@Singleton @Singleton
fun provideContext(application: Application): Context { fun provideContext(application: Application): Context {

View File

@@ -10,7 +10,8 @@ import androidx.appcompat.app.AppCompatActivity
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.hemocube.HemocubeActivity import com.example.hpostesting.presentation.hemocube.HemoCubeActivity
import com.example.hpostesting.presentation.hemocube.hb.HBHemoCubeActivity
import com.example.hpostesting.presentation.testRight.TestRightActivity import com.example.hpostesting.presentation.testRight.TestRightActivity
import com.journeyapps.barcodescanner.ScanContract import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanIntentResult import com.journeyapps.barcodescanner.ScanIntentResult
@@ -25,6 +26,8 @@ class KitScanActivity : AppCompatActivity() {
private lateinit var sharedPreference: SharedPreferences private lateinit var sharedPreference: SharedPreferences
private var hbTest = ""
private val barcodeLauncher = registerForActivityResult( private val barcodeLauncher = registerForActivityResult(
ScanContract() ScanContract()
) { result: ScanIntentResult -> ) { result: ScanIntentResult ->
@@ -47,6 +50,21 @@ class KitScanActivity : AppCompatActivity() {
sharedPreference = this.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE) sharedPreference = this.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
setContentView(binding.root) setContentView(binding.root)
hbTest = intent.getStringExtra("Test").toString()
if (hbTest.isNotEmpty()) {
if (checkHBHemoCubeKitData()) {
val i = Intent(applicationContext, HBHemoCubeActivity::class.java)
startActivity(i)
finish()
} else {
with(sharedPreference.edit()) {
putString(Constants.HB_KIT_NUMBER, "")
apply()
}
}
}
if (DataHolder.sampleReadCounter <= Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE && DataHolder.isReferenceTaken) { if (DataHolder.sampleReadCounter <= Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE && DataHolder.isReferenceTaken) {
DataHolder.selectedTest!!.kitSerial = DataHolder.kitSerial DataHolder.selectedTest!!.kitSerial = DataHolder.kitSerial
moveToNext() moveToNext()
@@ -98,6 +116,11 @@ class KitScanActivity : AppCompatActivity() {
&& sharedPreference.getInt(Constants.KIT_COUNT, 0) < 35 && sharedPreference.getInt(Constants.KIT_COUNT, 0) < 35
} }
private fun checkHBHemoCubeKitData(): Boolean {
return sharedPreference.getString(Constants.HB_KIT_NUMBER, "")
?.isNotBlank() == true
}
private fun isSerialValid(s: String): Boolean { private fun isSerialValid(s: String): Boolean {
if (s.length != 17) { if (s.length != 17) {
binding.nameEditText.error = getString(R.string.invalid_kit) binding.nameEditText.error = getString(R.string.invalid_kit)
@@ -108,16 +131,28 @@ class KitScanActivity : AppCompatActivity() {
private fun moveToNext() { private fun moveToNext() {
if (hbTest.isNotEmpty()) {
with(sharedPreference.edit()) {
putString(Constants.HB_KIT_NUMBER, binding.nameEditText.text.toString())
apply()
}
val i = Intent(applicationContext, HBHemoCubeActivity::class.java)
startActivity(i)
finish()
}
DataHolder.deviceType.observe(this) { deviceType -> DataHolder.deviceType.observe(this) { deviceType ->
when (deviceType) { when (deviceType) {
Constants.DEVICE_TYPE_HOMOCUBE -> { Constants.DEVICE_TYPE_HOMOCUBE -> {
val i = Intent(applicationContext, HemocubeActivity::class.java) val i = Intent(applicationContext, HemoCubeActivity::class.java)
startActivity(i) startActivity(i)
finish()
} }
Constants.DEVICE_TYPE_TEST_RIGHT -> { Constants.DEVICE_TYPE_TEST_RIGHT -> {
val i = Intent(applicationContext, TestRightActivity::class.java) val i = Intent(applicationContext, TestRightActivity::class.java)
startActivity(i) startActivity(i)
finish()
} }
} }
} }

View File

@@ -1,6 +1,7 @@
package com.example.hpostesting.presentation.adapter package com.example.hpostesting.presentation.adapter
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Intent
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -10,6 +11,8 @@ import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.test.TestType
import com.example.hpostesting.presentation.KitScanActivity
import com.example.hpostesting.presentation.testRight.TestRightViewModel import com.example.hpostesting.presentation.testRight.TestRightViewModel
import com.firebase.ui.firestore.FirestoreRecyclerAdapter import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions import com.firebase.ui.firestore.FirestoreRecyclerOptions
@@ -53,7 +56,10 @@ class UserListAdapter(
).show() ).show()
} else { } else {
DataHolder.selectedTest = model DataHolder.selectedTest = model
view.findNavController().navigate(R.id.action_nav_home_to_mainActivity) DataHolder.selectedTestType = TestType.HB
val intent = Intent(view.context, KitScanActivity::class.java)
intent.putExtra("Test", "HB")
view.context.startActivity(intent)
} }
} }
} }

View File

@@ -25,7 +25,7 @@ class GalleryFragment : Fragment() {
// val galleryViewModel = // val galleryViewModel =
// ViewModelProvider(this).get(GalleryViewModel::class.java) // ViewModelProvider(this).get(GalleryViewModel::class.java)
// _binding = FragmentGalleryBinding.inflate(inflater, container, false) _binding = FragmentGalleryBinding.inflate(inflater, container, false)
val root: View = binding.root val root: View = binding.root
// val textView: TextView = binding.textGallery // val textView: TextView = binding.textGallery

View File

@@ -3,7 +3,6 @@ package com.example.hpostesting.presentation.hemocube
import android.app.PendingIntent import android.app.PendingIntent
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.ComponentName import android.content.ComponentName
import android.content.ContentValues.TAG
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
@@ -11,32 +10,26 @@ import android.content.ServiceConnection
import android.hardware.usb.UsbDevice import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager import android.hardware.usb.UsbManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.os.IBinder import android.os.IBinder
import android.util.Log import android.util.Log
import android.view.Menu import android.view.Menu
import android.widget.Toast import android.widget.Toast
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants 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.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.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber import com.hoho.android.usbserial.driver.UsbSerialProber
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityHemocubeBinding import `in`.sminnovations.hpostesting.databinding.ActivityHemocubeBinding
import `in`.sminnovations.hpostesting.databinding.ActivityMainBinding
@AndroidEntryPoint @AndroidEntryPoint
class HemocubeActivity : AppCompatActivity() { class HemoCubeActivity : AppCompatActivity() {
private lateinit var binding: ActivityHemocubeBinding private lateinit var binding: ActivityHemocubeBinding
private val viewModel by viewModels<HemoCubeViewModel>() private val viewModel by viewModels<HemoCubeViewModel>()
private var myMenu: Menu? = null private var myMenu: Menu? = null
@@ -91,12 +84,14 @@ class HemocubeActivity : AppCompatActivity() {
} }
private fun setupListener() { private fun setupListener() {
DataHolder.usbConnected.observe(this){ DataHolder.usbConnected.observe(this) {
Log.d("USB OBSERVE", "HemoCube called -> $it") Log.d("USB OBSERVE", "HemoCube called -> $it")
if (it){ if (it) {
myMenu?.get(0)?.icon = ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24) myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24)
} else { } 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() Toast.makeText(this, "Device is Disconnected", Toast.LENGTH_SHORT).show()
} }
} }
@@ -123,22 +118,19 @@ class HemocubeActivity : AppCompatActivity() {
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) { private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent val mPendingIntent: PendingIntent =
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
mPendingIntent = PendingIntent.getBroadcast( PendingIntent.getBroadcast(
this, this, 0, Intent(Constants.HOMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
0, )
Intent(Constants.HOMOCUBE_USB_PERMISSION), } else {
PendingIntent.FLAG_MUTABLE PendingIntent.getBroadcast(
) this,
} else { 0,
mPendingIntent = PendingIntent.getBroadcast( Intent(Constants.HOMOCUBE_USB_PERMISSION),
this, PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
0, )
Intent(Constants.HOMOCUBE_USB_PERMISSION), }
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
)
}
val filter = IntentFilter(Constants.HOMOCUBE_USB_PERMISSION) val filter = IntentFilter(Constants.HOMOCUBE_USB_PERMISSION)
registerReceiver(broadcastReceiver, filter) registerReceiver(broadcastReceiver, filter)
@@ -152,23 +144,22 @@ class HemocubeActivity : AppCompatActivity() {
} }
private fun moveToNext() { private fun moveToNext() {
if (supportFragmentManager.isDestroyed) if (supportFragmentManager.isDestroyed) return
return
supportFragmentManager.beginTransaction() supportFragmentManager.beginTransaction().replace(binding.fghemocube.id, HemoCubeFragment())
.replace(binding.fghemocube.id, HemoCubeFragment()).commit() .commit()
} }
fun onErrorReported(msg: String) { fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
if (!isFinishing) if (!isFinishing) onBackPressed()
onBackPressed()
} }
override fun onCreateOptionsMenu(menu: Menu?): Boolean { override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.my_menu, menu) menuInflater.inflate(R.menu.my_menu, menu)
return true return true
} }
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
if (viewModel.isServiceConnected) { if (viewModel.isServiceConnected) {

View File

@@ -8,7 +8,6 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@@ -22,15 +21,15 @@ import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.utils.MyDialogListener import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils import com.example.hpostesting.presentation.utils.UIUtils
import com.google.firebase.firestore.BuildConfig
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
//import `in`.sminnovations.hpostesting.BuildConfig
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext
import kotlin.math.log10 import kotlin.math.log10
class HemoCubeFragment : Fragment() { class HemoCubeFragment : Fragment() {
@@ -62,15 +61,15 @@ class HemoCubeFragment : Fragment() {
private fun initViews() { private fun initViews() {
binding.btnSubmit.setOnClickListener { binding.btnSubmit.setOnClickListener {
val bloodGroupText = binding.etBloodGroup.text.toString() // val bloodGroupText = binding.etBloodGroup.text.toString()
if (bloodGroupText.isNullOrBlank() || bloodGroupText == "Select Blood Group") { // if (bloodGroupText.isNullOrBlank() || bloodGroupText == "Select Blood Group") {
binding.etBloodGroup.error = "Please enter your blood group" // binding.etBloodGroup.error = "Please enter your blood group"
Toast.makeText(context, "Please enter your blood group", Toast.LENGTH_SHORT).show() // Toast.makeText(context, "Please enter your blood group", Toast.LENGTH_SHORT).show()
} else { // } else {
binding.etBloodGroup.error = null // binding.etBloodGroup.error = null
bloodGroup = bloodGroupText // bloodGroup = bloodGroupText
checkBloodGroup() // checkBloodGroup()
} // }
it.isEnabled = false it.isEnabled = false
binding.progressBar.visibility = View.VISIBLE binding.progressBar.visibility = View.VISIBLE
fetchResult() fetchResult()
@@ -105,7 +104,7 @@ class HemoCubeFragment : Fragment() {
resetKitCount() resetKitCount()
val intent = Intent(context, KitScanActivity::class.java) val intent = Intent(context, KitScanActivity::class.java)
startActivity(intent) startActivity(intent)
(activity as HemocubeActivity).finish() (activity as HemoCubeActivity).finish()
} }
}) })
} }
@@ -144,8 +143,6 @@ class HemoCubeFragment : Fragment() {
binding.progressBar.visibility = View.GONE binding.progressBar.visibility = View.GONE
} }
hemoCubeViewModel.getDeviceData(sharedPreferences.getString(Constants.USER_ID,""))
hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) { hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) {
currentDeviceData = it currentDeviceData = it
showToast(calculateRatio(0.17).toString()) showToast(calculateRatio(0.17).toString())
@@ -153,17 +150,8 @@ class HemoCubeFragment : Fragment() {
} }
hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable -> hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
apply { hemoCubeViewModel.getDeviceData(sharedPreferences.getString(Constants.USER_ID,""))
DataHolder.hemoCubeTestData?.let { isOnline = isNetworkAvailable
currentDeviceData?.coefficients?.let { coefficients ->
val coefficient1 = coefficients[0]
val coefficient2 = coefficients[1]
val result = coefficient1 * coefficient2
showToast("Result: $result")
}
}
isOnline = isNetworkAvailable
}
} }
hemoCubeViewModel.messages.observe(viewLifecycleOwner) { hemoCubeViewModel.messages.observe(viewLifecycleOwner) {
@@ -226,7 +214,7 @@ class HemoCubeFragment : Fragment() {
hemoCubeViewModel.progressBar.postValue(true) hemoCubeViewModel.progressBar.postValue(true)
val fullReadOutput = StringBuilder() val fullReadOutput = StringBuilder()
(activity as HemocubeActivity).mService.listenToHemoCube(object : UsbServiceListener { (activity as HemoCubeActivity).mService.listenToHemoCube(object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
data?.let { data?.let {
val stringData = String(it) val stringData = String(it)
@@ -323,7 +311,7 @@ class HemoCubeFragment : Fragment() {
override fun onClickNegativeButton() {} override fun onClickNegativeButton() {}
override fun onClickPositiveButton() { override fun onClickPositiveButton() {
startSampleProcess()
} }
}) })
} }
@@ -349,9 +337,10 @@ class HemoCubeFragment : Fragment() {
val led1Average = log10(led1BufferForDevice?.div(led1Sample!!) ?: 0.0) val led1Average = log10(led1BufferForDevice?.div(led1Sample!!) ?: 0.0)
val led2Average = log10(led2BufferForDevice?.div(led2Sample!!) ?: 0.0) val led2Average = log10(led2BufferForDevice?.div(led2Sample!!) ?: 0.0)
val deviceRatio = led1Average / led2Average val deviceRatio = led1Average / led2Average
val version = BuildConfig.VERSION_NAME
DataHolder.hemoCubeTestData?.apply { DataHolder.hemoCubeTestData?.apply {
deviceId = deviceSerialNo deviceId = deviceSerialNo
appVersion = version
led1Buffer = led1BufferForDevice led1Buffer = led1BufferForDevice
led2Buffer = led2BufferForDevice led2Buffer = led2BufferForDevice
this.led1Sample = led1Sample this.led1Sample = led1Sample
@@ -387,7 +376,7 @@ class HemoCubeFragment : Fragment() {
private fun startBufferProcess() { private fun startBufferProcess() {
hemoCubeViewModel.progressBar.postValue(true) hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube( (activity as HemoCubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.startBuffer, HemoCubeCommands.startBuffer,
object : UsbServiceListener { object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {} override fun onUsbRead(data: ByteArray?) {}
@@ -401,7 +390,7 @@ class HemoCubeFragment : Fragment() {
private fun startSampleProcess() { private fun startSampleProcess() {
hemoCubeViewModel.progressBar.postValue(true) hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube( (activity as HemoCubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.startSample, HemoCubeCommands.startSample,
object : UsbServiceListener { object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {} override fun onUsbRead(data: ByteArray?) {}
@@ -415,7 +404,7 @@ class HemoCubeFragment : Fragment() {
private fun fetchResult() { private fun fetchResult() {
hemoCubeViewModel.progressBar.postValue(true) hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube( (activity as HemoCubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.getSample, HemoCubeCommands.getSample,
object : UsbServiceListener { object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {} override fun onUsbRead(data: ByteArray?) {}

View File

@@ -14,7 +14,6 @@ import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData 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.model.patient.toHemoCubeTestData
import com.example.hpostesting.data.repository.DatabaseRepository import com.example.hpostesting.data.repository.DatabaseRepository
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
@@ -71,13 +70,12 @@ class HemoCubeViewModel @Inject constructor(
} }
private fun addResultTestToDb() { private fun addResultTestToDb() {
testDetails?.deviceRatio = DataHolder.hemocubeResult
testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString() testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString()
testDetails?.location = DataHolder.location testDetails?.location = DataHolder.location
testDetails?.testTime = SimpleDateFormat( testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
testDetails?.appVersion = DataHolder.hemoCubeTestData?.appVersion
testDetails?.deviceId = DataHolder.hemoCubeTestData?.deviceId 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?.kitSerial = sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
@@ -100,7 +98,7 @@ class HemoCubeViewModel @Inject constructor(
is Response.Success -> { is Response.Success -> {
val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0) val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0)
with(sharedPreference.edit()) { with(sharedPreference.edit()) {
putInt(Constants.KIT_COUNT, kitCount.plus(1) ?: 0) putInt(Constants.KIT_COUNT, kitCount.plus(1))
apply() apply()
} }
Log.i("Testdb", "Data uploaded to Firestore successfully") Log.i("Testdb", "Data uploaded to Firestore successfully")
@@ -108,14 +106,10 @@ class HemoCubeViewModel @Inject constructor(
} }
is Response.Error -> { is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: ${response}") Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error") fireBaseUpload.postValue("Error")
} }
else -> {
Log.e("Testdb", "Unknown response from repository: $response")
fireBaseUpload.postValue("Unknown")
}
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}") Log.e("Testdb", "Exception during data upload: ${e.message}")

View File

@@ -0,0 +1,171 @@
package com.example.hpostesting.presentation.hemocube.hb
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.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
class HBHemoCubeActivity : AppCompatActivity() {
private lateinit var binding: ActivityHemocubeBinding
private val viewModel by viewModels<HBHemoCubeViewModel>()
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 {
onErrorReported("permission denied for device")
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()
}
}
}
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)
if (availableDrivers.isEmpty()) {
onErrorReported("No Device is Connected")
} 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_IMMUTABLE
)
} 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)
// startService(intent)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return
supportFragmentManager.beginTransaction()
.replace(binding.fghemocube.id, HBHemoCubeFragment()).commit()
}
fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
if (!isFinishing) onBackPressed()
}
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

@@ -0,0 +1,400 @@
package com.example.hpostesting.presentation.hemocube.hb
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.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
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.DeviceData
import com.example.hpostesting.data.model.patient.toHBHemoCubeTestData
import com.example.hpostesting.presentation.KitScanActivity
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 `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import kotlin.math.log10
class HBHemoCubeFragment : Fragment() {
private lateinit var binding: FragmentHemoCubeReferenceBinding
private val hemoCubeViewModel: HBHemoCubeViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences
private var isOnline = false
private var currentDeviceData: DeviceData? = null
private var resultData: String = ""
private var isUsingExistingBuffer = false
private var isTestOngoing = 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()
checkAndStartProcess()
}
private fun initViews() {
binding.btnSubmit.setOnClickListener {
it.isEnabled = false
binding.progressBar.visibility = View.VISIBLE
hemoCubeViewModel.uploadHBHemoCubeResultToDatabase(
isOnline, true, sharedPreferences.getString(Constants.HB_KIT_NUMBER, "")
)
}
if (isTestOngoing) {
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"
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 HBHemoCubeActivity).finish()
}
})
}
}
}
private fun observeViewModel() {
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
showToast("Test Results Uploaded Successfully")
startActivity(Intent(requireActivity(), DashboardActivity::class.java))
}
if (result == "Local") {
showToast("Internet not available, test details stored locally")
startActivity(Intent(requireActivity(), DashboardActivity::class.java))
}
binding.progressBar.visibility = View.GONE
}
hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) {
currentDeviceData = it
}
hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
hemoCubeViewModel.getDeviceData(sharedPreferences.getString(Constants.USER_ID, ""))
isOnline = isNetworkAvailable
}
hemoCubeViewModel.messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it
}
}
private fun checkAndStartProcess() {
if (isBufferValueAvailable()) {
showBufferAlertDialog()
} else {
listenToHemoCube()
startBufferProcess()
}
}
private fun isBufferValueAvailable(): Boolean {
return if (sharedPreferences.getString(Constants.HB_BUFFER_VALUE_1, "") != "") {
sharedPreferences.getString(Constants.HB_BUFFER_VALUE_1, "")
?.toDouble()!! > 0.0
} else {
false
}
}
private fun showBufferAlertDialog() {
val title = "WARNING"
val message = "Do you want to continue with existing buffer?"
val negativeText = getString(R.string.no)
val positiveText = "Yes"
UIUtils.createAlertDialog(requireContext(),
title,
message,
negativeText,
positiveText,
object : MyDialogListener {
override fun onClickNegativeButton() {
listenToHemoCube()
startBufferProcess()
with(sharedPreferences.edit()) {
putString(Constants.HB_BUFFER_VALUE_1, "")
apply()
}
}
override fun onClickPositiveButton() {
listenToHemoCube()
startSampleProcess()
isUsingExistingBuffer = true
}
})
}
private fun listenToHemoCube() {
if (DataHolder.HbHemoCubeTestData == null) {
DataHolder.HbHemoCubeTestData = DataHolder.selectedTest?.toHBHemoCubeTestData()
}
hemoCubeViewModel.progressBar.postValue(true)
val fullReadOutput = StringBuilder()
(activity as HBHemoCubeActivity).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)
}
})
}
private fun handleUsbData(stringData: String, fullReadOutput: StringBuilder) {
if (stringData.contains("#")) {
hemoCubeViewModel.messages.postValue(stringData)
isTestOngoing = true
}
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") -> {
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, resultData)
}
}
}
}
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(),
"Start Sample",
"Do you want to start sample reading?",
getString(R.string.no),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
startSampleProcess()
}
})
}
}
private fun handleValidResult(validString: String, fullReadOutput: String) {
try {
val result = validString.split(" ")
if (result.size == 6) {
val deviceSerialNo = result[2]
val led1BufferForDevice = if (isUsingExistingBuffer) {
sharedPreferences.getString(Constants.HB_BUFFER_VALUE_1, "")?.toDoubleOrNull()
} else {
result[3].toDoubleOrNull()
}
val led1Sample = result[4].toDoubleOrNull()
val led1Average = log10(led1BufferForDevice?.div(led1Sample!!) ?: 0.0)
binding.result.text = "HB Est. - ${((led1Average-0.0177)/0.0237).toString().substring(0, 6)}"
DataHolder.HbHemoCubeTestData?.apply {
deviceId = deviceSerialNo
led1Buffer = led1BufferForDevice
this.led1Sample = led1Sample
this.led1Average = led1Average
this.hbEstimation = ((led1Average-0.0177)/0.0237)
this.resultData = fullReadOutput
if (!isBufferValueAvailable()) {
with(sharedPreferences.edit()) {
putString(Constants.HB_BUFFER_VALUE_1, led1Buffer.toString())
apply()
}
}
}
}
} catch (_: Exception) {
}
}
private fun showToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
private fun startBufferProcess() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HBHemoCubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startBuffer,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun startSampleProcess() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HBHemoCubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startSample,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun fetchResult() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HBHemoCubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.getSample,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun calculateRatio(ratio: Double): Double {
val coefficient1 = currentDeviceData?.hbCoefficients?.get(0) ?: 0.0
val coefficient2 = currentDeviceData?.hbCoefficients?.get(1) ?: 0.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 == 6) {
return line
}
return ""
}
private fun isValidResult(line: String): String {
return if (line.contains("RESULT") && line.split(" ").size == 6) {
line
} else {
""
}
}
private fun resetKitCount() {
with(sharedPreferences.edit()) {
putString(Constants.KIT_NUMBER, "")
putInt(Constants.KIT_COUNT, 0)
apply()
}
}
}

View File

@@ -0,0 +1,138 @@
package com.example.hpostesting.presentation.hemocube.hb
import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.HBHemoCubeDao
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.toHBHemoCubeTestData
import com.example.hpostesting.data.repository.DatabaseRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import javax.inject.Inject
@HiltViewModel
class HBHemoCubeViewModel @Inject constructor(
private val hbHemoCubeDao: HBHemoCubeDao,
private val repository: DatabaseRepository,
context: Context,
) : ViewModel() {
var isServiceConnected = false
val progressBar = MutableLiveData(false)
val testDetails = DataHolder.selectedTest?.toHBHemoCubeTestData()
val messages = MutableLiveData<String>()
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)
private val _networkStatusLiveData = NetworkStatusLiveData(context)
val allUserData = hbHemoCubeDao.getAll()
val deviceData = MutableLiveData<DeviceData?>()
val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData
val fireBaseUpload = MutableLiveData<String>()
fun uploadHBHemoCubeResultToDatabase(
isOnline: Boolean, testStatus: Boolean, kitSerial: String?
) = viewModelScope.launch {
if (kitSerial != null) {
testDetails?.kitSerial = kitSerial
}
testDetails?.testStatus = testStatus
try {
if (isOnline) {
addResultTestToDb()
} else {
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
hbHemoCubeDao.insertAll(testDetails!!)
fireBaseUpload.postValue("Local")
}
} catch (e: Exception) {
Log.e("Testdb", "Upload failed: ${e.message}")
}
}
fun getDeviceData(deviceId: String?) = viewModelScope.launch {
deviceData.postValue(deviceId?.let { repository.getDeviceDataById(it) })
}
private fun addResultTestToDb() {
testDetails?.resultData = DataHolder.HbHemoCubeTestData?.resultData.toString()
testDetails?.location = DataHolder.location
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
testDetails?.deviceId = DataHolder.HbHemoCubeTestData?.deviceId
testDetails?.deviceSerialNumber =
sharedPreference.getString(Constants.USER_ID, "").toString()
testDetails?.kitSerial = sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
testDetails?.led1Buffer = DataHolder.HbHemoCubeTestData?.led1Buffer
testDetails?.led1Sample = DataHolder.HbHemoCubeTestData?.led1Sample
testDetails?.led1Average = DataHolder.HbHemoCubeTestData?.led1Average
testDetails?.hbEstimation = DataHolder.HbHemoCubeTestData?.hbEstimation
viewModelScope.launch {
try {
testDetails!!.reportUploadTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
when (val response = repository.addTestToDatabase(testDetails)) {
is Response.Success -> {
val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0)
with(sharedPreference.edit()) {
putInt(Constants.KIT_COUNT, kitCount.plus(1))
apply()
}
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")
}
}
} catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Error")
}
}
}
fun bulkAddResultTestToDb(userData: HemoCubeTestData) {
viewModelScope.launch {
userData.reportUploadTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(userData)) {
is Response.Success -> {
fireBaseUpload.postValue("Success")
}
else -> {}
}
}
}
fun deleteById(userId: String) = viewModelScope.launch {
hbHemoCubeDao.deleteById(id = userId)
}
}

View File

@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".presentation.dashboard.GalleryFragment"> >
<TextView <TextView
android:id="@+id/text_gallery" android:id="@+id/text_gallery"

View File

@@ -16,7 +16,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/Instructions" android:text="HB TESTING INSTRUCTIONS"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@@ -69,30 +69,7 @@
android:textColor="@color/white" android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_blood_group" /> 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 <Button
android:id="@+id/btn_kit" android:id="@+id/btn_kit"
@@ -105,7 +82,23 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
<!-- <Button--> <TextView
android:id="@+id/result"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:gravity="center"
tools:text="HB Est. : 16.254 g/dl"
android:textColor="@color/red"
android:textSize="28sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_submit" />
<!-- <Button-->
<!-- android:id="@+id/btn_buffer"--> <!-- android:id="@+id/btn_buffer"-->
<!-- android:layout_width="wrap_content"--> <!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"--> <!-- android:layout_height="wrap_content"-->