Compare commits

..

3 Commits

32 changed files with 123 additions and 1237 deletions

View File

@@ -15,12 +15,13 @@ android {
namespace 'in.sminnovations.hpostesting'
// dev -> development, quality -> qc, uat -> User Acceptance Testing, preprod -> preproduction, prod -> production, iocl -> iocl-iisc production
//for testing in iisc->in.sminnovations.hpostesting.test / prod -> in.sminnovations.hpostesting.iocl
defaultConfig {
applicationId "in.sminnovations.hpostesting.dev"
applicationId "in.sminnovations.hpostesting.iocl"
minSdk 21
targetSdk 34
versionCode 128
versionName "2.1.128"
versionCode 129
versionName "2.1.129"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View File

@@ -1,205 +1,45 @@
{
"project_info": {
"project_number": "650071678820",
"project_id": "hpos-af3cc",
"storage_bucket": "hpos-af3cc.appspot.com"
"project_number": "630821402019",
"project_id": "iocl-iisc",
"storage_bucket": "iocl-iisc.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:f1435a1c07f710036c6471",
"mobilesdk_app_id": "1:630821402019:android:ab77866fb7b3114b1dd616",
"android_client_info": {
"package_name": "com.example.hposconsentform"
"package_name": "in.sminnovations.hposregistration.iocl"
}
},
"oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
"current_key": "AIzaSyABIdxI89eTZ8BqU2cIoJOgJ1lS1cFLCtQ"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
"other_platform_oauth_client": []
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:7865bef608cdee6f6c6471",
"mobilesdk_app_id": "1:630821402019:android:ed56bae066ac32b51dd616",
"android_client_info": {
"package_name": "com.smi.counselling"
"package_name": "in.sminnovations.hpostesting.iocl"
}
},
"oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
"current_key": "AIzaSyABIdxI89eTZ8BqU2cIoJOgJ1lS1cFLCtQ"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:2925e9ce3417d2386c6471",
"android_client_info": {
"package_name": "in.sminnovations.hemocube"
}
},
"oauth_client": [
{
"client_id": "650071678820-srhm9spm9hjn4frcd3r6o02gdhdbtd15.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "in.sminnovations.hemocube",
"certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a"
}
},
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:7569c1cad4fc99916c6471",
"android_client_info": {
"package_name": "in.sminnovations.hposregistration"
}
},
"oauth_client": [
{
"client_id": "650071678820-70kp5jvjda4r5diqch2kn4lc40p4f42g.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "in.sminnovations.hposregistration",
"certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a"
}
},
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:f96be19e5d43102b6c6471",
"android_client_info": {
"package_name": "in.sminnovations.hpostesting"
}
},
"oauth_client": [
{
"client_id": "650071678820-l87dnr0bdj95get0khgnvfv2an1k6ogq.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "in.sminnovations.hpostesting",
"certificate_hash": "7714b9268a81d0cf0fb178b0af8dbb630f8fc70a"
}
},
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:650071678820:android:a53292637abb7c0d6c6471",
"android_client_info": {
"package_name": "in.sminnovations.hpostesting.dev"
}
},
"oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAVdNGCev_AFX0qmuZJF6kxzRzXUTeAW5I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "650071678820-to41afi9f0gi5r3k6v7pe1e5p96nupcs.apps.googleusercontent.com",
"client_type": 3
}
]
"other_platform_oauth_client": []
}
}
}

View File

@@ -4,15 +4,15 @@
"type": "APK",
"kind": "Directory"
},
"applicationId": "in.sminnovations.hpostesting.dev",
"applicationId": "in.sminnovations.hpostesting.iocl",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 128,
"versionName": "2.1.128",
"versionCode": 129,
"versionName": "2.1.129",
"outputFile": "app-release.apk"
}
],

View File

@@ -74,10 +74,6 @@
android:name="com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity"
android:exported="false"
android:theme="@style/Theme.HPOS.NoActionBar" />
<activity
android:name="com.example.hpostesting.presentation.hb_test.HBTestActivity"
android:exported="false"
android:theme="@style/Theme.HPOS.NoActionBar" />
<activity
android:name="com.example.hpostesting.presentation.autodac.AutoDacActivity"
android:exported="false"

View File

@@ -28,8 +28,8 @@ object Constants {
const val DOCUMENT_ID_FOR_UPDATE ="2o71vBKLqdgEKYtFG8Lb"
const val ABHA_APP_PACKAGE = "in.ndhm.phr"
const val MOLBIO_INTEGRATION = false
const val FIREBASE_INTEGRATION = true
const val MOLBIO_INTEGRATION = true
const val FIREBASE_INTEGRATION = false
const val deviceProvisionEmail = "HPOS_provisioner@bigtec.co.in"
const val deviceProvisionPassword = "f2ab0e7f9d69"
const val DEVICE_ID_API = "deviceIDAPI"

View File

@@ -21,7 +21,6 @@ import com.example.hpostesting.data.model.test.TestType
object DataHolder {
var sampleId: String = "sampleId"
var selectedTestType: TestType = TestType.SICKLECERT
val usbConnected = MutableLiveData(true)
var mobileUniqueId: String? = null
@@ -38,8 +37,6 @@ object DataHolder {
val intensityReferenceArray = ArrayList<Double>()
var selectedTest: UserData? = null
var hemoCubeTestData: HemoCubeTestData? = null
var bloodGroup: String = "Unknown"
var age = "0"
var kitSerial: String = ""
var centerName: String = ""
var district: String = ""

View File

@@ -35,8 +35,6 @@ enum class TestStatus(val code: Double) {
BUFFER_PRINT_STARTED(6.0),
BUFFER_PRINT_COMPLETED(7.0),
SAMPLE_STARTED(8.0),
CUVETTE_ABSENTT(30.2),
CUVETTE_PRESENTT(30.1),
SAMPLE_COMPLETED(9.0),
SAMPLE_PRINT_STARTED(10.0),
SAMPLE_PRINT_COMPLETED(11.0),

View File

@@ -40,8 +40,10 @@ interface HemoCubeDao {
@Query("DELETE FROM hemo_cube_test_table WHERE _id = :id")
suspend fun deleteById(id: String)
@Query("DELETE FROM hemo_cube_test_table WHERE testStatus = 0")
suspend fun deleteByStatus()
@Query("UPDATE hemo_cube_test_table SET localFlag = :newValue WHERE _id = :id")
suspend fun updateFieldById(id: String, newValue: Boolean)

View File

@@ -54,7 +54,7 @@ class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
"name",
"incubationTime",
"bloodGroup",
"age", // Include other fields from the data class
"birthYear", // Include other fields from the data class
"state",
"abhaId",
"userImageURL",
@@ -177,7 +177,7 @@ class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
"name",
"incubationTime",
"bloodGroup",
"age", // Include other fields from the data class
"birthYear", // Include other fields from the data class
"state",
"abhaId",
"userImageURL",

View File

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

View File

@@ -122,10 +122,15 @@ class DatabaseRepository @Inject constructor(
}
override suspend fun addQcTestToDatabase(data: HemoCubeTestData?): Response<String> {
return try {
db.collection("qcData").add(data!!).await()
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("qcData").add(data).await()
Response.Success(data._id)
} catch (e: Exception) {
Response.Error(e)
}

View File

@@ -26,9 +26,7 @@ import androidx.appcompat.app.AppCompatActivity
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.test.TestType
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.hb_test.HBTestActivity
import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import com.example.hpostesting.presentation.testRight.TestRightActivity
import com.google.android.material.snackbar.Snackbar
@@ -367,26 +365,21 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
private fun moveToNext() {
if(fromWhere == "Main"){
if(DataHolder.selectedTestType == TestType.HB_EST){
val i = Intent(applicationContext, HBTestActivity::class.java)
startActivity(i)
}else{
DataHolder.deviceType.observe(this) { deviceType ->
when (deviceType) {
Constants.DEVICE_TYPE_HEMOCUBE -> {
val i = Intent(applicationContext, HemocubeActivity::class.java)
startActivity(i)
}
DataHolder.deviceType.observe(this) { deviceType ->
when (deviceType) {
Constants.DEVICE_TYPE_HEMOCUBE -> {
val i = Intent(applicationContext, HemocubeActivity::class.java)
startActivity(i)
}
Constants.DEVICE_TYPE_TEST_RIGHT -> {
val i = Intent(applicationContext, TestRightActivity::class.java)
startActivity(i)
}
Constants.DEVICE_TYPE_TEST_RIGHT -> {
val i = Intent(applicationContext, TestRightActivity::class.java)
startActivity(i)
}
Constants.DEVICE_TYPE_TRUEHEME -> {
val i = Intent(applicationContext, HemocubeActivity::class.java)
startActivity(i)
}
Constants.DEVICE_TYPE_TRUEHEME -> {
val i = Intent(applicationContext, HemocubeActivity::class.java)
startActivity(i)
}
}
}

View File

@@ -103,7 +103,7 @@ class MainActivity : AppCompatActivity() {
with(binding) {
if (deviceType == Constants.DEVICE_TYPE_HEMOCUBE) {
cvItem1.visibility = View.VISIBLE
cvItem3.visibility = View.VISIBLE
cvItem3.visibility = View.GONE
cvItem2.visibility = View.GONE
cvItem4.visibility = View.GONE
}
@@ -132,7 +132,7 @@ class MainActivity : AppCompatActivity() {
when {
device.productId == Constants.HOMO_CUBE_ID && device.vendorId == Constants.VENDOR_ID -> {
binding.cvItem1.visibility = View.VISIBLE
binding.cvItem3.visibility = View.VISIBLE
binding.cvItem3.visibility = View.GONE
binding.cvItem2.visibility = View.GONE
binding.cvItem4.visibility = View.GONE
DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HEMOCUBE)
@@ -141,7 +141,7 @@ class MainActivity : AppCompatActivity() {
device.productId == Constants.HEMO_CUBE_V2_PRODUCT_ID && device.vendorId == Constants.HEMO_CUBE_V2_VENDOR_ID -> {
binding.cvItem1.visibility = View.VISIBLE
binding.cvItem3.visibility = View.VISIBLE
binding.cvItem3.visibility = View.GONE
binding.cvItem2.visibility = View.GONE
binding.cvItem4.visibility = View.GONE
DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HEMOCUBE)
@@ -150,7 +150,7 @@ class MainActivity : AppCompatActivity() {
device.productId == 24577 && device.vendorId == 1027 -> {
binding.cvItem1.visibility = View.VISIBLE
binding.cvItem3.visibility = View.VISIBLE
binding.cvItem3.visibility = View.GONE
binding.cvItem2.visibility = View.GONE
binding.cvItem4.visibility = View.GONE
DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_TRUEHEME)
@@ -159,7 +159,7 @@ class MainActivity : AppCompatActivity() {
device.productId == 8963 && device.vendorId == 1659 -> {
binding.cvItem1.visibility = View.VISIBLE
binding.cvItem3.visibility = View.VISIBLE
binding.cvItem3.visibility = View.GONE
binding.cvItem2.visibility = View.GONE
binding.cvItem4.visibility = View.GONE
DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HEMOCUBE)
@@ -168,7 +168,7 @@ class MainActivity : AppCompatActivity() {
device.productId == 4614 && device.vendorId == 7111 -> {
binding.cvItem1.visibility = View.VISIBLE
binding.cvItem3.visibility = View.VISIBLE
binding.cvItem3.visibility = View.GONE
binding.cvItem2.visibility = View.GONE
binding.cvItem4.visibility = View.GONE
DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HEMOCUBE)
@@ -232,13 +232,6 @@ class MainActivity : AppCompatActivity() {
startActivity(i)
finish()
}
binding.cvItem3.setOnClickListener {
DataHolder.selectedTestType = TestType.HB_EST
val i = Intent(applicationContext, KitScanActivity::class.java)
i.putExtra("fromWhere","Main")
startActivity(i)
finish()
}
DataHolder.usbConnected.observe(this) {
if (it) {

View File

@@ -58,11 +58,10 @@ class ActivitiesFragment : Fragment() {
if (userData.isNotEmpty()) {
userData.forEach { user ->
if((isBetween15And30Minutes(user.incubationTime) > 30 || isBetween15And30Minutes(user.incubationTime) < 0) && user.testStatus == false){
if(isBetween15And30Minutes(user.incubationTime) > 30 && user.testStatus == false){
hemoCubeViewModel.deleteByStatus()
}
}
binding.rvOrderOffline.visibility = View.VISIBLE
binding.noDataText.visibility = View.GONE
val bm =
@@ -89,5 +88,4 @@ class ActivitiesFragment : Fragment() {
return diffMillis / (60 * 1000)
}
}

View File

@@ -31,13 +31,13 @@ import android.os.BatteryManager
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.ContactsContract.Data
import android.provider.Settings
import android.util.Base64
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.content.res.AppCompatResources
@@ -134,7 +134,6 @@ class HomeFragment : Fragment() {
binding.labelQuickCapture.visibility = View.VISIBLE
binding.btnQuickCapture.visibility = View.VISIBLE
}
getDeviceId()
checkUnprocessedCSVData()
//checkForUpdate()
@@ -184,6 +183,7 @@ class HomeFragment : Fragment() {
Toast.makeText(requireContext(), R.string.test_upload_failed, Toast.LENGTH_SHORT)
.show()
}
}
// binding.btnLogout.setOnClickListener {
// logoutUser(requireContext())
@@ -202,8 +202,7 @@ class HomeFragment : Fragment() {
// }else{
// binding.downloadCSV.visibility = View.GONE
// }
val btnSaveLocalVisibility =
if (userData.any { it.testStatus == true }) View.VISIBLE else View.GONE
val btnSaveLocalVisibility = if (userData.any { it.testStatus == true }) View.VISIBLE else View.GONE
binding.downloadCSV.visibility = btnSaveLocalVisibility
binding.downloadCSV.setOnClickListener {
if (btnSaveLocalVisibility == View.VISIBLE) {
@@ -304,13 +303,13 @@ class HomeFragment : Fragment() {
}
if (isConnected != wasConnected) {
if (isConnected) {
binding.tvTitleNoInternet.text = "Please enter the user id and select blood group to start the test."
//binding.internetAvailableCL.visibility = View.VISIBLE
binding.internetIcon.setImageDrawable(AppCompatResources.getDrawable(requireContext(),R.drawable.internet))
binding.internetNotAvailableCL.visibility = View.VISIBLE
binding.pendingTest.visibility = View.GONE
setUserId()
// loadUserData()
binding.tvTitleNoInternet.text = "Please enter the user id and select blood group to start the test."
binding.internetIcon.setImageDrawable(AppCompatResources.getDrawable(requireContext(),R.drawable.internet))
binding.internetNotAvailableCL.visibility = View.VISIBLE
// setSearch()
//checkForLocalDBData()
if (Constants.MOLBIO_INTEGRATION) {
@@ -799,21 +798,8 @@ class HomeFragment : Fragment() {
private fun setUserId() {
binding.btnSubmit.setOnClickListener {
val userId = binding.userId.text.toString()
DataHolder.sampleId = userId
val age = binding.age.text.toString()
DataHolder.age = age
val bloodGroup = binding.etBloodGroup.text.toString()
DataHolder.bloodGroup = bloodGroup
// if (userId.length >= 5 && bloodGroup != "Select Blood Group") {
// DataHolder.selectedTest = UserData(
// _id = userId,
// bloodGroup = bloodGroup,
// incubationTime = SimpleDateFormat(
// "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
// ).format(Calendar.getInstance().time).toString()
// )
// findNavController().navigate(R.id.action_nav_home_to_mainActivity)
if (userId.length >= 5 && bloodGroup.isNotEmpty() && age.isNotEmpty()) {
lifecycleScope.launch {
// Add user first, ensuring it's done before fetching the user
@@ -854,16 +840,33 @@ class HomeFragment : Fragment() {
// hemoCubeViewModel.addUser(
// HemoCubeTestData(
// _id = userId,
// bloodGroup = bloodGroup.toString(),
// age = age,
// bloodGroup = bloodGroup,
// incubationTime = SimpleDateFormat(
// "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
// ).format(Calendar.getInstance().time).toString()
// )
// )
//
// lifecycleScope.launch {
// val user = hemoCubeViewModel.hemoCubeDao.getUserByID(userId)
// user.let {
// DataHolder.selectedTest = UserData(
// sampleid = it.sampleid,
// _id = it._id,
// age = it.age,
// bloodGroup = it.bloodGroup,
// incubationTime = SimpleDateFormat(
// "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
// ).format(Calendar.getInstance().time).toString()
// )
// findNavController().navigate(R.id.action_nav_home_to_mainActivity)
// }
// }
Toast.makeText(requireContext(), "Successfully added- $userId", Toast.LENGTH_SHORT).show()
binding.userId.setText("")
binding.age.setText("")
binding.etBloodGroup.setText("")
binding.etBloodGroup.clearListSelection()
// val userData = UserData(_id = userId)
// DataHolder.selectedTest = userData
// findNavController().navigate(R.id.action_nav_home_to_mainActivity)

View File

@@ -134,7 +134,7 @@ class PrefsFragment: PreferenceFragmentCompat(){
// App Version Preference
val appVersionPreference = Preference(requireContext())
appVersionPreference.title = "App Version"
appVersionPreference.title = "App Version SMI"
appVersionPreference.summary =
getAppVersion(requireContext()) + " [ " + getAppEnvironment(requireContext()) + " ]"

View File

@@ -91,7 +91,7 @@ class LoginFragment : Fragment() {
setupAutoCompleteTextView()
}
private fun setupAutoCompleteTextView() {
val districts = resources.getStringArray(R.array.district)
val districts = resources.getStringArray(R.array.districtN)
val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_dropdown_item_1line, districts)
binding.etDistrict.setAdapter(adapter)

View File

@@ -248,15 +248,15 @@ class DeviceProvisionFragment : Fragment() {
private fun encryptAndSaveToFile(username: String, password: String) {
val messageToEncrypt = "$username\n$password"
val encryptionKey = Settings.Secure.getString(requireContext().contentResolver, Settings.Secure.ANDROID_ID)
val encryptionKey =
Settings.Secure.getString(requireContext().contentResolver, Settings.Secure.ANDROID_ID)
val encryptedString = Encryption.encrypt(messageToEncrypt, encryptionKey)
Log.d("DEVICE ID/encryptionKey", encryptionKey)
// val target = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
val target = File(requireContext().getExternalFilesDir(null), "HPOSDocuments")
if (!target.exists()) {
target.mkdirs() // Create the directory if it doesn't exist
}
// val target = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val file = File(target, "credentials.txt")
if (!file.exists()) {

View File

@@ -1,194 +0,0 @@
/*
* // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
* // Notice: All information contained herein is, and remains
* // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
* // if any. The intellectual and technical concepts contained
* // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
* // and its suppliers and may be covered by Indian and Foreign Patents,
* // patents in process, and are protected by trade secret or copyright law.
* // Dissemination of this information or reproduction of this material
* // is strictly forbidden unless prior written permission is obtained
* // from ShanMukha Innovations Pvt. Ltd.
*/
package com.example.hpostesting.presentation.hb_test
import android.annotation.SuppressLint
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.constant.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.util.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.ActivityAutoDacBinding
import `in`.sminnovations.hpostesting.databinding.ActivityHbTestBinding
@AndroidEntryPoint
class HBTestActivity : AppCompatActivity() {
private lateinit var binding: ActivityHbTestBinding
val viewModel: HBTestViewModel by viewModels()
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 attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHbTestBinding.inflate(layoutInflater)
setContentView(binding.root)
// setSupportActionBar(binding.myToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
setupListener()
connectUsb(false)
}
private fun setupListener() {
DataHolder.usbConnected.observe(this) {
Log.d("USB OBSERVE", "HemoCube called -> $it")
if (it) {
myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24)
} else {
myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
Toast.makeText(this, "Device is Disconnected", Toast.LENGTH_SHORT).show()
}
}
}
open fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager
val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager)
if (availableDrivers.isEmpty()) {
onErrorReported("No Device is Connected")
} else {
mDriver = availableDrivers[0]
mConnection = manager.openDevice(mDriver.device)
if (mConnection == null) {
requestUserPermission(manager, mDriver.device)
} else {
setupService()
}
}
}
fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
if (!isFinishing) onBackPressed()
}
private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return
supportFragmentManager.beginTransaction().replace(binding.fgHbTest.id, HBTestFragment())
.commit()
}
@SuppressLint("MutableImplicitPendingIntent")
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
mPendingIntent = PendingIntent.getBroadcast(
this, 0, Intent(Constants.HEMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
)
} else {
mPendingIntent = PendingIntent.getBroadcast(
this,
0,
Intent(Constants.HEMOCUBE_USB_PERMISSION),
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
)
}
val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION)
registerReceiver(broadcastReceiver, filter)
manager.requestPermission(device, mPendingIntent)
}
fun setupService() {
val intent = Intent(this, UsbService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
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

@@ -1,397 +0,0 @@
/*
* // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
* // Notice: All information contained herein is, and remains
* // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
* // if any. The intellectual and technical concepts contained
* // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
* // and its suppliers and may be covered by Indian and Foreign Patents,
* // patents in process, and are protected by trade secret or copyright law.
* // Dissemination of this information or reproduction of this material
* // is strictly forbidden unless prior written permission is obtained
* // from ShanMukha Innovations Pvt. Ltd.
*/
package com.example.hpostesting.presentation.hb_test
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentAutoDacBinding
import `in`.sminnovations.hpostesting.databinding.FragmentHbTestBinding
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import kotlin.math.log10
class HBTestFragment : Fragment() {
private var isUsingExistingBuffer = false
private var led1Average = 0.0
private var led3Average = 0.0
private var led2Average = 0.0
private var led4Average = 0.0
private var led1SampleForDevice = 0.0
private var led2SampleForDevice = 0.0
private var led3SampleForDevice = 0.0
private var led4SampleForDevice = 0.0
private var led1BufferForDevice = 0.0
private var led2BufferForDevice = 0.0
private var led3BufferForDevice = 0.0
private var led4BufferForDevice = 0.0
private var x = 0.0
private var deviceId = ""
private var hbEst = 0.0
private var testStatusCode = 0.0
private var testDetails: HemoCubeTestData = HemoCubeTestData()
private lateinit var binding: FragmentHbTestBinding
private val hBTestViewModel: HBTestViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences
private var currentDeviceData: DeviceData? = null
private var resultData: String = ""
// private val messages = MutableLiveData<String>()
private var startListening = MutableLiveData(false)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View {
binding = FragmentHbTestBinding.inflate(inflater, container, false)
sharedPreferences =
requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViews()
observeViewModel()
}
private fun initViews() {
binding.btnSubmit.visibility = View.GONE
listenToHemoCube()
getDeviceId()
binding.tvSubtitle4.movementMethod = ScrollingMovementMethod()
binding.btnSubmit.setOnClickListener {
hBTestViewModel.messages.postValue(resultData)
binding.btnSubmit.visibility = View.GONE
testDetails.localFlag = false
testDetails.testStatus = true
testDetails.deviceId = deviceId
testDetails._id = DataHolder.sampleId
testDetails.kitSerial = DataHolder.kitSerial
testDetails.classificationResult = "HB: $hbEst"
testDetails.hb3 = x
testDetails.hb4 = hbEst
testDetails.age = DataHolder.age
testDetails.bloodGroup = DataHolder.bloodGroup
testDetails.led1Buffer = led1BufferForDevice
testDetails.led2Buffer = led2BufferForDevice
testDetails.led3Buffer = led3BufferForDevice
testDetails.led4Buffer = led4BufferForDevice
testDetails.led1Sample = led1SampleForDevice
testDetails.led2Sample = led2SampleForDevice
testDetails.led3Sample = led3SampleForDevice
testDetails.led4Sample = led4SampleForDevice
testDetails.led1Average = led1Average
testDetails.led2Average = led2Average
testDetails.led3Average = led3Average
testDetails.led4Average = led4Average
testDetails.testType = "HB Est"
testDetails.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
//Toast.makeText(requireContext(), "deviceID"+deviceId, Toast.LENGTH_LONG).show()
hBTestViewModel.uploadFirebaseQc(testDetails)
}
binding.btnBuffer.setOnClickListener {
binding.btnBuffer.visibility = View.GONE
binding.btnSample.isEnabled = false
binding.btnSample.isClickable = false
hBTestViewModel.messages.postValue("Buffer Started")
runBCommand()
}
binding.btnSample.setOnClickListener {
hBTestViewModel.messages.postValue("Sample Started")
binding.btnSample.visibility = View.GONE
binding.btnBuffer.visibility = View.GONE
runSCommand()
}
if (isBufferValueAvailable()) {
isUsingExistingBuffer = true
binding.btnBuffer.text = "Refresh Buffer"
binding.btnSample.isEnabled = true
binding.btnSample.isClickable = true
}else{
binding.btnBuffer.text = "Start Buffer"
binding.btnSample.isEnabled = false
binding.btnSample.isClickable = false
}
}
private fun observeViewModel() {
hBTestViewModel.deviceData.observe(viewLifecycleOwner) {
currentDeviceData = it
}
hBTestViewModel.messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it
}
hBTestViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
showToast("Data uploaded successfully")
requireActivity().finish()
}
if (result == "Local") {
showToast("Data uploading failed, note it down manually")
}
binding.progressBar.visibility = View.GONE
}
}
private fun getDeviceId() {
hBTestViewModel.progressBar.postValue(true)
(activity as HBTestActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
hBTestViewModel.messages.postValue(stringData)
binding.tvSubtitle4.text = stringData
}
}
override fun onUsbError(e: Exception?) {
hBTestViewModel.progressBar.postValue(false)
}
})
}
private fun runBCommand() {
hBTestViewModel.progressBar.postValue(true)
(activity as HBTestActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.START_BUFFER_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
override fun onUsbError(e: Exception?) {
hBTestViewModel.progressBar.postValue(false)
}
})
}
private fun runSCommand() {
hBTestViewModel.progressBar.postValue(true)
(activity as HBTestActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.START_SAMPLE,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
override fun onUsbError(e: Exception?) {
hBTestViewModel.progressBar.postValue(false)
}
})
}
private fun runPCommand() {
hBTestViewModel.progressBar.postValue(true)
(activity as HBTestActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.PRINT_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
override fun onUsbError(e: Exception?) {
hBTestViewModel.progressBar.postValue(false)
}
})
}
fun extractV2HardwareId(input: String): String? {
val pattern = Regex("SNS\\s*(.*?)\\s*SNE")
val matchResult: MatchResult? = pattern.find(input)
return matchResult?.groups?.get(1)?.value
}
private fun listenToHemoCube() {
val fullReadOutput = StringBuilder()
startListening.postValue(true)
try {
(activity as HBTestActivity).mService.listenToHemoCube(object :
UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
fullReadOutput.append(stringData)
resultData += stringData
hBTestViewModel.messages.postValue(resultData)
// binding.tvSubtitle4.text = resultData
if (stringData.contains("SNE")) {
val slData = stringData.split(" ")
if (slData.size > 1) {
deviceId = extractV2HardwareId(resultData).toString()
hBTestViewModel.messages.postValue("Place buffer and click below button to start test")
// with(sharedPreferences.edit()) {
// putString(Constants.DEVICE_ID, hardwareId)
// apply()
// }
}
activity?.runOnUiThread {
binding.btnBuffer.visibility = View.VISIBLE
}
}
}
if (resultData.contains("#BC") && testStatusCode < 1.0) {
testStatusCode = 1.1
resultData += getString(R.string.buffer_completed)
hBTestViewModel.messages.postValue(resultData)
activity?.runOnUiThread {
binding.btnSample.visibility = View.VISIBLE
binding.btnSample.isEnabled = true
binding.btnSample.isClickable = true
}
}
if (resultData.contains("#SC") && testStatusCode < 1.3) {
testStatusCode = 1.4
resultData +=getString(R.string.sample_completed) + "\n" + getString(R.string.gathering_data)
hBTestViewModel.messages.postValue(resultData)
activity?.runOnUiThread {
binding.btnSubmit.visibility = View.VISIBLE
runPCommand()
}
}
if (resultData.contains("REND") && testStatusCode < 1.5) {
testStatusCode = 1.6
runResult()
}
}
override fun onUsbError(e: Exception?) {
hBTestViewModel.progressBar.postValue(false)
}
})
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
}
}
private fun runResult() {
resultData += "\nFetching results...\n"
hBTestViewModel.messages.postValue(resultData)
val resultLines = resultData.split("\\s+(?=LB|LS)".toRegex())
var bufferIntensity = resultLines[1].split(' ')[1].trim()
led1BufferForDevice = if (isUsingExistingBuffer) {
sharedPreferences.getString(Constants.BUFFER_VALUE_1, "")?.toDoubleOrNull()!!
} else {
bufferIntensity.toDoubleOrNull()!!
}
bufferIntensity = resultLines[2].split(' ')[1].trim()
led2BufferForDevice = if (isUsingExistingBuffer) {
sharedPreferences.getString(Constants.BUFFER_VALUE_2, "")?.toDoubleOrNull()!!
} else {
bufferIntensity.toDoubleOrNull()!!
}
bufferIntensity = resultLines[3].split(' ')[1].trim()
led3BufferForDevice = if (isUsingExistingBuffer) {
sharedPreferences.getString(Constants.BUFFER_VALUE_3, "")?.toDoubleOrNull()!!
} else {
bufferIntensity.toDoubleOrNull()!!
}
bufferIntensity = resultLines[4].split(' ')[1].trim()
led4BufferForDevice = if (isUsingExistingBuffer) {
sharedPreferences.getString(Constants.BUFFER_VALUE_4, "")?.toDoubleOrNull()!!
} else {
bufferIntensity.toDoubleOrNull()!!
}
led1SampleForDevice = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2SampleForDevice = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3SampleForDevice = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
led4SampleForDevice = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
led1Average = log10(led1BufferForDevice.div(led1SampleForDevice))
led2Average = log10(led2BufferForDevice.div(led2SampleForDevice))
led3Average = log10(led3BufferForDevice.div(led3SampleForDevice))
led4Average = log10(led4BufferForDevice.div(led4SampleForDevice))
x = led1Average - led3Average
hbEst = (7.347 * x * x) + (12.704 * x) + 0.9033
resultData +="\n Result: HB EST: $hbEst"
if (!isUsingExistingBuffer) {
with(sharedPreferences.edit()) {
putString(Constants.BUFFER_VALUE_1, led1BufferForDevice.toString())
putString(Constants.BUFFER_VALUE_2, led2BufferForDevice.toString())
putString(Constants.BUFFER_VALUE_3, led3BufferForDevice.toString())
putString(Constants.BUFFER_VALUE_4, led4BufferForDevice.toString())
apply()
}
}
hBTestViewModel.messages.postValue(resultData)
}
private fun showToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
private fun isBufferValueAvailable(): Boolean {
return try {
if (sharedPreferences.getString(
Constants.BUFFER_VALUE_1, ""
) != "" && sharedPreferences.getString(Constants.BUFFER_VALUE_2, "") != ""
&& sharedPreferences.getString(Constants.BUFFER_VALUE_3, "") != ""
&& sharedPreferences.getString(Constants.BUFFER_VALUE_4, "") != ""
) {
sharedPreferences.getString(Constants.BUFFER_VALUE_1, "")
?.toDouble()!! > 0.0 && sharedPreferences.getString(
Constants.BUFFER_VALUE_2,
""
)
?.toDouble()!! > 0.0 && sharedPreferences.getString(
Constants.BUFFER_VALUE_3,
""
)
?.toDouble()!! > 0.0 && sharedPreferences.getString(
Constants.BUFFER_VALUE_4,
""
)
?.toDouble()!! > 0.0
} else {
false
}
} catch (e: Exception) {
showToast("error_exist")
false
}
}
}

View File

@@ -1,87 +0,0 @@
/*
* // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
* // Notice: All information contained herein is, and remains
* // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
* // if any. The intellectual and technical concepts contained
* // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
* // and its suppliers and may be covered by Indian and Foreign Patents,
* // patents in process, and are protected by trade secret or copyright law.
* // Dissemination of this information or reproduction of this material
* // is strictly forbidden unless prior written permission is obtained
* // from ShanMukha Innovations Pvt. Ltd.
*/
package com.example.hpostesting.presentation.hb_test
import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.repository.Repository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class HBTestViewModel @Inject constructor(
private val hemoCubeDao: HemoCubeDao,
private val repository: Repository,
context: Context,
) : ViewModel() {
var isServiceConnected = false
val progressBar = MutableLiveData(false)
val messages = MutableLiveData<String>()
private val sharedPreference: SharedPreferences =
context.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
val deviceData = MutableLiveData<DeviceData?>()
val fireBaseUpload = MutableLiveData<String>()
fun uploadFirebaseQc(testDetails: HemoCubeTestData){
viewModelScope.launch {
try {
when (val response = repository.addTestToDatabase(testDetails)) {
is Response.Success -> {
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
testDetails.localFlag = true
hemoCubeDao.updateTest(testDetails)
}
is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
hemoCubeDao.updateTest(testDetails)
}
else -> {}
}
} catch (e: Exception) {
fireBaseUpload.postValue("Error")
}
}
}
fun addAutoDacDataToDb(data: DiagnosticsData) {
viewModelScope.launch {
try {
when (val response = repository.addDiagnostics(data)) {
is Response.Success -> {
fireBaseUpload.postValue("Success")
}
is Response.Error -> {
fireBaseUpload.postValue("Error")
}
}
} catch (e: Exception) {
fireBaseUpload.postValue("Error")
}
}
}
}

View File

@@ -87,8 +87,6 @@ class HemoCubeFragment : Fragment() {
private var checkCuvette = false
private var checkRefreshCuvette = false
private var checkCuvetteSam = false
private var checkSubmit = false
private var submitClick = false
private var sampleClick = false
private var refreshClick = false
private lateinit var binding: FragmentHemoCubeReferenceBinding
@@ -184,31 +182,23 @@ class HemoCubeFragment : Fragment() {
binding.tvSubtitle4.movementMethod = ScrollingMovementMethod()
binding.tvDeviceMessages.movementMethod = ScrollingMovementMethod()
binding.btnSubmit.setOnClickListener {
submitClick = true
if(checkSubmit){
with(sharedPreferences.edit()) {
putBoolean(Constants.QUICK_CAPTURE, false)
apply()
}
if(DataHolder.hemoCubeTestData!!.classificationResult != "Invalid"){
DataHolder.sampleReadCounter++
}
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
activity?.runOnUiThread {
Log.d("HemoCubeFragment","Test Process completed, result saved")
binding.progressBar.visibility = View.VISIBLE
binding.btnSubmit.visibility = View.GONE
}
hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, ""),quickCapture
)
}else{
checkCuvettePresence()
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
with(sharedPreferences.edit()) {
putBoolean(Constants.QUICK_CAPTURE, false)
apply()
}
if(DataHolder.hemoCubeTestData!!.classificationResult != "Invalid"){
DataHolder.sampleReadCounter++
}
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
activity?.runOnUiThread {
Log.d("HemoCubeFragment","Test Process completed, result saved")
binding.progressBar.visibility = View.VISIBLE
binding.btnSubmit.visibility = View.GONE
}
hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, ""),quickCapture
)
}
binding.tvTitle2.visibility = View.GONE
@@ -674,21 +664,6 @@ class HemoCubeFragment : Fragment() {
}
showRetryButtonForCuvette()
}
resultData.contains("#CIN") && this.submitClick && this.testStatusCode < TestStatus.CUVETTE_PRESENTT.code -> {
hemoCubeViewModel.messages.postValue(getString(R.string.cuvette_presentt))
this.testStatusCode = TestStatus.CUVETTE_PRESENTT.code
activity?.runOnUiThread {
binding.testing.visibility = View.GONE
}
}
resultData.contains("#AIN") && this.submitClick && this.testStatusCode <= TestStatus.CUVETTE_ABSENTT.code -> {
hemoCubeViewModel.messages.postValue(getString(R.string.cuvette_absentt))
this.testStatusCode = TestStatus.CUVETTE_ABSENTT.code
activity?.runOnUiThread {
checkSubmit = true
binding.testing.visibility = View.GONE
}
}
resultData.contains("#BS") && this.testStatusCode < TestStatus.BUFFER_STARTED.code -> {
hemoCubeViewModel.messages.postValue(getString(R.string.buffer_started))
this.testStatusCode = TestStatus.BUFFER_STARTED.code
@@ -760,7 +735,6 @@ class HemoCubeFragment : Fragment() {
}
}
(resultData.contains("#SC") || resultData.contains("#SC1")) && this.testStatusCode < TestStatus.SAMPLE_COMPLETED.code -> {
this.testStatusCode = TestStatus.SAMPLE_COMPLETED.code
activity?.runOnUiThread {
@@ -774,7 +748,6 @@ class HemoCubeFragment : Fragment() {
fetchResult()
}
resultData.contains("ovf") -> {
activity?.runOnUiThread {
binding.testing.visibility = View.GONE
@@ -1381,7 +1354,7 @@ class HemoCubeFragment : Fragment() {
"%.3f".format(
borderlineMetric
)
} \n Remove Cuvette & Click Submit"
}"
)
if (DataHolder.hemoCubeTestData?.testType == "HB")
hemoCubeViewModel.messages.postValue("Hb: $calculatedHb4")
@@ -1458,19 +1431,19 @@ class HemoCubeFragment : Fragment() {
if (deviceRatioClass == "Negative Borderline") {
if (borderlineMetric < negativeBoderLine10mm1){//1.34
return "Sickle Cell Trait"
}else if(borderlineMetric > negativeBoderLine10mm1){
}else if(borderlineMetric > negativeBoderLine10mm2){
return "Normal"
}else if(borderlineMetric == negativeBoderLine10mm1){
return "Sickle Cell Trait"
}else if(borderlineMetric > negativeBoderLine10mm1 && borderlineMetric < negativeBoderLine10mm2){
return "Negative borderline. Confirm with HPLC"
}
}
if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") {
if (borderlineMetric < positiveBoderLine10mm1){//1.34
return "Sickle Cell Disease"
}else if(borderlineMetric > positiveBoderLine10mm1){
}else if(borderlineMetric > positiveBoderLine10mm2){
return "Sickle Cell Trait"
}else if(borderlineMetric == positiveBoderLine10mm1){
return "Sickle Cell Disease"
}else if(borderlineMetric > positiveBoderLine10mm1 && borderlineMetric < positiveBoderLine10mm2){
return "Positive for Sickle Cell. Confirm with HPLC"
}
}
}else if(cuvetteSize == "2mm"){

View File

@@ -74,7 +74,6 @@ class HemoCubeViewModel @Inject constructor(
private val localFileDataSource: LocalFileDataSource,
context: Context,
) : ViewModel() {
private var testUpload: Boolean = false
var isServiceConnected = false
val progressBar = MutableLiveData(false)
private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
@@ -133,13 +132,11 @@ class HemoCubeViewModel @Inject constructor(
try {
if (isOnline) {
parseData()
//addResultTestToDb(quickCapture)
if(Constants.FIREBASE_INTEGRATION){
addResultTestToDb(quickCapture)
}else{
uploadToMolbio()
}
} else {
parseData()
val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0)
@@ -147,21 +144,13 @@ class HemoCubeViewModel @Inject constructor(
putInt(Constants.KIT_COUNT, kitCount.plus(1))
apply()
}
// addResultTestToDb(quickCapture,isOnline)
// addResultTestToDb(quickCapture,isOnline)
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
testDetails?.localFlag = false
hemoCubeDao.updateTest(testDetails!!)
fireBaseUpload.postValue("Local")
// parseData()
// addResultTestToDb(quickCapture)
// testDetails?.testTime = SimpleDateFormat(
// "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
// ).format(Calendar.getInstance().time)
// hemoCubeDao.updateTest(testDetails!!)
// fireBaseUpload.postValue("Local")
}
} catch (e: Exception) {
Log.e("Testdb", "Upload failed: ${e.message}")
@@ -317,12 +306,6 @@ class HemoCubeViewModel @Inject constructor(
}
}
}
if(testUpload){
fireBaseBulkUpload.postValue("Success")
}
// else{
// fireBaseBulkUpload.postValue("Error")
// }
}
@@ -544,7 +527,6 @@ class HemoCubeViewModel @Inject constructor(
}
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
if (Constants.MOLBIO_INTEGRATION) {
// Sanitize testDetails before using it in the API call
val sanitizedTestDetails = sanitizeDoubleValues(testDetails)
@@ -596,13 +578,13 @@ class HemoCubeViewModel @Inject constructor(
).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(userData)) {
is Response.Success -> {
testUpload = true
fireBaseBulkUpload.postValue("Success")
userData.localFlag = true
updateLocalFlag(userData._id)
}
else -> {
testUpload = false
fireBaseBulkUpload.postValue("Error")
}
}
}
@@ -636,7 +618,9 @@ class HemoCubeViewModel @Inject constructor(
fun deleteById(userId: String) = viewModelScope.launch {
hemoCubeDao.deleteById(id = userId)
}
fun deleteByStatus() = viewModelScope.launch {
hemoCubeDao.deleteByStatus()
}
private fun addResultTestToDbforbuffercheck(bufferCheckData: BufferCheckData) {
viewModelScope.launch {
@@ -667,10 +651,6 @@ class HemoCubeViewModel @Inject constructor(
viewModelScope.launch {
hemoCubeBufferDao.updateFieldById(id = bufferId, true)
}
fun deleteByStatus() = viewModelScope.launch {
hemoCubeDao.deleteByStatus()
}
fun getLocalUserDataForCsv(context: Context): Boolean {
val localUserDataLiveData: LiveData<List<HemoCubeTestData>> = hemoCubeDao.getAll()

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
~ // Notice: All information contained herein is, and remains
~ // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
~ // if any. The intellectual and technical concepts contained
~ // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
~ // and its suppliers and may be covered by Indian and Foreign Patents,
~ // patents in process, and are protected by trade secret or copyright law.
~ // Dissemination of this information or reproduction of this material
~ // is strictly forbidden unless prior written permission is obtained
~ // from ShanMukha Innovations Pvt. Ltd.
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_parent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- <androidx.appcompat.widget.Toolbar-->
<!-- android:id="@+id/my_toolbar"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="?attr/actionBarSize"-->
<!-- android:background="?attr/colorPrimary"-->
<!-- app:titleTextColor="#FFFFFF"-->
<!-- android:elevation="4dp"-->
<!-- app:menu="@menu/my_menu"-->
<!-- android:theme="@style/ToolbarTheme"-->
<!-- app:popupTheme="@style/ThemeOverlay.AppCompat.Light"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent"/>-->
<FrameLayout
android:id="@+id/fg_hb_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -165,7 +165,7 @@
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_reset_password" />
app:layout_constraintTop_toBottomOf="@id/btn_deviceProvision" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_firefox"
android:layout_width="match_parent"

View File

@@ -1,158 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
~ // Notice: All information contained herein is, and remains
~ // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
~ // if any. The intellectual and technical concepts contained
~ // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
~ // and its suppliers and may be covered by Indian and Foreign Patents,
~ // patents in process, and are protected by trade secret or copyright law.
~ // Dissemination of this information or reproduction of this material
~ // is strictly forbidden unless prior written permission is obtained
~ // from ShanMukha Innovations Pvt. Ltd.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hpostesting.presentation.autodac.AutoDacFragment">
<!-- <TextView-->
<!-- android:id="@+id/tv_title"-->
<!-- style="@style/title1"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="24dp"-->
<!-- android:text="@string/diagnostics"-->
<!-- android:layout_marginTop="16dp"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent" />-->
<TextView
android:id="@+id/tv_subtitle2"
style="@style/title2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:textSize="22sp"
android:textStyle="bold"
android:text="HB Test"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_subtitle3"
style="@style/title2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />
<TextView
android:id="@+id/tv_subtitle4"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="320dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:gravity="center"
android:scrollbars="vertical"
android:text="Start"
android:textColor="@color/black"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" />
<Button
android:id="@+id/btn_buffer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:gravity="center"
android:text="Buffer Start"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />
<Button
android:id="@+id/btn_sample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="15dp"
android:clickable="false"
android:gravity="center"
android:visibility="visible"
android:text="Sample Start"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_buffer" />
<Button
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:gravity="center"
android:visibility="gone"
android:text="Submit"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_sample" />
<!-- <Button-->
<!-- android:id="@+id/btn_read"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/read"-->
<!-- android:layout_margin="16dp"-->
<!-- android:clickable="false"-->
<!-- app:layout_constraintTop_toBottomOf="@id/btn_set_reference"-->
<!-- app:layout_constraintStart_toStartOf="parent" />-->
<!-- </androidx.constraintlayout.widget.ConstraintLayout>-->
<ImageView
android:id="@+id/iv_check"
android:visibility="gone"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="40dp"
android:importantForAccessibility="no"
android:src="@drawable/check"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_submit" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:elevation="12dp"
android:indeterminate="true"
android:indeterminateDrawable="@drawable/progressbar_drawable"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -122,7 +122,6 @@
android:hint="@string/age" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_blood_group"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"

View File

@@ -289,8 +289,6 @@
<string name="check_cuvette">Checking cuvette presence</string>
<string name="cuvette_present">Cuvette present</string>
<string name="cuvette_absent">Cuvette absent</string>
<string name="cuvette_presentt">Cuvette Present , Please Remove Cuvette And Try Again</string>
<string name="cuvette_absentt">Cuvette Absent,Now You Can Submit</string>
<string name="retry">Retry</string>
<string name="Firefox">Firefox</string>
<string name="Files">Files</string>

View File

@@ -288,8 +288,6 @@
<string name="check_cuvette">ಕುವೆಟ್ ಇರುವಿಕೆಯನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ</string>
<string name="cuvette_present">ಕುವೆಟ್ಟೆ ಇರುತ್ತದೆ</string>
<string name="cuvette_absent">ಕುವೆಟ್ಟೆ ಇರುವುದಿಲ್ಲ </string>
<string name="cuvette_presentt">Cuvette Present , Please Remove Cuvette And Try Again</string>
<string name="cuvette_absentt">Cuvette Absent,Now You Can Submit</string>
<string name="retry">ಮರುಪ್ರಯತ್ನಿಸಿ</string>
<string name="Firefox">ಫೈರ್‌ಫಾಕ್ಸ್</string>
<string name="Files">ಫೈಲ್</string>

View File

@@ -31,5 +31,9 @@
<item>Chamarajanagar</item>
<item>Other</item>
</string-array>
<string-array name="districtN">
<item>Nagpur</item>
<item>Other</item>
</string-array>
</resources>

View File

@@ -291,8 +291,6 @@
<string name="check_cuvette">Checking cuvette presence</string>
<string name="cuvette_present">Cuvette present , you can start the test</string>
<string name="cuvette_absent">Cuvette is absent , please place the cuvette and retry again</string>
<string name="cuvette_presentt">Cuvette Present , Please Remove Cuvette And Try Again</string>
<string name="cuvette_absentt">Cuvette Absent,Now You Can Submit</string>
<string name="retry">Retry again</string>
<string name="usb_terminal">Usb Terminal</string>
<string name="menu_about">About</string>

View File

@@ -390,7 +390,7 @@ class HemoCubeFragmentTest {
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineSickleCellTrait1() {
val result =
hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline", 2.2)
assertEquals("Normal", result)
assertEquals("Negative borderline. Confirm with HPLC", result)
}
@Test
@@ -400,7 +400,7 @@ class HemoCubeFragmentTest {
"Positive for Sickle Cell. HPLC for Confirmation",
1.4
)
assertEquals("Sickle Cell Trait", result)
assertEquals("Positive for Sickle Cell. Confirm with HPLC", result)
}
@Test
@@ -410,7 +410,7 @@ class HemoCubeFragmentTest {
"Positive for Sickle Cell. HPLC for Confirmation",
1.33
)
assertEquals("Sickle Cell Trait", result)
assertEquals("Positive for Sickle Cell. Confirm with HPLC", result)
}
@Test