Compare commits

..

39 Commits

Author SHA1 Message Date
tanx
304f413364 changes Ui and attributes of panel, auto DAC, Calibration and device Diagnostics screens. 2024-03-28 16:29:55 +05:30
tanx
f1b03c93a2 chenges buttons and text inputs attributes. 2024-03-25 12:40:59 +05:30
tanx
dded6976f6 chenges buttons and text inputs attributes. 2024-03-19 18:08:46 +05:30
tanx
b1d10d5403 created new drawable and changed all buttons style 2024-03-18 16:24:37 +05:30
tanx
9cf7fae2ec changed normal FAB to extended FAB 2024-03-07 16:14:56 +05:30
tanx
ef419d8a71 Changed Nav header color at all places.
nav header text color changed.
text alignment.
2024-03-06 17:40:31 +05:30
tanx
3317df4f70 Updated scanner icon.
Changed header color.
Fixed letter casing.
2024-03-04 12:33:10 +05:30
tanx
6bdd1da9da icon aspect ratio changed in nav_header_dashboard.xml 2024-03-02 13:51:01 +05:30
chandrashekhar reddy
e947d083fb merge 2024-03-01 14:08:49 +05:30
Pritimay Sarkar
2e1c932e72 auto switch baud rate between old and new devices 2024-02-29 14:01:23 +05:30
chandrashekhar reddy
6474181664 gpg error 2024-02-29 12:41:12 +05:30
Pritimay Sarkar
a142717ef2 fix pipeline 2024-02-29 12:09:39 +05:30
Pritimay Sarkar
0d72a0f6f1 add toast to usb listener 2024-02-29 11:15:45 +05:30
Pritimay Sarkar
63b51b1526 Merge branch 'dev' of https://gitlab.com/sminnovations/hpos into dev 2024-02-29 10:16:25 +05:30
Pritimay Sarkar
95533aab0d add exception handling 2024-02-29 10:14:16 +05:30
chandrashekhar reddy
c8677bc2bb gpg setup 2024-02-28 12:20:34 +05:30
chandrashekhar reddy
c48c5a1ae3 update without app distribution done 2024-02-27 14:18:46 +05:30
chandrashekhar reddy
97cc281752 Merge remote-tracking branch 'origin/dev' into dev 2024-02-27 14:00:01 +05:30
chandrashekhar reddy
4f6d3fa203 update without app distribution done 2024-02-27 13:59:30 +05:30
Pritimay Sarkar
4272e36385 refactoring unit tests 2024-02-26 20:28:24 +05:30
Pritimay Sarkar
eb1c764551 change thresholds 2024-02-23 09:36:01 +05:30
Pritimay Sarkar
cd593bb67b add unit test 2024-02-21 22:05:09 +05:30
Pritimay Sarkar
69ebb2f343 add release folder to gitignore 2024-02-21 22:04:48 +05:30
Pritimay Sarkar
3ddad93a6a add readme 2024-02-21 22:04:14 +05:30
Mariya
f0d71b3167 Merge remote-tracking branch 'origin/dev' into dev 2024-02-21 19:19:40 +05:30
Mariya
ab810e788b added keystore 2024-02-21 19:19:19 +05:30
Pritimay Sarkar
1bc8b18669 add borderline method 2 based on led2Average 2024-02-21 17:49:31 +05:30
Pritimay Sarkar
ea21c5d862 Merge branch 'ujjain' into 'dev'
Ujjain - add borderline metric

See merge request sminnovations/hpos!38
2024-02-20 15:12:58 +00:00
Pritimay Sarkar
3bad0720e3 add users 2024-02-20 10:52:05 +05:30
Pritimay Sarkar
b1342580ea avoid saving deviceid to pref 2024-02-20 10:50:42 +05:30
Pritimay Sarkar
d4c66e5e1a refactor code 2024-02-19 23:15:42 +05:30
Pritimay Sarkar
14516cad5f change binding logic 2024-02-19 23:14:42 +05:30
Pritimay Sarkar
a384c3e93a Merge branch 'dev' of https://gitlab.com/sminnovations/hpos into dev 2024-02-19 11:01:19 +05:30
Pritimay Sarkar
8910e2978f hide device messages by default 2024-02-18 14:46:36 +05:30
Pritimay Sarkar
3bab859d0b update packages 2024-02-18 14:42:43 +05:30
Mariya
b036ae8377 getting null values in solution and concentration as name in firebase issue solved 2024-02-17 14:11:02 +05:30
Pritimay Sarkar
c91657c529 unit tests for lower and uppper bounds 2024-02-17 09:43:14 +05:30
Pritimay Sarkar
e64aa27f8a refine borderline 2024-02-17 09:09:45 +05:30
Pritimay Sarkar
f2d6916aa6 add borderline metric 2024-02-16 14:27:40 +05:30
68 changed files with 1066 additions and 523 deletions

3
.idea/gradle.xml generated
View File

@@ -4,9 +4,8 @@
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

4
README.md Normal file
View File

@@ -0,0 +1,4 @@
### Release key
key0: prime24

1
app/.gitignore vendored
View File

@@ -1,3 +1,4 @@
/build
/release
/google-services*
/idea

View File

@@ -80,16 +80,16 @@ 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.7.0'
implementation 'com.google.android.gms:play-services-auth:21.0.0'
implementation 'com.google.android.gms:play-services-location:21.1.0'
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-beta11'
implementation("com.google.firebase:firebase-appdistribution-api-ktx:16.0.0-beta11")
implementation 'com.google.firebase:firebase-appdistribution:16.0.0-beta12'
implementation("com.google.firebase:firebase-appdistribution-api-ktx:16.0.0-beta12")
implementation 'androidx.preference:preference-ktx:1.2.1'
implementation 'androidx.preference:preference-ktx:1.2.1'
implementation 'com.google.android.play:core:1.10.3'
implementation 'io.nats:jnats:2.11.2'
implementation 'io.nats:jnats:2.11.4'
@@ -143,8 +143,8 @@ dependencies {
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2'
// Navigation Component
implementation "androidx.navigation:navigation-fragment-ktx:2.7.6"
implementation "androidx.navigation:navigation-ui-ktx:2.7.6"
implementation "androidx.navigation:navigation-fragment-ktx:2.7.7"
implementation "androidx.navigation:navigation-ui-ktx:2.7.7"
//Dagger - Hilt
implementation "com.google.dagger:hilt-android:2.46"

View File

@@ -116,18 +116,15 @@
android:name="com.example.hpostesting.presentation.testRight.UsbService"
android:enabled="true"
android:exported="false" />
<activity
android:name="com.example.hpostesting.presentation.SplashActivity"
android:exported="true"
android:noHistory="true"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!-- <category android:name="android.intent.category.HOME" />-->
<!-- <category android:name="android.intent.category.DEFAULT" />-->
<!-- <category android:name="android.intent.category.MONKEY"/>-->
<!-- <category android:name="android.intent.category.LAUNCHER_APP" />-->
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
@@ -164,7 +161,7 @@
android:screenOrientation="portrait"
android:stateNotNeeded="true"
tools:replace="android:screenOrientation" />
<!-- ${applicationId}-->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"

View File

@@ -5,10 +5,10 @@ object Constants {
const val HEMOCUBE_USB_PERMISSION = "shanmukha.in.sickle_cell_homocube.USB_PERMISSION"
const val BASE_URL = "www.google.com"
const val DOCUMENT_ID_FOR_UPDATE ="2o71vBKLqdgEKYtFG8Lb"
const val ABHA_APP_PACKAGE = "in.ndhm.phr"
const val MOLBIO_INTEGRATION = true
const val MOLBIO_INTEGRATION = false
const val deviceProvisionEmail = "HPOS_provisioner@bigtec.co.in"
const val deviceProvisionPassword = "f2ab0e7f9d69"
const val DEVICE_ID_API = "deviceIDAPI"
@@ -67,6 +67,8 @@ object Constants {
val STATICID = listOf(
"FACTORY",
"ADMIN",
"PQUSER",
"QCUSER",
"VIZ-1000-0004",
"VIZ-1000-0005",
"VIZ-1000-0006",

View File

@@ -29,4 +29,8 @@ interface HemoCubeDao {
@Query("UPDATE hemo_cube_test_table SET isCSVCreated = :newValue WHERE _id = :id")
suspend fun updateCSVFieldById(id: String, newValue: Boolean)
@Query("SELECT * from hemo_cube_test_table WHERE molbioFlag = :status")
suspend fun getPendingUser(status: Boolean): List<HemoCubeTestData>
}

View File

@@ -10,7 +10,7 @@ import com.example.hpostesting.data.model.patient.UserData
@Database(
entities = [UserData::class, HemoCubeTestData::class, DeviceData::class, BufferCheckData::class],
version = 26,
version = 27,
exportSchema = false
)
@TypeConverters(Converters::class)

View File

@@ -1,36 +0,0 @@
package com.example.hpostesting.data.encryption
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import android.util.Base64
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.spec.SecretKeySpec
object AESCrypt {
private const val ALGORITHM = "AES"
private const val KEY = "your_secret_key"
@Throws(Exception::class)
fun encrypt(value: String): String {
val keySpec = SecretKeySpec(KEY.toByteArray(), ALGORITHM)
val cipher = Cipher.getInstance(ALGORITHM)
cipher.init(Cipher.ENCRYPT_MODE, keySpec)
val encryptedBytes = cipher.doFinal(value.toByteArray())
return Base64.encodeToString(encryptedBytes, Base64.DEFAULT)
}
@Throws(Exception::class)
fun decrypt(encrypted: String?): String {
val keySpec = SecretKeySpec(KEY.toByteArray(), ALGORITHM)
val cipher = Cipher.getInstance(ALGORITHM)
cipher.init(Cipher.DECRYPT_MODE, keySpec)
val encryptedBytes = Base64.decode(encrypted, Base64.DEFAULT)
val decryptedBytes = cipher.doFinal(encryptedBytes)
return String(decryptedBytes)
}
//generates a secret key for the encryption functions to use
//TODO: Generating keys requires a higher API level. ask someone if this is okay.
}

View File

@@ -26,4 +26,14 @@ data class DeviceData(
var natsToken: String = "",
@get:PropertyName("natsTokenExpiry") @set:PropertyName("natsTokenExpiry")
var natsTokenExpiry: String = "",
@get:PropertyName("deviceUpdateAvailable") @set:PropertyName("deviceUpdateAvailable")
var deviceUpdateAvailable: Boolean = false,
@get:PropertyName("updatePath") @set:PropertyName("updatePath")
var updatePath: String = "",
@get:PropertyName("deviceVersion") @set:PropertyName("deviceVersion")
var deviceVersion: String = "",
@get:PropertyName("globalUpdateDone") @set:PropertyName("globalUpdateDone")
var globalUpdateDone: Boolean = false,
@get:PropertyName("globalUpdateIgnore") @set:PropertyName("globalUpdateIgnore")
var globalUpdateIgnore: Boolean = false,
)

View File

@@ -78,6 +78,7 @@ data class HemoCubeTestData(
var prdClassification: String = "",
var deviceRatioClass: String = "",
var slopeRatioClass: String = "",
var borderlineMethod2Class: String = "",
var errorMessages: String = "",
var batteryLevel: String = "",
var batteryCapacity: String = "",

View File

@@ -1,29 +0,0 @@
package com.example.hpostesting.di
import android.content.Context
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ViewModelComponent
import dagger.hilt.android.qualifiers.ApplicationContext
@Module
@InstallIn(ViewModelComponent::class)
object ViewModelModule {
@Provides
fun provideTestRightViewModel(
saveRawData: SaveRawData,
saveRawDataTest: SaveRawDataTest,
databaseRepository: DatabaseRepository,
userDao: UserDao,
context: Context
): TestRightViewModel {
return TestRightViewModel(saveRawData, saveRawDataTest, databaseRepository, userDao, context)
}
}

View File

@@ -22,6 +22,8 @@ import com.example.hpostesting.domain.LogFileManager
import com.example.hpostesting.domain.LogFileManagerImpl
import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.UsbServiceListenerImpl
import com.example.hpostesting.util.PropertyProviderImpl
import dagger.Module
import dagger.Provides
@@ -179,4 +181,10 @@ object AppModule {
fun provideLocalFileDataSource(): LocalFileDataSource {
return LocalFileDataSourceImpl()
}
@Provides
@Singleton
fun provideUsbServiceListener(context: Context): UsbServiceListener {
return UsbServiceListenerImpl(context)
}
}

View File

@@ -125,13 +125,8 @@ class NatsManager(datacollector: DashboardActivity) {
if (nc?.status == Connection.Status.CONNECTED) {
Log.d("NATSCONNECTION", "NATS is successfully connected.")
val d = nc?.createDispatcher { msg: Message? ->
println("Nats dispatcher $msg")
}
nc?.subscribe("device.hpos.${deviceId}.ping")
// Log.d(TAG, "Nats subscribed with ping-"+d)
nc?.publish(
"server.hpos.${deviceId}.ping",
"ALIVE".toByteArray(StandardCharsets.UTF_8)
@@ -140,7 +135,10 @@ class NatsManager(datacollector: DashboardActivity) {
"server.hpos.${deviceId}.health",
"ALIVE".toByteArray(StandardCharsets.UTF_8)
)
val d = nc?.createDispatcher { msg: Message? ->
println("Nats dispatcher $msg")
Log.d(TAG, "Nats dispatcher--$msg")
}
d?.subscribe("device.hpos.${deviceId}.ping") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8)
datacollector.setResponse(response)
@@ -172,10 +170,11 @@ class NatsManager(datacollector: DashboardActivity) {
println("Message received (up to 100 times): $response")
}
d?.subscribe("device.hpos.${deviceId}.checkupdate") { msg ->
d?.subscribe("device.hpos.${deviceId}.checkUpdate") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8)
datacollector.setResponse(response)
println("Message received (up to 100 times): $response")
println("Message received (up to 100 times) on topic checkupdate: $response")
Log.d(TAG, "subscribed msg ${msg} on topic checkupdate")
}
} else {
Log.d("NATSCONNECTION", "NATS is not connected. Current status: ${nc?.status}")

View File

@@ -0,0 +1,26 @@
package com.example.hpostesting.presentation
import android.content.Context
import android.util.Log
import android.widget.Toast
class UsbServiceListenerImpl(private val context: Context): UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
if (data != null) {
val receivedData = String(data)
logData(receivedData)
}
}
override fun onUsbError(e: Exception?) {
showToast("USB Error: ${e?.message}")
}
private fun showToast(message: String) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
}
private fun logData(data: String) {
Log.d("UsbServiceListener", "Received data from USB: $data")
}
}

View File

@@ -162,8 +162,8 @@ class AssuranceControlsFragment : Fragment() {
}
DataHolder.hemoCubeTestData!!._id = currentUnixTime.toString() + "SMI"
DataHolder.hemoCubeTestData!!.solution = binding.spinnerSolutions.selectedItem.toString()
DataHolder.hemoCubeTestData!!.name = binding.spinnerConcentration.selectedItem.toString()
"${DataHolder.hemoCubeTestData!!.solution} ${DataHolder.hemoCubeTestData!!.concentration} ${DataHolder.hemoCubeTestData!!.volume}"
DataHolder.hemoCubeTestData!!.concentration = binding.spinnerConcentration.selectedItem.toString()
DataHolder.hemoCubeTestData!!.name = "${DataHolder.hemoCubeTestData!!.solution} ${DataHolder.hemoCubeTestData!!.concentration} ${DataHolder.hemoCubeTestData!!.volume}"
DataHolder.selectedTest = UserData()
DataHolder.selectedTest?._id = DataHolder.hemoCubeTestData!!._id

View File

@@ -163,10 +163,10 @@ class AutoDacFragment : Fragment() {
val slData = stringData.split(" ")
if (slData.size > 1) {
val hardwareId = slData[1].trim()
with(sharedPreferences.edit()) {
putString(Constants.DEVICE_ID, hardwareId)
apply()
}
// with(sharedPreferences.edit()) {
// putString(Constants.DEVICE_ID, hardwareId)
// apply()
// }
}
activity?.runOnUiThread {
binding.btnSubmit.visibility = View.VISIBLE

View File

@@ -4,6 +4,7 @@ import android.app.DownloadManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.net.Uri
import android.os.Build
@@ -23,6 +24,7 @@ import androidx.navigation.ui.setupWithNavController
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.NatsManager
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.jig.JigActivity
@@ -30,6 +32,8 @@ import com.google.android.material.navigation.NavigationView
import com.google.firebase.appdistribution.FirebaseAppDistribution
import com.google.firebase.appdistribution.FirebaseAppDistributionException
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
@@ -49,6 +53,7 @@ open interface IDataCollector: NatsMessageCallback {
class DashboardActivity : AppCompatActivity(), IDataCollector {
val TAG = "DashboardActivity"
private var isRegistered= false
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityDashboardBinding
lateinit var sharedPreferences: SharedPreferences
@@ -66,13 +71,13 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
override fun onMessageReceived(topic: String, message: String) {
// Handle incoming messages from NATS
Log.d(TAG, "Received message on topic $topic: $message")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDashboardBinding.inflate(layoutInflater)
sharedPreferences = this.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
setContentView(binding.root)
@@ -117,6 +122,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
}
}
val drawerLayout: DrawerLayout = binding.drawerLayout
val navView: NavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_content_dashboard)
@@ -135,6 +141,8 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.dashboard, menu)
@@ -146,8 +154,8 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
private fun initiateUpdate(responseBody: String) {
val apkUrl = responseBody
private fun initiateUpdate(url: String) {
val apkUrl = url
if (!isValidHttpUrl(apkUrl)) {
return
}
@@ -162,8 +170,11 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
downloadId = downloadManager.enqueue(request)
// Register a BroadcastReceiver to receive the download complete event
// val filter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
// registerReceiver(downloadReceiver, filter)
val filter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
isRegistered = true
registerReceiver(downloadReceiver, filter, RECEIVER_EXPORTED)
}
}
private fun extractApkUrl(responseBody: ResponseBody): String {
return responseBody.string()
@@ -187,7 +198,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
val pInfo = baseContext.packageManager.getPackageInfo(baseContext.packageName, 0)
val uri: Uri = FileProvider.getUriForFile(
this,
"${pInfo}.fileprovider",
"in.sminnovations.hpostesting.dev.fileprovider",
file
)
@@ -207,8 +218,15 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
}
override fun onDestroy() {
try {
if (isRegistered){
unregisterReceiver(downloadReceiver)
}
}catch (e: IllegalArgumentException){
Log.e("HOmeFragment",e.toString())
}
super.onDestroy()
// unregisterReceiver(downloadReceiver)
}
override fun onResume() {
@@ -258,8 +276,8 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
}
override fun setResponse(response: String) {
responses = responses+response+"\n"
println(responses)
Log.d("DashBoardActResponse",response)
}
}

View File

@@ -1,12 +1,18 @@
package com.example.hpostesting.presentation.dashboard
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.app.DownloadManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Context.BATTERY_SERVICE
import android.content.DialogInterface
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.net.Uri
import android.os.BatteryManager
import android.os.Build
import android.os.Bundle
import android.util.Base64
import android.util.Log
@@ -14,6 +20,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
@@ -47,6 +54,7 @@ import com.google.firebase.perf.ktx.performance
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
import kotlinx.coroutines.tasks.await
import okhttp3.ResponseBody
import org.json.JSONObject
import java.io.BufferedOutputStream
@@ -58,15 +66,14 @@ import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.concurrent.atomic.AtomicBoolean
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
@AndroidEntryPoint
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
private var downloadId: Long = 0
private var isRegistered = false
private lateinit var binding: FragmentHomeBinding
private val viewModel: TestRightViewModel by activityViewModels()
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var rvAdapter: UserListAdapter
@@ -78,21 +85,12 @@ class HomeFragment : Fragment() {
private var isTokenAvailable = false
private var natsToken: String = ""
private var deviceId: String = ""
private lateinit var sharedPreference: SharedPreferences
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View? {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
Log.d("OnCreate Home Fragment", "HomeFragment calls")
// 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)
}
): View {
binding = FragmentHomeBinding.inflate(inflater, container, false)
sharedPreference = requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
DataHolder.selectedTest = null
@@ -104,11 +102,12 @@ class HomeFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)
if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") {
binding.labelQuickCapture.visibility = View.VISIBLE
binding.btnQuickCapture.visibility = View.VISIBLE
}
getDeviceId()
checkUnprocessedCSVData()
checkForUpdate()
viewModel.allUserData.observe(viewLifecycleOwner) { userData ->
deleteIncompleteRegistrations(userData)
}
@@ -128,15 +127,14 @@ class HomeFragment : Fragment() {
binding.rvOrderOffline.adapter = adapter
}
}
hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) { deviceData ->
val devicelist = mutableListOf<DeviceData>()
if (deviceData != null) {
devicelist.add(DeviceData(deviceData.deviceId))
}
}
// hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) { deviceData ->
// val devicelist = mutableListOf<DeviceData>()
// if (deviceData != null) {
// devicelist.add(DeviceData(deviceData.deviceId))
// }
//
// }
viewModel.networkStatusLiveData?.observe(viewLifecycleOwner) { isConnected ->
Log.d("NETWORK OBSERVE", "OBSERVE CALLED")
if (isConnected) {
binding.internetAvailableCL.visibility = View.VISIBLE
binding.internetNotAvailableCL.visibility = View.GONE
@@ -148,61 +146,38 @@ class HomeFragment : Fragment() {
checkForTokenAndUpdate()
}
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { originalUserDataList ->
Log.d("LOCAL_DB OBSERVE", "OBSERVE CALLED")
val resultList = MolbioV2ResultRequest(mutableListOf())
originalUserDataList.forEach { userData ->
Log.d(
": USER DATA",
originalUserDataList.count().toString() + " : " + userData._id
)
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
val resultList = MolbioV2ResultRequest(mutableListOf(MolbioV2Result()))
userDataList.forEach { userData ->
if (!userData.molbioFlag && isTokenAvailable && Constants.MOLBIO_INTEGRATION) {
val currentTimeFormatted = SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssZZZZZ",
Locale.getDefault()
).format(Calendar.getInstance().time)
val bufferIntensityThreshold =
Constants.BUFFER_INTENSITY_THRESHOLDS[userData.deviceId]?.toString()
?: "defaultThreshold" // Handle possible nulls safely
resultList.results?.add(
MolbioV2Result(
rawData = userData,
analysisId = userData._id,
analysisDate = currentTimeFormatted,
analysisStatus = userData.classificationResult
?: "defaultStatus", // Handle possible nulls
thresholds = bufferIntensityThreshold,
interpretation = userData.classificationResult
?: "defaultInterpretation", // Handle possible nulls
analysisDate = "2024-02-08 16:33:56",//userData.testTime,
analysisStatus = userData.classificationResult,
thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[userData.deviceId].toString(),
interpretation = userData.classificationResult,
testId = userData._id,
testTime = currentTimeFormatted,
collectionTime = currentTimeFormatted,
expiryTime = currentTimeFormatted
testTime = "2024-02-08 16:33:56",//userData.testTime,
collectionTime = "2024-02-08 16:33:56",//userData.testTime,
expiryTime = "2024-02-08 16:33:56"//userData.testTime,
)
)
}
}
Log.d("USER DATA LIST SIZE", resultList.results?.count().toString())
resultList.results?.forEach { result ->
val userData = result.rawData
Log.d("UserData", userData.toString())
if (userData != null) {
if (!userData.localFlag) {
hemoCubeViewModel.bulkAddResultTestToDb(userData)
userData.localFlag = true
}
if (!userData.molbioFlag && isTokenAvailable && Constants.MOLBIO_INTEGRATION) {
userData.molbioFlag = true
hemoCubeViewModel.uploadResult(resultList)
}
}
// Upload results after processing all userData to avoid duplicates and ensure all modifications are done
if (resultList.results?.isNotEmpty() == true) {
hemoCubeViewModel.uploadResult(resultList)
}
}
if (!userData.localFlag) {
userData.localFlag = true
hemoCubeViewModel.bulkAddResultTestToDb(userData)
}
}
}
} else {
binding.internetAvailableCL.visibility = View.GONE
@@ -281,9 +256,6 @@ class HomeFragment : Fragment() {
var password = sharedPreference.getString(Constants.DEVICE_PASSWORD_API, "").toString()
var userID = sharedPreference.getString(Constants.DEVICE_ID_API, "").toString()
deviceId = sharedPreference.getString(Constants.DEVICE_ID, "").toString()
Log.e("idpass", userID)
Log.e("idpass", password)
Log.e("idpass", deviceId)
if (userID.isNotEmpty() && password.isNotEmpty()) {
if (!isTokenAvailable) {
hemoCubeViewModel.login(createLoginRequestData(userID, password))
@@ -314,31 +286,7 @@ class HomeFragment : Fragment() {
hemoCubeViewModel.uploadLogs()
hemoCubeViewModel.startPeriodicCheckUpdate()
}
}
// } else if (fis.available()>0){
// val buffer = ByteArray(fis.available())
// fis.read(buffer)
// fis.close()
// val encryptedData = String(buffer)
// val parts = encryptedData.split(",".toRegex()).dropLastWhile { it.isEmpty() }
// .toTypedArray()
// val deviceID = parts[0]
// val decryptedUsername = decrypt(parts[1])
// val decryptedPassword = decrypt(parts[2])
// if (accessToken.isEmpty()) {
// hemoCubeViewModel.login(createLoginRequestData(decryptedUsername, decryptedPassword))
//}
// else {
// // Continue with your existing logic if the token is not empty.
// isTokenAvailable = true
// hemoCubeViewModel.deviceUpdate(createDeviceUpdateRequestData())
// hemoCubeViewModel.uploadLogs()
// hemoCubeViewModel.startPeriodicCheckUpdate()
// }
//}
else {
} else {
Toast.makeText(
requireContext(),
"Contact Help and get your device provision done",
@@ -400,8 +348,6 @@ class HomeFragment : Fragment() {
}
}
hemoCubeViewModel.downloadcertificate.observe(viewLifecycleOwner) { response ->
when (response) {
is Result.Success -> {
@@ -448,7 +394,6 @@ class HomeFragment : Fragment() {
hemoCubeViewModel.resultUpload.observe(viewLifecycleOwner) {
when (it) {
is Result.Success -> {
Log.d("MOLBIO UPLOAD", "RESULT SUCCESS")
it.data.data?.forEach { id ->
id.rawData?.let { it1 ->
hemoCubeViewModel.updateMolbioFlag(
@@ -456,22 +401,18 @@ class HomeFragment : Fragment() {
)
}
}
}
is Result.Error -> {
binding.btnSubmit.visibility = View.VISIBLE
//Remove this line of code while deploying to IOCL
it.exception.let { message ->
Toast.makeText(activity, "An error occurred: $message", Toast.LENGTH_LONG)
.show()
}
}
else -> {
}
else -> {}
}
}
@@ -880,6 +821,39 @@ class HomeFragment : Fragment() {
}
}
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
val resultList = MolbioV2ResultRequest(mutableListOf(MolbioV2Result()))
userDataList.forEach { userData ->
if (!userData.molbioFlag && isTokenAvailable) {
resultList.results?.add(
MolbioV2Result(
rawData = userData,
analysisId = userData._id,
analysisDate = "2024-02-08 16:33:56", //userData.reportUploadTime,
analysisStatus = userData.classificationResult,
thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[userData.deviceId].toString(),
interpretation = userData.classificationResult,
testId = userData._id,
testTime = userData.testTime,
collectionTime = "2024-02-08 16:33:56",//userData.testTime,
expiryTime = "2024-02-08 16:33:56",//userData.testTime,
)
)
}
if (!userData.localFlag) {
userData.localFlag = true
hemoCubeViewModel.bulkAddResultTestToDb(userData)
}
if (!userData.molbioFlag && isTokenAvailable && Constants.MOLBIO_INTEGRATION) {
userData.molbioFlag = true
hemoCubeViewModel.uploadResult(resultList)
}
}
dialog.dismiss()
}
hemoCubeViewModel.allKitTestData.observe(viewLifecycleOwner) { kitDataList ->
kitDataList.forEach { userData ->
if (!userData.localFlag) {
@@ -890,6 +864,36 @@ class HomeFragment : Fragment() {
dialog.dismiss()
}
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
val resultList = MolbioV2ResultRequest(mutableListOf(MolbioV2Result()))
userDataList.forEach { userData ->
if (!userData.molbioFlag && isTokenAvailable) {
resultList.results?.add(
MolbioV2Result(
rawData = userData,
analysisId = userData._id,
analysisDate = "2024-02-08 16:33:56",//userData.testTime,
analysisStatus = userData.classificationResult,
thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[userData.deviceId].toString(),
interpretation = userData.classificationResult,
testId = userData._id,
testTime = "2024-02-08 16:33:56",//userData.testTime,
collectionTime = "2024-02-08 16:33:56",//userData.testTime,
expiryTime = "2024-02-08 16:33:56"//userData.testTime,
)
)
userData.molbioFlag = true
hemoCubeViewModel.uploadResult(resultList)
}
if (!userData.localFlag) {
userData.localFlag = true
hemoCubeViewModel.bulkAddResultTestToDb(userData)
}
}
dialog.dismiss()
}
}
// private fun downloadLocalDBData(dialog: DialogInterface) {
@@ -932,7 +936,6 @@ class HomeFragment : Fragment() {
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun downloadCsv() {
@@ -1048,5 +1051,168 @@ class HomeFragment : Fragment() {
val matchResult = regex.find(receivedData)
return matchResult?.groups?.get(1)?.value ?: ""
}
@SuppressLint("SuspiciousIndentation")
private fun checkForUpdate() {
try {
val db = Firebase.firestore
val deviceId="HHH-AAA-ZZZ"
val deviceRef = db.collection("deviceUpdate").document(Constants.DOCUMENT_ID_FOR_UPDATE)
deviceRef.get().addOnSuccessListener { documentSnapshot ->
if (documentSnapshot.exists()) {
val deviceData =
documentSnapshot.toObject(DeviceData::class.java)
// deviceData?.let { data ->
val deviceVersion = deviceData!!.deviceVersion
val deviceUpdateAvailableGlobal= deviceData.deviceUpdateAvailable
val updatePathGlobal= deviceData.updatePath
// if(deviceUpdateAvailableGlobal){
db.collection("devices").whereEqualTo("deviceId", deviceId).get().addOnSuccessListener { documentSnapshotNew ->
if (documentSnapshotNew.documents.isNotEmpty()) {
documentSnapshotNew.documents.forEach{
val documentIn = it.toObject(DeviceData::class.java)
val globalUpdateIgnore = documentIn!!.globalUpdateIgnore
val deviceUpdateAvailable = documentIn.deviceUpdateAvailable
val globalUpdateDone = documentIn.globalUpdateDone
val updatePath = documentIn.updatePath
if(globalUpdateIgnore){
if(deviceUpdateAvailable){
val update = db.collection("devices").document(it.id).update("deviceUpdateAvailable",false)
update.addOnSuccessListener {
Log.d("HomeFragmentUpdate","Device local update done")
initiateUpdate(updatePath)
}.addOnFailureListener{
Log.e("fetchDeviceUpdate", "update fail.")
}
}else{
Log.d("HomeFragmentUpdate","Device update not available")
}
}else{
if(!globalUpdateDone){
val update = db.collection("devices").document(it.id).update("globalUpdateDone",true)
update.addOnSuccessListener {
Log.d("HomeFragmentUpdate","Device global update done")
initiateUpdate(updatePathGlobal)
}.addOnFailureListener{
Log.e("fetchDeviceUpdate", "update fail.")
}
}
}
}
} else {
Log.e("fetchDeviceUpdate", "Document does not exist.")
}
}.addOnFailureListener { exception ->
Log.e("fetchDeviceUpdate", "Error fetching device data", exception)
}
// Toast.makeText(requireActivity()," true -version."+deviceVersion+"updatePath.."+updatePath,Toast.LENGTH_LONG).show()
// Log for debugging
Log.d(
"fetchDeviceCredentials",
"deviceVersion: $deviceVersion, Password: $deviceUpdateAvailableGlobal, updatePath: $updatePathGlobal"
)
// } ?: Log.e("fetchDeviceUpdate", "Failed to parse device data.")
} else {
Log.e("fetchDeviceUpdate", "Document does not exist.")
}
}
.addOnFailureListener { exception ->
Log.e("fetchDeviceUpdate", "Error fetching device data", exception)
}
} catch (e: Exception) {
Log.e("fetchDeviceUpdate", "Error in fetchDeviceUpdate", e)
}
}
private fun initiateUpdate(url: String) {
val apkUrl = url
if (!isValidHttpUrl(apkUrl)) {
return
}
val request = DownloadManager.Request(Uri.parse(apkUrl))
request.setTitle("App Update")
request.setDescription("Downloading update...")
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalFilesDir(requireActivity(), "Updates", "update.apk")
val downloadManager = requireActivity().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
downloadId = downloadManager.enqueue(request)
// Register a BroadcastReceiver to receive the download complete event
val filter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
isRegistered = true
requireActivity().registerReceiver(downloadReceiver, filter, Context.RECEIVER_EXPORTED)
}
}
private fun extractApkUrl(responseBody: ResponseBody): String {
return responseBody.string()
}
private fun isValidHttpUrl(url: String): Boolean {
return url.startsWith("http://") || url.startsWith("https://")
}
private val downloadReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
if (id == downloadId) {
installApk()
}
}
}
private fun installApk() {
val file = File(requireActivity().getExternalFilesDir("Updates"), "update.apk")
file.setReadable(true, false) // Ensure the file is readable
val pInfo = requireActivity().baseContext.packageManager.getPackageInfo(requireActivity().baseContext.packageName, 0)
Log.d("HomeFragmentShowInfo",pInfo.packageName.toString())
val uri: Uri = FileProvider.getUriForFile(
requireActivity(),
"${pInfo.packageName}.fileprovider",
file
)
// Create an intent to install the APK
val installIntent = Intent(Intent.ACTION_INSTALL_PACKAGE)
installIntent.data = uri
installIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_CLEAR_TOP
installIntent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
// Start the installation
startActivity(installIntent)
Log.d("InstallApk", "Install Intent URI: $uri")
Log.d("InstallApk", "Package Name: ${requireActivity().packageName}")
}
override fun onDestroy() {
try {
if (isRegistered){
requireActivity().unregisterReceiver(downloadReceiver)
}
}catch (e: IllegalArgumentException){
Log.e("HOmeFragment",e.toString())
}
super.onDestroy()
}
}

View File

@@ -93,6 +93,7 @@ class DeviceProvisionActivity : AppCompatActivity(), DeviceCommunicationHandler
supportActionBar?.setDisplayHomeAsUpEnabled(true)
setupListener()
connectUsb(false)
}
private fun setupListener() {

View File

@@ -15,7 +15,6 @@ import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.encryption.AESCrypt
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener
@@ -24,7 +23,6 @@ import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDeviceProvisionBinding
class DeviceProvisionFragment : Fragment() {
private var resultData: String = ""
private lateinit var binding: FragmentDeviceProvisionBinding
@@ -125,9 +123,6 @@ class DeviceProvisionFragment : Fragment() {
Log.e("idpass", response.toString())
Log.e("idpass", response.data.data?.credentials?.username.toString())
Log.e("idpass", deviceProvisionResponse)
saveDataToLocalFile(response.data.data?.credentials?.username.toString(), response.data.data?.credentials?.password.toString())
} else {
Toast.makeText(
activity,
@@ -223,18 +218,4 @@ class DeviceProvisionFragment : Fragment() {
}
}
}
//saves username and password to a local file after encrypting it.
private fun saveDataToLocalFile( username : String, password : String){
val deviceID = sharedPreferences.getString(Constants.DEVICE_ID, "").toString();
val encryptedUsername = AESCrypt.encrypt(username)
val encryptedPassword = AESCrypt.encrypt(password)
val encryptedData = deviceID + "\n" + encryptedUsername + "\n" + encryptedPassword
val fileOutputStream = requireContext().openFileOutput("credentials.txt", Context.MODE_PRIVATE)
fileOutputStream.write(encryptedData.toByteArray())
fileOutputStream.close()
}
}

View File

@@ -1,5 +1,6 @@
package com.example.hpostesting.presentation.hemocube
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
@@ -90,8 +91,11 @@ class HemoCubeFragment : Fragment() {
observeViewModel()
}
@SuppressLint("SetTextI18n")
private fun initViews() {
binding.btnSubmit.setOnClickListener {
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
activity?.runOnUiThread {
binding.progressBar.visibility = View.VISIBLE
binding.btnSubmit.visibility = View.GONE
@@ -106,8 +110,6 @@ class HemoCubeFragment : Fragment() {
binding.nameEditText.visibility = View.GONE
binding.tvTitle.visibility = View.GONE
binding.btnGo.visibility = View.GONE
// binding.btnSubmit.isEnabled = false
// binding.btnSubmit.isClickable = false
binding.btnPlacebuffer.visibility = View.GONE
binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}"
@@ -585,8 +587,7 @@ class HemoCubeFragment : Fragment() {
led1Gain4 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2Gain4 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3Gain4 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
led4Gain4 =
resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
led4Gain4 = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
}
finishReading()
@@ -764,6 +765,7 @@ class HemoCubeFragment : Fragment() {
val led3Average = log10(led3BufferForDevice.div(led3SampleForDevice))
val led4Average = log10(led4BufferForDevice.div(led4SampleForDevice))
val deviceRatio = led2Average / led1Average
val borderlineMetric = (led1Average - led2Average) / deviceRatio
if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0)
?.get(0)!!
@@ -861,7 +863,7 @@ class HemoCubeFragment : Fragment() {
}
}
var absorbanceLowerLimit = 0.0
val absorbanceLowerLimit = 0.0
if (led1Average < absorbanceLowerLimit || led2Average < absorbanceLowerLimit || led3Average < absorbanceLowerLimit || led4Average < absorbanceLowerLimit) {
validationError = true
activity?.runOnUiThread {
@@ -908,8 +910,13 @@ class HemoCubeFragment : Fragment() {
.toString() + ", " + currentDeviceData?.coefficients?.get(1).toString()
this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio)
this.deviceRatioClass = deviceRatioClassification(deviceRatio)
this.borderlineMethod2Class = reclassifyWithBorderlineMethod2(deviceRatio, deviceRatioBorderlineThresholds(deviceRatio), led2Average)
this.slopeRatioClass = slopeClass
this.classificationResult = deviceRatioClass
this.classificationResult = findResultWithAdditionalMethods(
deviceRatio,
deviceRatioClass,
borderlineMetric
)
hemoCubeViewModel.messages.postValue(
"${this.classificationResult} \n Device Ratio: ${
"%.3f".format(
@@ -950,17 +957,20 @@ class HemoCubeFragment : Fragment() {
}
}
fun findResultWithAdditionalMethods(
deviceRatio: Double?,
deviceRatioClass: String?,
slopeRatio: Double?,
): String {
fun reclassifyWithBorderlineMethod2(deviceRatio: Double?, deviceRatioClass: String?, led2Average: Double?): String {
try {
// hemoCubeViewModel.messages.postValue("post classification checks")
if (deviceRatio != null) {
if (slopeRatio != null) {
if (deviceRatioClass == "Normal" && slopeRatio > 45.0)
return "Negative Borderline, Repeat Test"
if (deviceRatio != null && led2Average != null) {
if (deviceRatioClass == "Negative Borderline") {
return if (led2Average >= 0.15)
"Borderline. Normal"
else
"Borderline. Sickle Cell Trait"
}
if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") {
return if (led2Average >= 0.19)
"Borderline. Sickle Cell Trait"
else
"Borderline. Sickle Cell Disease"
}
}
} catch (e: Exception) {
@@ -970,20 +980,74 @@ class HemoCubeFragment : Fragment() {
return deviceRatioClass.toString()
}
fun deviceRatioClassification(ratio: Double?): String {
fun findResultWithAdditionalMethods(
deviceRatio: Double?,
deviceRatioClass: String?,
borderlineMetric: Double?,
): String {
try {
// hemoCubeViewModel.messages.postValue("post classification checks")
if (deviceRatio != null && borderlineMetric != null) {
if (deviceRatioClass == "Negative Borderline") {
return if (borderlineMetric >= 2.4)
"Borderline. Normal"
else
"Borderline. Sickle Cell Trait"
}
if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") {
return if (borderlineMetric >= 1.34)
"Borderline. Sickle Cell Trait"
else
"Borderline. Sickle Cell Disease"
}
}
} catch (e: Exception) {
handleException(e)
return "Error"
}
return deviceRatioClass.toString()
}
fun deviceRatioBorderlineThresholds(ratio: Double?): String {
try {
if (ratio != null) {
if (ratio in 0.016..0.22) {
val roundedRatio = String.format("%.3f", ratio).toDouble()
if (roundedRatio >= 0.11 && roundedRatio < 0.237) {
// setSubtitleTextColor(R.color.green_2)
return "Normal"
}
if (ratio in 0.22..0.24)
if (roundedRatio in 0.237..0.242)
return "Negative Borderline"
if (ratio in 0.24..0.32)
if (roundedRatio in 0.242..0.318)
return "Sickle Cell Trait"
if (ratio in 0.32..0.37)
if (roundedRatio >= 0.318 && roundedRatio < 0.356)
return "Positive for Sickle Cell. HPLC for Confirmation"
if (ratio in 0.37..0.56)
if (roundedRatio in 0.356..0.7)
return "Sickle Cell Disease"
} else {
return "Invalid"
}
} catch (e: Exception) {
handleException(e)
return "Error"
}
return "Invalid"
}
fun deviceRatioClassification(ratio: Double?): String {
try {
if (ratio != null) {
if (ratio in 0.16..0.23) {
// setSubtitleTextColor(R.color.green_2)
return "Normal"
}
if (ratio in 0.23..0.25)
return "Negative Borderline"
if (ratio in 0.25..0.31)
return "Sickle Cell Trait"
if (ratio in 0.31..0.36)
return "Positive for Sickle Cell. HPLC for Confirmation"
if (ratio in 0.36..0.7)
return "Sickle Cell Disease"
} else {
return "Invalid"

View File

@@ -88,6 +88,7 @@ class HemoCubeViewModel @Inject constructor(
private val _networkStatusLiveData = NetworkStatusLiveData(context)
val allUserData = hemoCubeDao.getAll()
val allPendingUserToUpload = MutableLiveData<List<HemoCubeTestData>>()
val allKitTestData = hemoCubeBufferDao.getAll()
val deviceData = MutableLiveData<DeviceData?>()
@@ -137,7 +138,6 @@ class HemoCubeViewModel @Inject constructor(
fun uploadResult(molbioV2ResultRequest: MolbioV2ResultRequest) = viewModelScope.launch {
resultUpload.postValue(Result.Loading())
Log.d("API CALL", "UPLOADED RESULT")
repository.uploadResults(molbioV2ResultRequest).let {
resultUpload.postValue(it)
}
@@ -187,6 +187,9 @@ class HemoCubeViewModel @Inject constructor(
}
}
}
fun uploadPendingUser() = viewModelScope.launch {
allPendingUserToUpload.postValue(hemoCubeDao.getPendingUser(false))
}
fun uploadHemoCubeResultToDatabaseForBufferCheck(
isOnline: Boolean,
@@ -291,6 +294,7 @@ class HemoCubeViewModel @Inject constructor(
testDetails?.prdClassification = DataHolder.hemoCubeTestData?.prdClassification.toString()
testDetails?.deviceRatioClass = DataHolder.hemoCubeTestData?.deviceRatioClass.toString()
testDetails?.slopeRatioClass = DataHolder.hemoCubeTestData?.slopeRatioClass.toString()
testDetails?.borderlineMethod2Class = DataHolder.hemoCubeTestData?.borderlineMethod2Class.toString()
testDetails?.errorMessages = DataHolder.hemoCubeTestData?.errorMessages.toString()
testDetails?.batteryLevel = DataHolder.hemoCubeTestData?.batteryLevel.toString()
testDetails?.batteryCapacity = DataHolder.hemoCubeTestData?.batteryCapacity.toString()
@@ -408,6 +412,8 @@ class HemoCubeViewModel @Inject constructor(
Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
}
else -> {}
}
} catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}")

View File

@@ -33,32 +33,53 @@ class UsbService : Service() {
var bus: UsbServiceListener? = null
fun connect(driver: UsbSerialDriver, connection: UsbDeviceConnection) {
mPort = driver.ports[0] // Most devices have just one port (port 0)
mPort.open(connection)
mPort.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
isUsbConnected = true
Log.d(TAG, "My Usb Connected ${mPort.driver}")
try {
mPort = driver.ports[0]
mPort.open(connection)
val usbIoManager = SerialInputOutputManager(mPort,
object : SerialInputOutputManager.Listener {
override fun onNewData(data: ByteArray?) {
listener?.onUsbRead(data)
}
if (mPort.device.vendorId == 6790 && mPort.device.productId == 29987)
mPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
else
mPort.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
override fun onRunError(e: Exception?) {
Log.e(TAG, "onRunError() called inside eventDrivenWrite()")
listener?.onUsbError(e)
}
isUsbConnected = true
Log.d(TAG, "Usb Connected ${mPort.driver}")
})
usbIoManager.start();
val usbIoManager = SerialInputOutputManager(mPort,
object : SerialInputOutputManager.Listener {
override fun onNewData(data: ByteArray?) {
listener?.onUsbRead(data)
}
override fun onRunError(e: Exception?) {
Log.e(TAG, "onRunError() called")
listener?.onUsbError(e)
}
})
usbIoManager.start()
} catch (ioException: IOException) {
Log.e(TAG, "IOException during USB connection: ${ioException.message}", ioException)
listener?.onUsbError(ioException)
} catch (e: Exception) {
Log.e(TAG, "Error connecting USB: ${e.message}", e)
listener?.onUsbError(e)
}
}
fun disconnect() {
if (isUsbConnected) {
mPort.close()
isUsbConnected = false;
Log.d(TAG, "My Usb disconnected:: ${mPort.driver}")
try {
if (isUsbConnected) {
mPort.close()
isUsbConnected = false
Log.d(TAG, "USB Port closed successfully:: ${mPort.driver}")
} else {
Log.d(TAG, "USB Port is not connected")
}
} catch (e: IOException) {
Log.e(TAG, "Error closing USB Port: ${e.message}", e)
} catch (e: Exception) {
Log.e(TAG, "An unexpected error occurred: ${e.message}", e)
}
}

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/card_blue_app" />
<corners android:radius="20dp" />
</shape>
</item>
</selector>

View File

@@ -1,5 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#EF0A0A" android:viewportHeight="24"
android:tint="#FF1010" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M17,7l-1.41,1.41L18.17,11H8v2h10.17l-2.58,2.58L17,17l5,-5zM4,5h8V3H4c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h8v-2H4V5z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="15dp" />
<solid android:color="#D7FF0000" />
</shape>

View File

@@ -3,7 +3,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
tools:ignore="ExtraText">
<solid android:color="@android:color/transparent" />
<corners android:radius="10dp" />
<stroke
android:color="#000000"
android:width="2dp" />
android:width="1dp" />
</shape>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/white" />
<corners android:radius="20dp" />
<stroke android:color="@color/red" android:width="1dp" />
</shape>
</item>
</ripple>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Drop Shadow -->
<item>
<shape android:shape="rectangle">
<solid android:color="#4D000000" /> <!-- Semi-transparent black color -->
<corners android:radius="20dp" />
</shape>
</item>
<!-- Original Shape with Blue Color -->
<item android:top="5dp" android:right="5dp" android:left="5dp" android:bottom="5dp">
<shape android:shape="rectangle">
<solid android:color="@color/card_blue_app" />
<corners android:radius="20dp" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/new_blue" />
<corners android:radius="10dp" /> <!-- Adjust the radius as needed -->
</shape>

View File

@@ -15,7 +15,7 @@
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:titleTextColor="#FFFFFF"
app:titleTextColor="@color/blue_text_color"
android:elevation="4dp"
app:menu="@menu/my_menu"
android:theme="@style/ToolbarTheme"

View File

@@ -19,6 +19,7 @@
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_dashboard"
app:menu="@menu/activity_main_drawer" />
app:menu="@menu/activity_main_drawer"
app:itemIconTint="@color/blue_text_color" />
</androidx.drawerlayout.widget.DrawerLayout>

View File

@@ -13,7 +13,7 @@
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:titleTextColor="#FFFFFF"
app:titleTextColor="@color/blue_text_color"
android:elevation="4dp"
app:menu="@menu/my_menu"
android:theme="@style/ToolbarTheme"

View File

@@ -32,6 +32,7 @@
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/scan_qr_code_of_the_kit"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/app_bar_layout" />
@@ -40,11 +41,12 @@
android:layout_width="258dp"
android:layout_height="56dp"
android:layout_margin="24dp"
android:drawableLeft="@drawable/baseline_qr_code_scanner_24"
android:drawableLeft="@drawable/baseline_qr_code_scanner_24_x"
android:text="@string/scan_now"
android:textColor="@color/black"
app:backgroundTint="@color/blue_app_light"
app:cornerRadius="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
@@ -75,7 +77,7 @@
android:layout_centerVertical="true"
android:layout_marginLeft="16dp"
android:layout_toLeftOf="@id/tvText1"
android:background="@color/gray" />
android:background="@color/red" />
<View
android:layout_width="match_parent"
@@ -83,7 +85,7 @@
android:layout_centerVertical="true"
android:layout_marginRight="16dp"
android:layout_toRightOf="@id/tvText1"
android:background="@color/gray" />
android:background="@color/red" />
</RelativeLayout>
@@ -96,6 +98,7 @@
android:layout_marginHorizontal="24dp"
android:layout_marginTop="48dp"
android:text="@string/enter_kit_serial_number_manually"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/seperator1" />
@@ -121,13 +124,15 @@
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/go"
app:cornerRadius="16dp"
android:textColor="@color/red"
android:background="@drawable/button_new"
app:layout_constraintBottom_toBottomOf="@id/et_abha_id"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"

View File

@@ -15,7 +15,7 @@
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:titleTextColor="#FFFFFF"
app:titleTextColor="@color/blue_text_color"
android:elevation="4dp"
app:menu="@menu/my_menu"
android:theme="@style/ToolbarTheme"

View File

@@ -13,7 +13,7 @@
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:titleTextColor="#FFFFFF"
app:titleTextColor="@color/blue_text_color"
android:elevation="4dp"
app:menu="@menu/my_menu"
android:theme="@style/ToolbarTheme"

View File

@@ -14,8 +14,9 @@
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
app:titleTextColor="@color/blue_text_color"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:background="@color/new_blue"
app:popupTheme="@style/Theme.HPOS.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>

View File

@@ -71,7 +71,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/spinner_concentration" />
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -80,8 +80,9 @@
android:clickable="false"
android:gravity="center"
android:text="Continue"
android:textColor="@color/white"
android:textColor="@color/red"
app:cornerRadius="16dp"
android:background="@drawable/button_new"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_readings_per_sample" />

View File

@@ -47,41 +47,48 @@
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="380dp"
android:background="@drawable/baground_auto_dac"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:gravity="center"
android:text="Start"
android:textColor="@color/black"
android:textSize="11sp"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" />
<Button
<androidx.appcompat.widget.AppCompatButton
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:paddingRight="5dp"
android:paddingLeft="5dp"
android:background="@drawable/button_new"
android:gravity="center"
android:text="Start Auto DAC"
android:textColor="@color/white"
android:textColor="@color/red"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_read_dac"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:gravity="center"
android:text="Read Current DAC Values"
android:textColor="@color/white"
android:textColor="@color/red"
android:background="@drawable/button_new"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_submit" />

View File

@@ -50,38 +50,45 @@
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:gravity="center"
android:background="@drawable/baground_auto_dac"
android:text="Start"
android:textColor="@color/black"
android:textSize="11sp"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" />
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:gravity="center"
android:background="@drawable/button_new"
android:text="Start Auto DAC"
android:textColor="@color/white"
android:textColor="@color/red"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_read_dac"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:clickable="false"
android:gravity="center"
android:background="@drawable/button_new"
android:text="Read Current DAC Values"
android:textColor="@color/white"
android:textColor="@color/red"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_submit" />

View File

@@ -37,6 +37,8 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:orientation="horizontal"
android:background="@drawable/border"
app:layout_constraintEnd_toEndOf="parent"
@@ -70,8 +72,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:layout_marginTop="36dp"
android:orientation="horizontal"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:background="@drawable/border"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -104,8 +108,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:layout_marginTop="36dp"
android:orientation="horizontal"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:background="@drawable/border"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -138,8 +144,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:layout_marginTop="36dp"
android:orientation="horizontal"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:background="@drawable/border"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -174,7 +182,7 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:layout_marginTop="36dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/llLed4Fields" />
@@ -185,26 +193,30 @@
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="8dp"
android:layout_marginTop="60dp"
android:gravity="center"
android:text="Start"
android:background="@drawable/baground_auto_dac"
android:textColor="@color/black"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" />
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="10dp"
android:layout_marginTop="60dp"
android:clickable="false"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:gravity="center"
android:text="Save"
android:background="@drawable/button_new"
app:cornerRadius="100dp"
android:textColor="@color/white"
android:textColor="@color/red"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />

View File

@@ -13,6 +13,7 @@
android:layout_marginHorizontal="24dp"
android:layout_marginTop="50dp"
android:gravity="center"
android:background="@drawable/baground_auto_dac"
android:text="Start"
android:textColor="@color/black"
android:textSize="16sp"

View File

@@ -51,6 +51,7 @@
android:layout_marginTop="16dp"
android:gravity="center"
android:text="Start"
android:background="@drawable/baground_auto_dac"
android:textColor="@color/red"
android:textSize="22sp"
app:layout_constraintEnd_toEndOf="parent"
@@ -58,7 +59,7 @@
app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" />
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -66,8 +67,9 @@
android:layout_marginTop="24dp"
android:clickable="false"
android:gravity="center"
android:background="@drawable/button_new"
android:text="Start"
android:textColor="@color/white"
android:textColor="@color/red"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />

View File

@@ -26,121 +26,130 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/check_buffer"
android:textColor="@color/white"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />
<Button
android:id="@+id/btn_diagnostics"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/diagnostics"
android:textColor="@color/white"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_submit" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_auto_dac"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/auto_dac"
android:textColor="@color/white"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_diagnostics" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_calibration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/calibration"
android:textColor="@color/white"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_auto_dac" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_deviceInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/deviceinfo"
android:textColor="@color/white"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_calibration" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_deviceProvision"
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/deviceProvision"
android:textColor="@color/white"
app:cornerRadius="16dp"
android:columnCount="2"
android:rowCount="4"
android:layout_margin="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_deviceInfo" />
app:layout_constraintTop_toBottomOf="@+id/tv_subtitle4"
>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_firefox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/Firefox"
android:textColor="@color/white"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_deviceProvision" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_files"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/Files"
android:textColor="@color/white"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_firefox" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_submit"
android:layout_width="160dp"
android:layout_height="120dp"
android:textSize="14dp"
android:layout_margin="8sp"
android:layout_gravity="center"
android:clickable="false"
android:background="@drawable/pannel_button"
android:text="@string/check_buffer"
android:textColor="@color/blue_text_color" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_diagnostics"
android:layout_width="160dp"
android:layout_height="120dp"
android:layout_margin="8sp"
android:textSize="14dp"
android:layout_gravity="center"
android:text="diagnostics"
android:clickable="false"
android:background="@drawable/pannel_button"
android:textColor="@color/blue_text_color" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_auto_dac"
android:layout_width="160dp"
android:layout_height="120dp"
android:textSize="14dp"
android:layout_gravity="center"
android:layout_margin="8sp"
android:clickable="false"
android:text="@string/auto_dac"
android:background="@drawable/pannel_button"
android:textColor="@color/blue_text_color"
app:cornerRadius="16dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_calibration"
android:layout_width="160dp"
android:layout_height="120dp"
android:textSize="14dp"
android:layout_gravity="center"
android:layout_margin="8sp"
android:clickable="false"
android:text="@string/calibration"
android:background="@drawable/pannel_button"
android:textColor="@color/blue_text_color"
app:cornerRadius="16dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_deviceInfo"
android:layout_width="160dp"
android:layout_gravity="center"
android:textSize="14dp"
android:layout_height="120dp"
android:layout_margin="8sp"
android:clickable="false"
android:text="@string/deviceinfo"
android:background="@drawable/pannel_button"
android:textColor="@color/blue_text_color"
app:cornerRadius="16dp" />
<Button
android:id="@+id/btn_deviceProvision"
android:layout_width="160dp"
android:layout_height="120dp"
android:layout_margin="8sp"
android:textSize="14dp"
android:layout_gravity="center"
android:text="@string/deviceProvision"
android:background="@drawable/pannel_button"
android:textColor="@color/blue_text_color"
android:visibility="visible"
app:cornerRadius="16dp" />
<Button
android:id="@+id/btn_firefox"
android:layout_width="160dp"
android:layout_height="120dp"
android:textSize="14dp"
android:layout_margin="8sp"
android:clickable="false"
android:layout_gravity="center"
android:text="@string/Firefox"
android:background="@drawable/pannel_button"
android:textColor="@color/blue_text_color"
app:cornerRadius="16dp" />
<Button
android:id="@+id/btn_files"
android:layout_width="160dp"
android:layout_height="120dp"
android:layout_margin="8sp"
android:textSize="14dp"
android:layout_gravity="center"
android:clickable="false"
android:text="@string/Files"
android:background="@drawable/pannel_button"
android:textColor="@color/blue_text_color"
app:cornerRadius="16dp"
tools:layout_editor_absoluteX="208dp"
tools:layout_editor_absoluteY="240dp" />
</GridLayout>
</androidx.constraintlayout.widget.ConstraintLayout
>
</ScrollView>

View File

@@ -98,7 +98,7 @@
<!-- app:layout_constraintTop_toBottomOf="@id/btn_submit" />-->
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -106,7 +106,8 @@
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/submit"
android:textColor="@color/white"
android:textColor="@color/red"
android:background="@drawable/button_new"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />

View File

@@ -108,8 +108,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="48dp"
android:text="@string/enter_kit_serial_number_manually"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints" />
@@ -135,13 +135,15 @@
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/go"
app:cornerRadius="16dp"
android:textColor="@color/red"
android:background="@drawable/button_new"
app:layout_constraintBottom_toBottomOf="@id/et_abha_id"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
@@ -164,7 +166,7 @@
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_placebuffer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -172,7 +174,8 @@
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/place_buffer"
android:textColor="@color/white"
android:background="@drawable/button_new"
android:textColor="@color/red"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -217,6 +220,7 @@
android:text="no device message"
android:textColor="@color/black"
android:textSize="11sp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/error_message" />

View File

@@ -131,8 +131,10 @@
android:id="@+id/internetAvailableCL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp"
android:visibility="visible"
android:padding="24dp">
tools:layout_editor_absoluteX="162dp"
tools:layout_editor_absoluteY="-82dp">
<TextView
android:id="@+id/tv_title"
@@ -153,6 +155,7 @@
app:layout_constraintBottom_toBottomOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/tv_title" />
<ImageView
android:id="@+id/btnLogout"
android:layout_width="30dp"
@@ -211,8 +214,9 @@
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="0dp"
android:orientation="horizontal"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView4">
@@ -249,52 +253,58 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/radioGroup"
tools:listitem="@layout/user_item_view"/>
tools:listitem="@layout/user_item_view" />
<TextView
android:id="@+id/labelQuickCapture"
style="@style/title1_1"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Quick Capture"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/btnQuickCapture"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/btnQuickCapture"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:backgroundTint="@color/primary"
android:contentDescription="Capture measurements quickly"
android:src="@drawable/flask"
android:text="Quick Capture"
android:visibility="visible"
app:elevation="1dp"
app:layout_constraintBottom_toTopOf="@+id/label"
app:icon="@drawable/flask"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@+id/label"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/label"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="2dp"
android:layout_height="6dp"
android:layout_marginBottom="8dp"
android:background="@drawable/rounded_corner_background"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:text="@string/new_kit"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/btnNewKit"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/btnNewKit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:backgroundTint="@color/primary"
android:contentDescription="@string/new_kit"
android:src="@drawable/ic_add"
android:text="@string/new_kit"
app:elevation="1dp"
app:icon="@drawable/ic_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />

View File

@@ -38,6 +38,7 @@
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="Scan to get the code"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />
@@ -58,11 +59,12 @@
android:layout_width="258dp"
android:layout_height="56dp"
android:layout_margin="24dp"
android:drawableLeft="@drawable/baseline_qr_code_scanner_24"
android:drawableLeft="@drawable/baseline_qr_code_scanner_24_x"
android:text="@string/scan_now"
android:textColor="@color/black"
app:backgroundTint="@color/blue_app_light"
app:cornerRadius="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
@@ -90,9 +92,9 @@
android:clickable="false"
android:gravity="center"
android:text="Refresh"
android:visibility="visible"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="@id/btn_scan_now"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_scan_now" />

View File

@@ -52,6 +52,10 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
app:boxCornerRadiusBottomEnd="10dp"
app:boxCornerRadiusBottomStart="10dp"
app:boxCornerRadiusTopEnd="10dp"
app:boxCornerRadiusTopStart="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView">
@@ -70,6 +74,10 @@
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:boxCornerRadiusBottomEnd="10dp"
app:boxCornerRadiusBottomStart="10dp"
app:boxCornerRadiusTopEnd="10dp"
app:boxCornerRadiusTopStart="10dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -84,12 +92,14 @@
android:maxLength="12" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="150dp"
android:layout_height="match_parent"
android:layout_marginTop="16dp"
android:text="@string/login"
android:background="@drawable/button_new"
android:textColor="@color/red"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@@ -16,6 +16,7 @@
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/scan_patient_abha_id_card"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -25,11 +26,12 @@
android:layout_height="56dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:drawableLeft="@drawable/baseline_qr_code_scanner_24"
android:drawableLeft="@drawable/baseline_qr_code_scanner_24_x"
android:text="@string/scan_now"
android:textColor="@color/black"
app:backgroundTint="@color/blue_app_light"
app:cornerRadius="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
@@ -60,7 +62,7 @@
android:layout_centerVertical="true"
android:layout_marginLeft="16dp"
android:layout_toLeftOf="@id/tvText1"
android:background="@color/gray" />
android:background="@color/red" />
<View
android:layout_width="match_parent"
@@ -68,7 +70,7 @@
android:layout_centerVertical="true"
android:layout_marginRight="16dp"
android:layout_toRightOf="@id/tvText1"
android:background="@color/gray" />
android:background="@color/red" />
</RelativeLayout>
@@ -81,6 +83,7 @@
android:layout_marginHorizontal="24dp"
android:layout_marginTop="48dp"
android:text="@string/enter_abha_number_manualy"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/seperator1" />
@@ -105,13 +108,15 @@
android:inputType="number" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/go"
app:cornerRadius="16dp"
android:background="@drawable/button_new"
android:textColor="@color/red"
app:layout_constraintBottom_toBottomOf="@id/et_abha_id"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
@@ -144,7 +149,7 @@
android:layout_centerVertical="true"
android:layout_marginLeft="16dp"
android:layout_toLeftOf="@id/tvText2"
android:background="@color/gray" />
android:background="@color/red" />
<View
android:layout_width="match_parent"
@@ -152,7 +157,7 @@
android:layout_centerVertical="true"
android:layout_marginRight="16dp"
android:layout_toRightOf="@id/tvText2"
android:background="@color/gray" />
android:background="@color/red" />
</RelativeLayout>
@@ -164,6 +169,7 @@
android:layout_marginHorizontal="24dp"
android:layout_marginTop="48dp"
android:text="Create ABHA ID card"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/seperator2" />
@@ -177,6 +183,7 @@
android:textColor="@color/black"
app:backgroundTint="@color/blue_app_light"
app:cornerRadius="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title3" />

View File

@@ -137,15 +137,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_careof">
<AutoCompleteTextView
android:id="@+id/et_is_married"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/is_patient_married_yes_no"
android:inputType="none"
android:labelFor="@id/til_is_married"
app:simpleItems="@array/yes_no" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
@@ -168,6 +159,15 @@
android:labelFor="@id/til_category"
app:simpleItems="@array/category" />
<AutoCompleteTextView
android:id="@+id/et_is_married"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/is_patient_married_yes_no"
android:inputType="none"
android:labelFor="@id/til_is_married"
app:simpleItems="@array/yes_no" />
</com.google.android.material.textfield.TextInputLayout>
<TextView

View File

@@ -16,6 +16,7 @@
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/scan_patient_aadhaar_card"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -24,11 +25,12 @@
android:layout_width="258dp"
android:layout_height="56dp"
android:layout_margin="24dp"
android:drawableLeft="@drawable/baseline_qr_code_scanner_24"
android:drawableLeft="@drawable/baseline_qr_code_scanner_24_x"
android:text="@string/scan_now"
android:textColor="@color/black"
app:backgroundTint="@color/blue_app_light"
app:cornerRadius="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
@@ -59,7 +61,7 @@
android:layout_centerVertical="true"
android:layout_marginLeft="16dp"
android:layout_toLeftOf="@id/tvText1"
android:background="@color/gray" />
android:background="@color/red" />
<View
android:layout_width="match_parent"
@@ -67,7 +69,7 @@
android:layout_centerVertical="true"
android:layout_marginRight="16dp"
android:layout_toRightOf="@id/tvText1"
android:background="@color/gray" />
android:background="@color/red" />
</RelativeLayout>
@@ -80,6 +82,7 @@
android:layout_marginHorizontal="24dp"
android:layout_marginTop="48dp"
android:text="@string/enter_aadhaar_number_manualy"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/seperator1" />
@@ -105,15 +108,17 @@
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/go"
android:textColor="@color/red"
app:cornerRadius="16dp"
app:layout_constraintBottom_toBottomOf="@id/et_abha_id"
app:layout_constraintEnd_toEndOf="parent"
android:background="@drawable/button_new"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@id/et_abha_id"
app:layout_constraintTop_toTopOf="@id/et_abha_id" />

View File

@@ -45,14 +45,15 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle1" />
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_set_reference"
android:layout_width="192dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="false"
android:text="@string/set_reference"
android:textColor="@color/white"
android:background="@drawable/button_new"
android:textColor="@color/red"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />

View File

@@ -222,7 +222,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_submit"
android:layout_width="216dp"
android:layout_height="wrap_content"
@@ -230,7 +230,8 @@
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/submit"
android:textColor="@color/white"
android:background="@drawable/button_new"
android:textColor="@color/red"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" />

View File

@@ -108,8 +108,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="48dp"
android:text="@string/enter_kit_serial_number_manually"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints" />
@@ -129,34 +129,42 @@
android:id="@+id/name_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:boxCornerRadiusBottomEnd="10dp"
app:boxCornerRadiusBottomStart="10dp"
app:boxCornerRadiusTopEnd="10dp"
app:boxCornerRadiusTopStart="10dp"
android:maxLength="17"
android:inputType="text"
android:hint="@string/serial_number" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/go"
app:cornerRadius="16dp"
android:background="@drawable/button_new"
android:textColor="@color/red"
app:layout_constraintBottom_toBottomOf="@id/et_abha_id"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@id/et_abha_id"
app:layout_constraintTop_toTopOf="@id/et_abha_id" />
<Button
<androidx.appcompat.widget.AppCompatButton
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:background="@drawable/button_new"
android:clickable="false"
android:text="@string/Start_Sample"
android:textColor="@color/white"
android:textColor="@color/red"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -164,7 +172,7 @@
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_placebuffer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -172,7 +180,8 @@
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/place_buffer"
android:textColor="@color/white"
android:background="@drawable/button_new"
android:textColor="@color/red"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height"
android:background="@color/blue_app"
android:background="@color/new_blue"
android:gravity="bottom"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
@@ -18,25 +18,29 @@
android:layout_height="wrap_content"
app:cardCornerRadius="16dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/nav_header_desc"
android:paddingTop="@dimen/nav_header_vertical_spacing"
app:srcCompat="@mipmap/hpos_icon" />
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/nav_header_desc"
android:padding="6dp"
app:srcCompat="@mipmap/hpos_icon" />
</androidx.cardview.widget.CardView>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8sp"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:text="@string/nav_header_title"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="@color/blue_text_color" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nav_header_subtitle" />
android:layout_marginLeft="8sp"
android:text="@string/nav_header_subtitle"
android:textColor="@color/blue_text_color" />
</LinearLayout>

View File

@@ -24,6 +24,7 @@
android:id="@+id/userImage"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginLeft="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_launcher_foreground" />
@@ -82,15 +83,21 @@
android:textColor="@color/white"
app:layout_constraintStart_toEndOf="@+id/btn_blood"
app:layout_constraintBottom_toBottomOf="@+id/btn_blood" />
<Button
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_blood"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="60dp"
android:background="@drawable/bloodgroup_button"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:text="@string/blood_group"
android:textColor="@color/white"
app:layout_constraintEnd_toStartOf="@+id/btn_startIncubation"
app:layout_constraintTop_toBottomOf="@id/teststatus" />
app:layout_constraintTop_toBottomOf="@id/userImage" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -17,4 +17,4 @@
android:icon="@drawable/baseline_settings_24"
android:title="@string/menu_settings" />
</group>
</menu>
</menu>

View File

@@ -271,4 +271,6 @@
<string name="deviceinfo">डिवाइस जानकारी</string>
<string name="downloadcsv">सीएसवी डाउनलोड करें</string>
<string name="Firefox">Firefox</string>
<string name="Files">Files</string>
</resources>

View File

@@ -271,5 +271,7 @@
<string name="ok">ಸರಿ</string>
<string name="downloadcsv">CSV ಡೌನ್ಲೋಡ್ ಮಾಡಿ</string>
<!-- Add translations for other strings -->
<string name="Firefox">Firefox</string>
<string name="Files">Files</string>
</resources>

View File

@@ -8,20 +8,27 @@
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="gray">#808080</color>
<color name="blue_text_color">#0E2347</color>
<color name="brightGreen">#00FF00</color>
<color name="green_2">#295F2D</color>
<color name="red">#FF0000</color>
<color name="red_light">#88FF0000</color>
<color name="blue_app">#4daaff</color>
<color name="card_blue_app">#43BFE8F7</color>
<color name="blue_app_dark">#005db3</color>
<color name="blue_app_light">#e5f3ff</color>
<color name="new_blue">#A2C3FA</color>
<color name="primary">#4daaff</color>
<color name="primary">#A2C3FA</color>
<color name="primary_dark">#005db3</color>
<color name="primary_light">#e5f3ff</color>
</resources>

View File

@@ -174,7 +174,7 @@
<string name="create_abha_id_card">Create ABHA ID Card</string>
<string name="official_abha_app">Official ABHA App</string>
<string name="scan_patient_aadhaar_card">Scan Patient Aadhaar Card</string>
<string name="enter_aadhaar_number_manualy">Enter Aadhaar number manualy</string>
<string name="enter_aadhaar_number_manualy">Enter Aadhaar Number Manually</string>
<string name="aadhaar_number">Aadhaar Number</string>
<string name="aadhaar_in_tv"><b>Aadhaar Number</b></string>
<string name="please_use_official_abha_app_to_create_abha_id_and_come_back">Please use “Official ABHA App" to create ABHA ID, and come back.</string>

View File

@@ -1,11 +1,7 @@
package com.example.hpostesting
import android.content.Context
import android.content.SharedPreferences
import com.example.hpostesting.presentation.hemocube.HemoCubeFragment
import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import junit.framework.TestCase
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertNull
import org.junit.Before
@@ -17,18 +13,9 @@ import org.mockito.MockitoAnnotations
class HemoCubeFragmentTest {
@Mock
lateinit var mockContext: Context
@Mock
private lateinit var mockSharedPreferences: SharedPreferences
@Mock
private lateinit var mockActivity: HemocubeActivity // Replace with your actual Activity class
@Mock
private lateinit var mockBinding: FragmentHemoCubeReferenceBinding // Replace with your actual Binding class
private lateinit var hemoCubeFragment: HemoCubeFragment
@Before
@@ -51,7 +38,7 @@ class HemoCubeFragmentTest {
val deviceId = hemoCubeFragment.extractV2HardwareId("SNS HPP1-9000 SNE")
// Assert
TestCase.assertEquals("HPP1-9000", deviceId)
assertEquals("HPP1-9000", deviceId)
}
@Test
@@ -71,7 +58,7 @@ class HemoCubeFragmentTest {
)
// Assert
TestCase.assertEquals("HPP1-0001", deviceId)
assertEquals("HPP1-0001", deviceId)
}
@Test
@@ -84,8 +71,8 @@ class HemoCubeFragmentTest {
val result = hemoCubeFragment.allReadingsComplete(repeatReadingCount, readingsPerSample)
// Assert
TestCase.assertEquals(true, result)
TestCase.assertEquals(hemoCubeFragment.allReadingsComplete(0, 1), false)
assertEquals(true, result)
assertEquals(hemoCubeFragment.allReadingsComplete(0, 1), false)
}
@Test
@@ -316,6 +303,13 @@ class HemoCubeFragmentTest {
assertEquals("HPP-000-5001", result)
}
@Test
fun testDeviceRatioClassificationNormalWithStartRange() {
val ratio = 0.16
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Normal", result)
}
@Test
fun testDeviceRatioClassificationNormal() {
val ratio = 0.22
@@ -331,19 +325,33 @@ class HemoCubeFragmentTest {
}
@Test
fun testDeviceRatioClassificationSickleCellTrait() {
val ratio = 0.25
fun testDeviceRatioClassificationSickleCellTraitLowerBound() {
val ratio = 0.251
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Sickle Cell Trait", result)
}
@Test
fun testDeviceRatioClassificationSickleCellTraitUpperBound() {
val ratio = 0.309
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Sickle Cell Trait", result)
}
@Test
fun testDeviceRatioClassificationPositiveForSickleCell() {
val ratio = 0.37
val ratio = 0.359
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Positive for Sickle Cell. HPLC for Confirmation", result)
}
@Test
fun testDeviceRatioClassificationSickleCellDiseaseLowerBound() {
val ratio = 0.361
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Sickle Cell Disease", result)
}
@Test
fun testDeviceRatioClassificationSickleCellDisease() {
val ratio = 0.45
@@ -359,44 +367,166 @@ class HemoCubeFragmentTest {
}
@Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsNegativeBorderlineRepeatTest() {
// `when`(hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Normal", 70.0)).thenReturn("Negative Borderline, Repeat Test")
val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Normal", 70.0)
assertEquals("Negative Borderline, Repeat Test", result)
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineNormal() {
val result =
hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline", 2.5)
assertEquals("Borderline. Normal", result)
}
@Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineSickleCellTrait1() {
val result =
hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline", 2.2)
assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineSickleCellTrait2() {
val result = hemoCubeFragment.findResultWithAdditionalMethods(
0.5,
"Positive for Sickle Cell. HPLC for Confirmation",
1.35
)
assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineSickleCellDisease() {
val result = hemoCubeFragment.findResultWithAdditionalMethods(
0.5,
"Positive for Sickle Cell. HPLC for Confirmation",
1.33
)
assertEquals("Borderline. Sickle Cell Disease", result)
}
@Test
fun findResultWithAdditionalMethods_NormalDeviceRatio_ReturnsNormalBelowSlopeRatioThreshold() {
// `when`(hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Normal", 70.0)).thenReturn("Negative Borderline, Repeat Test")
val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Normal", 30.0)
assertEquals("Normal", result)
}
@Test
fun findResultWithAdditionalMethods_NBL_ReturnsNBL() {
// `when`(hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Abnormal", 70.0)).thenReturn("Invalid")
val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline, Repeat Test", 70.0)
val result = hemoCubeFragment.findResultWithAdditionalMethods(
0.5,
"Negative Borderline, Repeat Test",
70.0
)
assertEquals("Negative Borderline, Repeat Test", result)
}
@Test
fun findResultWithAdditionalMethods_SCT_ReturnsSCT() {
// `when`(hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Abnormal", 70.0)).thenReturn("Invalid")
val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Sickle Cell Trait", 70.0)
val result =
hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Sickle Cell Trait", 70.0)
assertEquals("Sickle Cell Trait", result)
}
@Test
fun findResultWithAdditionalMethods_PBL_ReturnsPBL() {
// `when`(hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Abnormal", 70.0)).thenReturn("Invalid")
val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Positive for Sickle Cell. HPLC for Confirmation", 70.0)
assertEquals("Positive for Sickle Cell. HPLC for Confirmation", result)
val result = hemoCubeFragment.findResultWithAdditionalMethods(
0.5,
"Positive for Sickle Cell. HPLC for Confirmation",
1.35
)
assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun findResultWithAdditionalMethods_SCD_ReturnsSCD() {
// `when`(hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Abnormal", 70.0)).thenReturn("Invalid")
val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Sickle Cell Disease", 70.0)
val result =
hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Sickle Cell Disease", 70.0)
assertEquals("Sickle Cell Disease", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_NegativeBorderlineToNormal() {
// Arrange
val deviceRatio = 0.1
val deviceRatioClass = "Negative Borderline"
val led2Average = 0.2
// Act
val result = hemoCubeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
assertEquals("Borderline. Normal", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_NegativeBorderlineToSCT() {
// Arrange
val deviceRatio = 0.1
val deviceRatioClass = "Negative Borderline"
val led2Average = 0.14
// Act
val result = hemoCubeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_PositiveSickleCell() {
// Arrange
val deviceRatio = 0.2
val deviceRatioClass = "Positive for Sickle Cell. HPLC for Confirmation"
val led2Average = 0.18
// Act
val result = hemoCubeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
assertEquals("Borderline. Sickle Cell Disease", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_PositiveSickleCellToSCT() {
// Arrange
val deviceRatio = 0.2
val deviceRatioClass = "Positive for Sickle Cell. HPLC for Confirmation"
val led2Average = 0.195
// Act
val result = hemoCubeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
assertEquals("Borderline. Sickle Cell Trait", result)
}
@Test
fun testReclassifyWithBorderlineMethod2_PositiveSickleCellToSCD() {
// Arrange
val deviceRatio = 0.2
val deviceRatioClass = "Positive for Sickle Cell. HPLC for Confirmation"
val led2Average = 0.189
// Act
val result = hemoCubeFragment.reclassifyWithBorderlineMethod2(
deviceRatio,
deviceRatioClass,
led2Average
)
// Assert
assertEquals("Borderline. Sickle Cell Disease", result)
}
}

View File

@@ -3,7 +3,7 @@ buildscript {
kotlin_version = '1.8.21'
}
dependencies {
classpath 'com.android.tools.build:gradle:8.1.1'
classpath 'com.android.tools.build:gradle:8.2.2'
classpath 'com.google.gms:google-services:4.4.0'
classpath 'com.google.firebase:firebase-appdistribution-gradle:4.0.1'
}

View File

@@ -1,6 +1,6 @@
#Mon Jun 12 17:07:47 IST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

BIN
keystore.jks Normal file

Binary file not shown.