Compare commits

...

18 Commits

Author SHA1 Message Date
Pritimay Sarkar
0624a8fb5e Merge branch 'Homocube' into 'CrashIssues'
# Conflicts:
#   app/build.gradle
#   app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt
#   app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt
#   app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt
2023-09-16 05:42:49 +00:00
smileomi18@gmail.com
34bed4e5fe app version -updation- notifying user 2023-09-15 17:26:38 +05:30
smileomi18@gmail.com
f019e1897d Added placebuffer and sample buttons for the new feature 2023-09-15 17:03:03 +05:30
mohamedkaif356
d5553d9a23 Error resolved 2023-09-15 12:44:54 +05:30
smileomi18@gmail.com
a54c720d8f App version automatic updation addede 2023-09-15 12:32:33 +05:30
smileomi18@gmail.com
f183a1dab3 log deleted 2023-09-14 13:59:24 +05:30
mohamedkaif356
281946ffde Release 2.1.6 2023-09-13 20:42:21 +05:30
mohamedkaif356
7e32a10186 Release 2.1.5 2023-09-13 20:26:26 +05:30
mohamedkaif356
d823821026 App distrubation 2023-09-13 20:25:37 +05:30
smileomi18@gmail.com
61e5fbf4a1 production Issues resolved 2023-09-13 20:06:49 +05:30
smileomi18@gmail.com
e5da37064a production errors 2023-09-13 14:40:46 +05:30
smileomi18@gmail.com
19289a5c33 production errors 2023-09-12 18:02:39 +05:30
smileomi18@gmail.com
da3a89245e production errors 2023-09-12 16:56:06 +05:30
Pritimay Sarkar
1d542f5562 Merge branch 'kitscan_fix' into Homocube 2023-09-11 09:22:06 +05:30
Pritimay Sarkar
4289d1c399 release version 2.1.3 2023-09-11 09:20:55 +05:30
Pritimay Sarkar
38f2122444 add version name in the settings 2023-09-10 23:59:54 +05:30
Pritimay Sarkar
d6bacd578c show users in ordered, latest first 2023-09-10 23:58:02 +05:30
Pritimay Sarkar
f8a7bff5b2 add new kit button
- device data processing error toast
2023-09-10 23:55:24 +05:30
16 changed files with 378 additions and 118 deletions

View File

@@ -18,8 +18,8 @@ android {
applicationId "in.sminnovations.hpostesting"
minSdk 21
targetSdk 34
versionCode 2
versionName "2.0.1"
versionCode 7
versionName "2.1.7"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -52,11 +52,11 @@ android {
dependencies {
implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2'
//firebase
implementation platform('com.google.firebase:firebase-bom:32.1.0')
@@ -66,10 +66,13 @@ dependencies {
implementation 'com.google.firebase:firebase-auth-ktx'
implementation 'com.google.firebase:firebase-storage-ktx'
implementation 'com.firebaseui:firebase-ui-firestore:8.0.2'
implementation 'com.google.android.gms:play-services-auth:20.6.0'
implementation 'com.google.android.gms:play-services-auth:20.7.0'
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'
@@ -77,7 +80,7 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"
implementation 'com.opencsv:opencsv:4.6'
implementation 'com.github.mik3y:usb-serial-for-android:3.5.1'
@@ -102,8 +105,8 @@ dependencies {
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2'
// Navigation Component
implementation "androidx.navigation:navigation-fragment-ktx:2.7.1"
implementation "androidx.navigation:navigation-ui-ktx:2.7.1"
implementation "androidx.navigation:navigation-fragment-ktx:2.7.2"
implementation "androidx.navigation:navigation-ui-ktx:2.7.2"
//Dagger - Hilt
implementation "com.google.dagger:hilt-android:2.46"

View File

@@ -5,6 +5,8 @@ import android.content.Context
import androidx.room.Room
import com.example.hpostesting.data.dao.MyDatabase
import com.google.android.datatransport.runtime.dagger.Provides
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.FirebaseFirestoreSettings
import dagger.hilt.android.HiltAndroidApp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -15,5 +17,14 @@ import javax.inject.Singleton
class HPOSTestingApplication: Application() {
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
override fun onCreate() {
super.onCreate()
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
val firestoreSettings = FirebaseFirestoreSettings.Builder()
.setPersistenceEnabled(true) // Enable offline persistence if needed
.build()
val firestore = FirebaseFirestore.getInstance()
firestore.firestoreSettings = firestoreSettings
}
}

View File

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

View File

@@ -3,7 +3,7 @@ package com.example.hpostesting.data.model.patient
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "HemocubeTest_table")
@Entity(tableName = "hemo_cube_test_table")
data class HemoCubeTestData(
@PrimaryKey
var _id: String = "",

View File

@@ -5,6 +5,7 @@ import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.hpostesting.data.DataHolder
@@ -12,6 +13,8 @@ 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
import com.journeyapps.barcodescanner.ScanIntentResult
import com.journeyapps.barcodescanner.ScanOptions
@@ -52,20 +55,48 @@ class KitScanActivity : AppCompatActivity() {
moveToNext()
}
if (checkHemoCubeKitData()) {
DataHolder.selectedTest!!.kitSerial =
sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
moveToNext()
} else {
with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "")
putInt(Constants.KIT_COUNT, 0)
putString(Constants.BUFFER_VALUE_1, "")
putString(Constants.BUFFER_VALUE_2, "")
apply()
// if (checkHemoCubeKitData()) {
// DataHolder.selectedTest!!.kitSerial =
// sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
// moveToNext()
// } else {
// with(sharedPreference.edit()) {
// putString(Constants.KIT_NUMBER, "")
// putInt(Constants.KIT_COUNT, 0)
// putString(Constants.BUFFER_VALUE_1, "")
// putString(Constants.BUFFER_VALUE_2, "")
// apply()
// }
// }
try {
if (checkHemoCubeKitData()) {
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()
}
binding.nameEditText.setText("SMI/SC/")
setSupportActionBar(binding.toolbar)

View File

@@ -20,7 +20,10 @@ 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
import com.hoho.android.usbserial.driver.UsbSerialProber
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityMainBinding
@@ -83,6 +86,11 @@ class MainActivity : AppCompatActivity() {
}
}
if (DataHolder.selectedTest == null) {
startActivity(Intent(this, DashboardActivity::class.java))
finish()
}
// val crashButton = Button(this)
// crashButton.text = "Test Crash"
@@ -159,12 +167,14 @@ 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) {
@@ -234,18 +244,46 @@ class MainActivity : AppCompatActivity() {
return
}
// fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
// location?.let {
// DataHolder.selectedTest!!.location =
// UserData.Location(location.latitude, location.longitude)
// DataHolder.location =
// UserData.Location(location.latitude, location.longitude)
// } ?: run {
// requestLocationUpdates()
// }
// }.addOnFailureListener { exception: Exception ->
// exception.printStackTrace()
// }
fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
location?.let {
DataHolder.selectedTest!!.location =
UserData.Location(location.latitude, location.longitude)
if (DataHolder.selectedTest != null) {
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()
}
}.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()
}
}
private fun requestLocationUpdates() {

View File

@@ -39,7 +39,7 @@ class SplashActivity : AppCompatActivity() {
binding = ActivitySplashBinding.inflate(layoutInflater)
setContentView(binding.root)
setupFirestoreCache()
// setupFirestoreCache()
setupStaticConstants()
requestPermissions()
@@ -50,12 +50,12 @@ class SplashActivity : AppCompatActivity() {
Settings.Secure.getString(applicationContext.contentResolver, Settings.Secure.ANDROID_ID)
}
private fun setupFirestoreCache() {
val settings = FirebaseFirestoreSettings.Builder()
.setCacheSizeBytes(FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED)
.build()
Firebase.firestore.firestoreSettings = settings
}
// private fun setupFirestoreCache() {
// val settings = FirebaseFirestoreSettings.Builder()
// .setCacheSizeBytes(FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED)
// .build()
// Firebase.firestore.firestoreSettings = settings
// }
private fun requestPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {

View File

@@ -2,6 +2,7 @@ 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
@@ -10,6 +11,8 @@ 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 dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
@@ -25,7 +28,6 @@ class DashboardActivity : AppCompatActivity() {
binding = ActivityDashboardBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.appBarDashboard.toolbar)
val drawerLayout: DrawerLayout = binding.drawerLayout
@@ -53,4 +55,31 @@ class DashboardActivity : AppCompatActivity() {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
override fun onResume() {
super.onResume()
// Copy and paste this into any part of your app - for example, in your main
// activity's onResume method.
val firebaseAppDistribution = FirebaseAppDistribution.getInstance()
firebaseAppDistribution.updateIfNewReleaseAvailable()
.addOnProgressListener { updateProgress ->
Toast.makeText(this, "Updating", 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.
}
}
}
}
}
}

View File

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

View File

@@ -20,6 +20,7 @@ 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.firestore.Query
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import dagger.hilt.android.AndroidEntryPoint
@@ -37,8 +38,16 @@ class HomeFragment : Fragment() {
private lateinit var sharedPreference: SharedPreferences
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
): View? {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
// Check if _binding is null
if (_binding == null) {
// Handle the case where binding could not be initialized
// You may want to log an error or return a default view in this case
return super.onCreateView(inflater, container, savedInstanceState)
}
sharedPreference = requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
DataHolder.selectedTest = null
@@ -90,6 +99,7 @@ class HomeFragment : Fragment() {
}
}
private fun loadUserData() {
// val query = Firebase.firestore.collection("patientData").whereEqualTo("testStatus", false).orderBy("createdAt", Query.Direction.DESCENDING)
val query = Firebase.firestore.collection("patientData").whereEqualTo("testStatus", false)
query.get().addOnSuccessListener {
if (it.documents.isEmpty()) {
@@ -154,8 +164,10 @@ class HomeFragment : Fragment() {
binding.aadharIdRadioButton.isChecked -> "aadharId"
else -> null
}
field?.let { getData(query, it) }
false
} else {
loadUserData()
false
@@ -252,7 +264,7 @@ class HomeFragment : Fragment() {
private fun deleteHemoCubeIncompleteRegistrations(userDataList: List<HemoCubeTestData>) {
userDataList.forEach { userData ->
if (userData.testTime?.isEmpty() == false) {
if (userData.testTime?.isEmpty() == true) {
hemoCubeViewModel.deleteById(userData._id)
}
}

View File

@@ -9,6 +9,7 @@ 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
@@ -20,7 +21,7 @@ class SlideshowFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View {
val slideshowViewModel =
ViewModelProvider(this).get(SlideshowViewModel::class.java)
@@ -28,6 +29,12 @@ 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

@@ -10,6 +10,7 @@ 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
@@ -28,6 +29,7 @@ import `in`.sminnovations.hpostesting.BuildConfig
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext
@@ -43,7 +45,7 @@ class HemoCubeFragment : Fragment() {
private var resultData: String = ""
private var isUsingExistingBuffer = false
private var isTestOngoing = false
private var bloodGroup: String = ""
private var startListening = MutableLiveData<Boolean>(false)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
@@ -57,7 +59,7 @@ class HemoCubeFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)
initViews()
observeViewModel()
checkAndStartProcess()
// checkAndStartProcess()
}
private fun initViews() {
@@ -78,10 +80,22 @@ class HemoCubeFragment : Fragment() {
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
binding.btnSamplestart.setOnClickListener {
startSampleProcess()
it.visibility = View.GONE
}
binding.btnPlacebuffer.setOnClickListener {
checkAndStartProcess()
it.visibility = View.GONE
}
binding.btnKit.setOnClickListener {
if (isTestOngoing) {
val title = "WARNING"
val message = "There is a on going test, do you want to stop it"
val message =
"There is a on going test, do you want to stop it. if Yes please disconnect the device and connect it again, once you reached to kitDetails Screen"
val negativeText = getString(R.string.no)
val positiveText = "Yes"
@@ -102,6 +116,11 @@ class HemoCubeFragment : Fragment() {
(activity as HemocubeActivity).finish()
}
})
} else {
resetKitCount()
val intent = Intent(context, KitScanActivity::class.java)
startActivity(intent)
(activity as HemocubeActivity).finish()
}
}
}
@@ -150,7 +169,7 @@ class HemoCubeFragment : Fragment() {
hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) {
currentDeviceData = it
showToast(calculateRatio(0.17).toString())
// showToast(calculateRatio(0.17).toString())
}
@@ -161,15 +180,31 @@ class HemoCubeFragment : Fragment() {
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() {
if (isBufferValueAvailable()) {
showBufferAlertDialog()
} else {
listenToHemoCube()
startBufferProcess()
}
// if (isBufferValueAvailable()) {
// showBufferAlertDialog()
// } else {
listenToHemoCube()
startBufferProcess()
// }
}
private fun isBufferValueAvailable(): Boolean {
@@ -218,19 +253,25 @@ class HemoCubeFragment : Fragment() {
hemoCubeViewModel.progressBar.postValue(true)
val fullReadOutput = StringBuilder()
(activity as HemocubeActivity).mService.listenToHemoCube(object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
fullReadOutput.append(stringData)
handleUsbData(stringData, fullReadOutput)
}
}
startListening.postValue(true)
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
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)
}
}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
} catch (e: Exception) {
showToast("test is going on")
}
}
private fun handleUsbData(stringData: String, fullReadOutput: StringBuilder) {
@@ -244,7 +285,12 @@ class HemoCubeFragment : Fragment() {
when {
stringData.contains("ERROR 500") -> showError500Dialog()
stringData.contains("ERROR 501") -> showError501Dialog()
stringData.contains("#Buffer Completed") -> showStartSampleDialog()
stringData.contains("#Buffer Completed") ->
activity?.runOnUiThread {
binding.btnSamplestart.visibility = View.VISIBLE
binding.btnSamplestart.isClickable = true
}
stringData.contains("#Sample Completed") -> {
activity?.runOnUiThread {
binding.btnSubmit.isEnabled = true
@@ -272,6 +318,25 @@ 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",
@@ -288,6 +353,19 @@ class HemoCubeFragment : Fragment() {
})
}
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",
@@ -315,7 +393,7 @@ class HemoCubeFragment : Fragment() {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
startSampleProcess()
}
})
}
@@ -342,15 +420,15 @@ class HemoCubeFragment : Fragment() {
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) {
}
}
}
}
// 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 {
deviceId = deviceSerialNo
led1Buffer = led1BufferForDevice
@@ -361,7 +439,7 @@ class HemoCubeFragment : Fragment() {
this.led1Average = led1Average
this.led2Average = led2Average
this.deviceRatio = deviceRatio
this.calculatedRatio = calculateRatio(deviceRatio)
// this.calculatedRatio = calculateRatio(deviceRatio)
this.resultData = fullReadOutput
if (!isBufferValueAvailable()) {
with(sharedPreferences.edit()) {
@@ -370,6 +448,9 @@ class HemoCubeFragment : Fragment() {
apply()
}
}
activity?.runOnUiThread {
binding.progressBar.visibility = View.VISIBLE
}
hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "")
)
@@ -377,7 +458,11 @@ class HemoCubeFragment : Fragment() {
}
} catch (_: Exception) {
Toast.makeText(
requireContext(),
"Error while processing device data",
Toast.LENGTH_SHORT
).show()
}
}
@@ -425,11 +510,11 @@ class HemoCubeFragment : Fragment() {
})
}
private fun calculateRatio(ratio: Double): Double {
val coefficient1 = currentDeviceData?.coefficients?.get(0) ?: 0.0
val coefficient2 = currentDeviceData?.coefficients?.get(1) ?: 0.0
return coefficient1 * ratio + coefficient2
}
// private fun calculateRatio(ratio: Double): Double {
// val coefficient1 = currentDeviceData?.coefficients?.get(0) ?: 0.0
// val coefficient2 = currentDeviceData?.coefficients?.get(1) ?: 0.0
// return coefficient1 * ratio + coefficient2
// }
private fun parseResult(frames: List<String>): String {
val lines = mutableListOf<String>()

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.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,7 +33,8 @@ 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)
@@ -53,8 +53,10 @@ 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,7 +72,7 @@ class HemoCubeViewModel @Inject constructor(
deviceData.postValue(deviceId?.let { repository.getDeviceDataById(it) })
}
private fun addResultTestToDb() {
private fun parseData() {
testDetails?.deviceRatio = DataHolder.hemocubeResult
testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString()
testDetails?.location = DataHolder.location
@@ -79,7 +81,8 @@ 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
@@ -89,7 +92,9 @@ class HemoCubeViewModel @Inject constructor(
testDetails?.led2Average = DataHolder.hemoCubeTestData?.led2Average
testDetails?.deviceRatio = DataHolder.hemoCubeTestData?.deviceRatio
testDetails?.calculatedRatio = DataHolder.hemoCubeTestData?.calculatedRatio
}
private fun addResultTestToDb() {
viewModelScope.launch {
try {
testDetails!!.reportUploadTime = SimpleDateFormat(
@@ -100,7 +105,7 @@ 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) ?: 0)
putInt(Constants.KIT_COUNT, kitCount.plus(1))
apply()
}
Log.i("Testdb", "Data uploaded to Firestore successfully")
@@ -108,14 +113,9 @@ class HemoCubeViewModel @Inject constructor(
}
is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: ${response}")
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) {
Log.e("Testdb", "Exception during data upload: ${e.message}")
@@ -132,6 +132,7 @@ class HemoCubeViewModel @Inject constructor(
when (repository.addTestToDatabase(userData)) {
is Response.Success -> {
fireBaseUpload.postValue("Success")
deleteById(userData._id)
}
else -> {}

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,32 +10,26 @@ 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() {
open class HemocubeActivity : AppCompatActivity() {
private lateinit var binding: ActivityHemocubeBinding
private val viewModel by viewModels<HemoCubeViewModel>()
private var myMenu: Menu? = null
@@ -91,18 +84,20 @@ 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()
}
}
}
private fun connectUsb(permissionGranted: Boolean) {
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)
@@ -126,10 +121,7 @@ class HemocubeActivity : AppCompatActivity() {
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
this, 0, Intent(Constants.HOMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
)
} else {
mPendingIntent = PendingIntent.getBroadcast(
@@ -145,30 +137,46 @@ class HemocubeActivity : AppCompatActivity() {
manager.requestPermission(device, mPendingIntent)
}
private fun setupService() {
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, HemoCubeFragment()).commit()
open fun reconnectDevice() {
mService.disconnect()
unbindService(connection)
viewModel.isServiceConnected = false
connectUsb(true)
}
private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return
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 {
menuInflater.inflate(R.menu.my_menu, menu)
return true
}
override fun onDestroy() {
super.onDestroy()
if (viewModel.isServiceConnected) {

View File

@@ -58,6 +58,40 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" />
<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"
@@ -69,8 +103,7 @@
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_blood_group" />
app:layout_constraintTop_toBottomOf="@id/btn_samplestart" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_blood_group"

View File

@@ -112,6 +112,8 @@
<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>