Compare commits

..

59 Commits

Author SHA1 Message Date
chandrashekhar reddy
372489330a Added new screen ActivitiesFragment to check upload pending list and added version name in DashboardActivity, so it will be easy to know which version currently in use 2024-03-09 15:20:49 +05:30
chandrashekhar reddy
0c10e5a920 Merge remote-tracking branch 'origin/dev' into dev 2024-03-09 12:27:22 +05:30
chandrashekhar reddy
045bda26ff Rearranging the project structure, so it will east to understand and following proper clean code rules 2024-03-09 12:26:59 +05:30
Mariya
b31e5e6c06 removed getting null values from result upload 2024-03-07 13:30:38 +05:30
Mariya
53c36d3cf9 added different id and set as primary key for testing twice with same sample Id and uploading the result, offline ,issue fixed, and set ADMIN as user that can only download and export CSV file, for collecting user Data 2024-03-07 12:11:27 +05:30
chandrashekhar reddy
f922f585b5 Merge remote-tracking branch 'origin/dev' into dev 2024-03-05 14:46:12 +05:30
chandrashekhar reddy
1742363f1a added deviceUpdateGlobal field in HomeFragment 2024-03-05 14:45:47 +05:30
Mariya
ba9564d867 added new kit button and logout button for offline test 2024-03-05 14:44:06 +05:30
Mariya
1aaf2ba485 sanitize the results values if the result is NaN or infinity 2024-03-04 18:02:07 +05:30
Mariya
85756a7052 commented code for unregistereceiver 2024-03-04 16:47:55 +05:30
Mariya Varghese
0141c2791e Merge branch 'dev-check-apk-update' into 'dev'
app update and other api calls managing for molbio

See merge request sminnovations/hpos!39
2024-03-04 11:12:21 +00:00
Mariya Varghese
a52538e72d Merge branch 'dev' into 'dev-check-apk-update'
# Conflicts:
#   app/build.gradle
#   app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt
#   app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt
#   app/src/main/java/com/example/hpostesting/presentation/hemocube/HemocubeActivity.kt
#   build.gradle
#   gradle/wrapper/gradle-wrapper.properties
2024-03-04 11:11:13 +00:00
chandrashekhar reddy
78cc79eef8 changes in HomeFragment added deviceId global and added default values 2024-03-04 15:37:32 +05:30
Mariya
c9d0c440e3 added code for sanitize result upload values if if the result is NAN or infinity for molbio integration 2024-03-04 14:48:43 +05:30
chandrashekhar reddy
99da2fc094 error in HomeFragment and DashboardActivity solved registering broadcast receiver was giving issue solved by adding checks 2024-03-04 14:26:44 +05:30
Mariya
20f408230e api calls managing, and error resolving for molbio 2024-03-02 19:37:24 +05:30
Mariya
c8d5d41c81 api calls maintaining for molbio 2024-03-02 15:41:17 +05:30
Mariya
210c9fed5d added code for usb permission 2024-03-01 16:21:27 +05:30
chandrashekhar reddy
e947d083fb merge 2024-03-01 14:08:49 +05:30
Mariya
b68ec45642 reduced number of api calls in home screen 2024-03-01 13:37:16 +05:30
Mariya
1e5afa0a5c reduced number api calls for bigtec 2024-03-01 12:38:19 +05:30
Mariya
80ab69c772 added code for uploading logs only once 2024-02-29 14:18:09 +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
Mariya
f7dc879c75 added code related offline bulkupload 2024-02-28 15:17:36 +05:30
Mariya
e8b5d12db5 removed unwanted toast messages 2024-02-28 15:12:21 +05:30
Mariya
626dd380ab Apk update successfully added 2024-02-28 14:46:06 +05:30
chandrashekhar reddy
c8677bc2bb gpg setup 2024-02-28 12:20:34 +05:30
Mariya
70b0b93f57 Apk Update Code Added 2024-02-27 20:44:32 +05:30
Mariya
5cdc156f33 Apk Update Code Added 2024-02-27 16:49:25 +05:30
Mariya
71d298cd69 Apk Update Code Added 2024-02-27 14:59:03 +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
Mariya
bb6f4ee859 Apk Update Code Added 2024-02-27 12:43:14 +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
89 changed files with 1416 additions and 791 deletions

3
.idea/gradle.xml generated
View File

@@ -4,9 +4,8 @@
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" /> <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <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 /build
/release
/google-services* /google-services*
/idea /idea

View File

@@ -19,8 +19,8 @@ android {
applicationId "in.sminnovations.hpostesting.dev" applicationId "in.sminnovations.hpostesting.dev"
minSdk 21 minSdk 21
targetSdk 34 targetSdk 34
versionCode 114 versionCode 120
versionName "2.1.114" versionName "2.1.120"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -80,16 +80,16 @@ dependencies {
implementation 'com.google.firebase:firebase-auth-ktx' implementation 'com.google.firebase:firebase-auth-ktx'
implementation 'com.google.firebase:firebase-storage-ktx' implementation 'com.google.firebase:firebase-storage-ktx'
implementation 'com.firebaseui:firebase-ui-firestore:8.0.2' 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-location:21.1.0'
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1' implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
implementation 'com.google.android.things:androidthings:1.0' implementation 'com.google.android.things:androidthings:1.0'
implementation 'com.google.firebase:firebase-appdistribution: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-beta11") 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 '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 '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' annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2'
// Navigation Component // Navigation Component
implementation "androidx.navigation:navigation-fragment-ktx:2.7.6" implementation "androidx.navigation:navigation-fragment-ktx:2.7.7"
implementation "androidx.navigation:navigation-ui-ktx:2.7.6" implementation "androidx.navigation:navigation-ui-ktx:2.7.7"
//Dagger - Hilt //Dagger - Hilt
implementation "com.google.dagger:hilt-android:2.46" implementation "com.google.dagger:hilt-android:2.46"

View File

@@ -25,6 +25,7 @@
<application <application
android:name="com.example.hpostesting.HPOSTestingApplication" android:name="com.example.hpostesting.HPOSTestingApplication"
android:largeHeap="true"
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
@@ -116,18 +117,15 @@
android:name="com.example.hpostesting.presentation.testRight.UsbService" android:name="com.example.hpostesting.presentation.testRight.UsbService"
android:enabled="true" android:enabled="true"
android:exported="false" /> android:exported="false" />
<activity <activity
android:name="com.example.hpostesting.presentation.SplashActivity" android:name="com.example.hpostesting.presentation.SplashActivity"
android:exported="true" android:exported="true"
android:noHistory="true" android:noHistory="true"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" /> <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" />-->
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
@@ -164,7 +162,7 @@
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:stateNotNeeded="true" android:stateNotNeeded="true"
tools:replace="android:screenOrientation" /> tools:replace="android:screenOrientation" />
<!-- ${applicationId}-->
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider" android:authorities="${applicationId}.fileprovider"

View File

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

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data package com.example.hpostesting.data.constant
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.HemoCubeTestData

View File

@@ -5,6 +5,7 @@ import androidx.room.Dao
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import androidx.room.Update
import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
@Dao @Dao
@@ -29,4 +30,8 @@ interface HemoCubeDao {
@Query("UPDATE hemo_cube_test_table SET isCSVCreated = :newValue WHERE _id = :id") @Query("UPDATE hemo_cube_test_table SET isCSVCreated = :newValue WHERE _id = :id")
suspend fun updateCSVFieldById(id: String, newValue: Boolean) suspend fun updateCSVFieldById(id: String, newValue: Boolean)
@Query("SELECT * from hemo_cube_test_table WHERE localFlag = 0")
fun getPendingUser(): LiveData<List<HemoCubeTestData>>
} }

View File

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

View File

@@ -89,8 +89,9 @@ class LocalFileDataSourceImpl @Inject constructor() : LocalFileDataSource {
) )
csvWriter.writeNext(header) csvWriter.writeNext(header)
// Write data rows // Filter and write data rows where testStatus is true
for (data in dataList) { val filteredDataList = dataList.filter { it.testStatus == true }
for (data in filteredDataList) {
val row = arrayOf( val row = arrayOf(
data._id, data._id,
data.name, data.name,

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 = "", var natsToken: String = "",
@get:PropertyName("natsTokenExpiry") @set:PropertyName("natsTokenExpiry") @get:PropertyName("natsTokenExpiry") @set:PropertyName("natsTokenExpiry")
var natsTokenExpiry: String = "", 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

@@ -5,7 +5,8 @@ import androidx.room.PrimaryKey
@Entity(tableName = "hemo_cube_test_table") @Entity(tableName = "hemo_cube_test_table")
data class HemoCubeTestData( data class HemoCubeTestData(
@PrimaryKey @PrimaryKey(autoGenerate = true)
var sampleid: Int = 0,
var _id: String = "", var _id: String = "",
var name: String = "", var name: String = "",
var incubationTime: String = "", var incubationTime: String = "",
@@ -78,6 +79,7 @@ data class HemoCubeTestData(
var prdClassification: String = "", var prdClassification: String = "",
var deviceRatioClass: String = "", var deviceRatioClass: String = "",
var slopeRatioClass: String = "", var slopeRatioClass: String = "",
var borderlineMethod2Class: String = "",
var errorMessages: String = "", var errorMessages: String = "",
var batteryLevel: String = "", var batteryLevel: String = "",
var batteryCapacity: 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

@@ -1,7 +1,7 @@
package com.example.hpostesting.data.repository package com.example.hpostesting.data.repository
import android.net.Uri import android.net.Uri
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.api.MolbioAuthApi import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi import com.example.hpostesting.data.api.MolbioResultApi
import com.example.hpostesting.data.model.PendingUploads import com.example.hpostesting.data.model.PendingUploads
@@ -109,20 +109,7 @@ class DatabaseRepository @Inject constructor(
} }
override suspend fun addTestToDatabase(data: UserData?): Response<String> { override suspend fun addTestToDatabase(data: UserData?): Response<String> {
return try { TODO("Not yet implemented")
val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true)
}
}
db.collection("testData").add(data).await()
Response.Success(data._id)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
} }
override suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response<String> { override suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response<String> {
@@ -247,4 +234,22 @@ class DatabaseRepository @Inject constructor(
override fun <UserData> addTestToDatabase(testDetails: UserData): Any { override fun <UserData> addTestToDatabase(testDetails: UserData): Any {
TODO("Not yet implemented") TODO("Not yet implemented")
} }
override suspend fun addTestToDatabasefornew(data: HemoCubeTestData?): Response<String> {
return try {
val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true)
}
}
db.collection("testData").add(data).await()
Response.Success(data._id)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
}
} }

View File

@@ -1,6 +1,6 @@
package com.example.hpostesting.data.repository package com.example.hpostesting.data.repository
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse
@@ -25,6 +25,7 @@ import okhttp3.ResponseBody
interface Repository { interface Repository {
suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String> suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String>
suspend fun addTestToDatabasefornew(data: HemoCubeTestData?): Response<String>
suspend fun addTestToDatabase(data: UserData?): Response<String> suspend fun addTestToDatabase(data: UserData?): Response<String>

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.domain.di package com.example.hpostesting.di
import android.app.Application import android.app.Application
import android.content.Context import android.content.Context
@@ -7,7 +7,7 @@ import android.content.res.AssetManager
import androidx.room.Room import androidx.room.Room
import com.example.hpostesting.data.api.MolbioAuthApi import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi import com.example.hpostesting.data.api.MolbioResultApi
import com.example.hpostesting.data.api.PropertyProvider import com.example.hpostesting.util.PropertyProvider
import com.example.hpostesting.data.dao.HemoCubeBufferDao import com.example.hpostesting.data.dao.HemoCubeBufferDao
import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.dao.MyDatabase import com.example.hpostesting.data.dao.MyDatabase
@@ -22,6 +22,8 @@ import com.example.hpostesting.domain.LogFileManager
import com.example.hpostesting.domain.LogFileManagerImpl import com.example.hpostesting.domain.LogFileManagerImpl
import com.example.hpostesting.domain.SaveRawData import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.utils.UsbServiceListenerImpl
import com.example.hpostesting.util.PropertyProviderImpl import com.example.hpostesting.util.PropertyProviderImpl
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
@@ -145,7 +147,7 @@ object AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideRetrofit( fun provideRetrofit(
propertyProvider: PropertyProvider,@Named("Auth") client: OkHttpClient propertyProvider: PropertyProvider, @Named("Auth") client: OkHttpClient
): Retrofit { ): Retrofit {
return Retrofit.Builder().baseUrl(propertyProvider.getProperty("BASE_URL")).client(client) return Retrofit.Builder().baseUrl(propertyProvider.getProperty("BASE_URL")).client(client)
.addConverterFactory(GsonConverterFactory.create()).build() .addConverterFactory(GsonConverterFactory.create()).build()
@@ -179,4 +181,10 @@ object AppModule {
fun provideLocalFileDataSource(): LocalFileDataSource { fun provideLocalFileDataSource(): LocalFileDataSource {
return LocalFileDataSourceImpl() return LocalFileDataSourceImpl()
} }
@Provides
@Singleton
fun provideUsbServiceListener(context: Context): UsbServiceListener {
return UsbServiceListenerImpl(context)
}
} }

View File

@@ -10,7 +10,7 @@ import android.view.View
import android.widget.EditText import android.widget.EditText
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity

View File

@@ -17,7 +17,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData

View File

@@ -1,7 +0,0 @@
package com.example.hpostesting.presentation
import androidx.lifecycle.ViewModel
class MainViewModel : ViewModel() {
}

View File

@@ -13,7 +13,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.util.MyUtils import com.example.hpostesting.util.MyUtils

View File

@@ -11,7 +11,7 @@ import androidx.navigation.findNavController
import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData

View File

@@ -14,7 +14,7 @@ import androidx.fragment.app.FragmentActivity
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.firebase.ui.firestore.FirestoreRecyclerAdapter import com.firebase.ui.firestore.FirestoreRecyclerAdapter

View File

@@ -13,9 +13,8 @@ import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.Spinner import android.widget.Spinner
import android.widget.Toast import android.widget.Toast
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.hemocube.HemocubeActivity import com.example.hpostesting.presentation.hemocube.HemocubeActivity
@@ -162,8 +161,8 @@ class AssuranceControlsFragment : Fragment() {
} }
DataHolder.hemoCubeTestData!!._id = currentUnixTime.toString() + "SMI" DataHolder.hemoCubeTestData!!._id = currentUnixTime.toString() + "SMI"
DataHolder.hemoCubeTestData!!.solution = binding.spinnerSolutions.selectedItem.toString() DataHolder.hemoCubeTestData!!.solution = binding.spinnerSolutions.selectedItem.toString()
DataHolder.hemoCubeTestData!!.name = binding.spinnerConcentration.selectedItem.toString() DataHolder.hemoCubeTestData!!.concentration = binding.spinnerConcentration.selectedItem.toString()
"${DataHolder.hemoCubeTestData!!.solution} ${DataHolder.hemoCubeTestData!!.concentration} ${DataHolder.hemoCubeTestData!!.volume}" DataHolder.hemoCubeTestData!!.name = "${DataHolder.hemoCubeTestData!!.solution} ${DataHolder.hemoCubeTestData!!.concentration} ${DataHolder.hemoCubeTestData!!.volume}"
DataHolder.selectedTest = UserData() DataHolder.selectedTest = UserData()
DataHolder.selectedTest?._id = DataHolder.hemoCubeTestData!!._id DataHolder.selectedTest?._id = DataHolder.hemoCubeTestData!!._id

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService

View File

@@ -14,7 +14,7 @@ import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentAutoDacBinding import `in`.sminnovations.hpostesting.databinding.FragmentAutoDacBinding
@@ -163,10 +163,10 @@ class AutoDacFragment : Fragment() {
val slData = stringData.split(" ") val slData = stringData.split(" ")
if (slData.size > 1) { if (slData.size > 1) {
val hardwareId = slData[1].trim() val hardwareId = slData[1].trim()
with(sharedPreferences.edit()) { // with(sharedPreferences.edit()) {
putString(Constants.DEVICE_ID, hardwareId) // putString(Constants.DEVICE_ID, hardwareId)
apply() // apply()
} // }
} }
activity?.runOnUiThread { activity?.runOnUiThread {
binding.btnSubmit.visibility = View.VISIBLE binding.btnSubmit.visibility = View.VISIBLE

View File

@@ -1,4 +0,0 @@
package com.example.hpostesting.presentation.blank
class BlankActivity {
}

View File

@@ -1,4 +0,0 @@
package com.example.hpostesting.presentation.blank
class BlankFragment {
}

View File

@@ -1,4 +0,0 @@
package com.example.hpostesting.presentation.blank
class BlankViewModel {
}

View File

@@ -15,7 +15,7 @@ import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.patient.BufferCheckData import com.example.hpostesting.data.model.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService

View File

@@ -17,7 +17,7 @@ import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.calibration.CalibrationData import com.example.hpostesting.data.model.calibration.CalibrationData
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase

View File

@@ -0,0 +1,63 @@
package com.example.hpostesting.presentation.dashboard
import android.content.Context
import android.content.SharedPreferences
import android.os.BatteryManager
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.presentation.adapter.OfflineUserListAdapter
import com.example.hpostesting.presentation.adapter.UserListAdapter
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentActivitiesBinding
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
class ActivitiesFragment : Fragment() {
private lateinit var binding: FragmentActivitiesBinding
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var adapter: OfflineUserListAdapter
private lateinit var sharedPreference: SharedPreferences
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View {
binding = FragmentActivitiesBinding.inflate(inflater, container, false)
sharedPreference = requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
DataHolder.selectedTest = null
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
hemoCubeViewModel.allPendingUserToUpload.observe(viewLifecycleOwner) { userData ->
if (userData.isNotEmpty()) {
binding.rvOrderOffline.visibility = View.VISIBLE
binding.noDataText.visibility = View.GONE
val bm =
requireContext().getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
adapter = OfflineUserListAdapter(binding.root, batLevel)
adapter.differ.submitList(userData)
binding.rvOrderOffline.adapter = adapter
}else{
binding.rvOrderOffline.visibility = View.GONE
binding.noDataText.visibility = View.VISIBLE
Log.d("Activities","Nothing to show")
}
}
}
}

View File

@@ -1,10 +1,10 @@
package com.example.hpostesting.presentation.dashboard package com.example.hpostesting.presentation.dashboard
import android.app.DownloadManager import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
@@ -20,10 +20,11 @@ import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.NatsManager import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import com.example.hpostesting.presentation.utils.NatsManager
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.jig.JigActivity import com.example.hpostesting.presentation.jig.JigActivity
import com.google.android.material.navigation.NavigationView import com.google.android.material.navigation.NavigationView
@@ -31,9 +32,9 @@ import com.google.firebase.appdistribution.FirebaseAppDistribution
import com.google.firebase.appdistribution.FirebaseAppDistributionException import com.google.firebase.appdistribution.FirebaseAppDistributionException
import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.firebase.crashlytics.FirebaseCrashlytics
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.BuildConfig
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
import okhttp3.ResponseBody
import java.io.File import java.io.File
interface NatsMessageCallback { interface NatsMessageCallback {
@@ -49,6 +50,7 @@ open interface IDataCollector: NatsMessageCallback {
class DashboardActivity : AppCompatActivity(), IDataCollector { class DashboardActivity : AppCompatActivity(), IDataCollector {
val TAG = "DashboardActivity" val TAG = "DashboardActivity"
private var isRegistered = false
private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityDashboardBinding private lateinit var binding: ActivityDashboardBinding
lateinit var sharedPreferences: SharedPreferences lateinit var sharedPreferences: SharedPreferences
@@ -57,7 +59,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
private var downloadId: Long = 0 private var downloadId: Long = 0
// TODO: Remove hemocube viewmodel // TODO: Remove hemocube viewmodel
private val hemocubeViewModel: HemoCubeViewModel by viewModels() private val hemocubeViewModel: HemoCubeViewModel by viewModels()
private lateinit var sharedPreference: SharedPreferences
override fun attachBaseContext(newBase: Context?) { override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!) val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode) LanguageManager.setLocale(newBase, languageCode)
@@ -66,13 +68,14 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
override fun onMessageReceived(topic: String, message: String) { override fun onMessageReceived(topic: String, message: String) {
// Handle incoming messages from NATS // Handle incoming messages from NATS
Log.d(TAG, "Received message on topic $topic: $message") Log.d(TAG, "Received message on topic $topic: $message")
} }
@SuppressLint("SetWorldReadable")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityDashboardBinding.inflate(layoutInflater) binding = ActivityDashboardBinding.inflate(layoutInflater)
sharedPreferences = this.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) sharedPreferences = this.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
setContentView(binding.root) setContentView(binding.root)
@@ -81,6 +84,9 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
nats.connect() nats.connect()
} }
val versionName = getAppVersion(this@DashboardActivity) + " [ " + getAppEnvironment(this@DashboardActivity) + " ]"
binding.appBarDashboard.versionName.text = versionName
val deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "") val deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "")
@@ -91,15 +97,22 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
when (result) { when (result) {
is Result.Success -> { is Result.Success -> {
// Handle success // Handle success
val apkUrl = result.data val apk = result.data
// val apkUrl = "https://dl.dropboxusercontent.com/s/fi/1c3nn7t0co431hicl3hrt/app-debug.apk?rlkey=e4uf13ty1dpcked614vy1aaqp&dl=0" val file = File(getExternalFilesDir("Updates"), "update.apk")
initiateUpdate(apkUrl.toString()) file.setReadable(true, false) // Ensure the file is readable
Log.d("ApI", "APK URL: $apkUrl") apk.byteStream().use { input ->
// Toast.makeText( file.outputStream().use { output ->
// this, input.copyTo(output)
// "APK UPLOAD ${result.data}", }
// Toast.LENGTH_SHORT }
// ).show() Log.d("Responsebodyformat", "Responsebodyformat: ")
installApk(file)
Log.e("ApI", "APK URL: $apk")
Toast.makeText(
this,
"${result.data}",
Toast.LENGTH_SHORT
).show()
} }
is Result.Error -> { is Result.Error -> {
@@ -117,13 +130,14 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
} }
} }
val drawerLayout: DrawerLayout = binding.drawerLayout val drawerLayout: DrawerLayout = binding.drawerLayout
val navView: NavigationView = binding.navView val navView: NavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_content_dashboard) val navController = findNavController(R.id.nav_host_fragment_content_dashboard)
appBarConfiguration = AppBarConfiguration( appBarConfiguration = AppBarConfiguration(
setOf( setOf(
R.id.nav_home, R.id.nav_profile, R.id.nav_settings R.id.nav_home, R.id.nav_profile, R.id.nav_activity,R.id.nav_settings
), drawerLayout ), drawerLayout
) )
setupActionBarWithNavController(navController, appBarConfiguration) setupActionBarWithNavController(navController, appBarConfiguration)
@@ -135,6 +149,8 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
} }
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present. // Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.dashboard, menu) menuInflater.inflate(R.menu.dashboard, menu)
@@ -146,52 +162,15 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
} }
private fun initiateUpdate(responseBody: String) {
val apkUrl = responseBody
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(this, "Updates", "update.apk")
val downloadManager = 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)
// registerReceiver(downloadReceiver, filter)
}
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(getExternalFilesDir("Updates"), "update.apk")
file.setReadable(true, false) // Ensure the file is readable
private fun installApk(file: File) {
val pInfo = baseContext.packageManager.getPackageInfo(baseContext.packageName, 0) val pInfo = baseContext.packageManager.getPackageInfo(baseContext.packageName, 0)
val uri: Uri = FileProvider.getUriForFile( val uri: Uri = FileProvider.getUriForFile(
this, this,
"${pInfo}.fileprovider", "${BuildConfig.APPLICATION_ID}.fileprovider",
file file
) )
// Create an intent to install the APK
val installIntent = Intent(Intent.ACTION_INSTALL_PACKAGE) val installIntent = Intent(Intent.ACTION_INSTALL_PACKAGE)
installIntent.data = uri installIntent.data = uri
installIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or installIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
@@ -207,8 +186,14 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
} }
override fun onDestroy() { override fun onDestroy() {
if(isRegistered) {
try {
// unregisterReceiver(downloadReceiver)
} catch (e: Exception) {
Log.d("HomeFragment", e.toString())
}
}
super.onDestroy() super.onDestroy()
// unregisterReceiver(downloadReceiver)
} }
override fun onResume() { override fun onResume() {
@@ -258,8 +243,32 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
} }
override fun setResponse(response: String) { override fun setResponse(response: String) {
responses = responses+response+"\n" responses = responses+response+"\n"
println(responses) println(responses)
// if (response.contains("checkUpdate")) {
// hemocubeViewModel.deviceUpdate(createDeviceUpdateRequestData())
// }
}
private fun createDeviceUpdateRequestData(): DeviceUpdateRequest {
return DeviceUpdateRequest(
serial_no = sharedPreference.getString(Constants.DEVICE_ID, "")
)
}
private fun getAppVersion(context: Context): String {
return try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
pInfo.versionName
} catch (e: PackageManager.NameNotFoundException) {
"N/A"
}
}
private fun getAppEnvironment(context: Context): String {
return try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
pInfo.packageName.substringAfterLast('.')
} catch (e: PackageManager.NameNotFoundException) {
"N/A"
}
} }
} }

View File

@@ -21,12 +21,12 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.api.DeviceCommunicationHandler
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.DeviceCommunicationHandler
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber import com.hoho.android.usbserial.driver.UsbSerialProber

View File

@@ -12,7 +12,7 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase

View File

@@ -20,12 +20,12 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.api.DeviceCommunicationHandler
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.DeviceCommunicationHandler
import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber import com.hoho.android.usbserial.driver.UsbSerialProber
@@ -93,6 +93,7 @@ class DeviceProvisionActivity : AppCompatActivity(), DeviceCommunicationHandler
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
setupListener() setupListener()
connectUsb(false) connectUsb(false)
} }
private fun setupListener() { private fun setupListener() {

View File

@@ -12,19 +12,17 @@ import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands 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.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDeviceProvisionBinding import `in`.sminnovations.hpostesting.databinding.FragmentDeviceProvisionBinding
class DeviceProvisionFragment : Fragment() { class DeviceProvisionFragment : Fragment() {
private var resultData: String = "" private var resultData: String = ""
private lateinit var binding: FragmentDeviceProvisionBinding private lateinit var binding: FragmentDeviceProvisionBinding
@@ -118,16 +116,16 @@ class DeviceProvisionFragment : Fragment() {
password = response.data.data?.credentials?.password.toString(), password = response.data.data?.credentials?.password.toString(),
deviceProvisionResponse = response.data.data.toString(), deviceProvisionResponse = response.data.data.toString(),
natsToken = response.data.data?.device?.deviceUser?.natsToken.toString(), natsToken = response.data.data?.device?.deviceUser?.natsToken.toString(),
natsTokenExpiry = response.data.data?.device?.deviceUser?.natsTokenExpiry.toString() natsTokenExpiry = response.data.data?.device?.deviceUser?.natsTokenExpiry.toString(),
globalUpdateIgnore = false,
globalUpdateDone = false,
deviceUpdateAvailable = false
) )
) )
// viewModel.addDeviceId(DeviceData(deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString())) // viewModel.addDeviceId(DeviceData(deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString()))
Log.e("idpass", response.toString()) Log.e("idpass", response.toString())
Log.e("idpass", response.data.data?.credentials?.username.toString()) Log.e("idpass", response.data.data?.credentials?.username.toString())
Log.e("idpass", deviceProvisionResponse) Log.e("idpass", deviceProvisionResponse)
saveDataToLocalFile(response.data.data?.credentials?.username.toString(), response.data.data?.credentials?.password.toString())
} else { } else {
Toast.makeText( Toast.makeText(
activity, activity,
@@ -223,18 +221,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

@@ -3,7 +3,7 @@ package com.example.hpostesting.presentation.deviceprovision
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse

View File

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService

View File

@@ -13,15 +13,15 @@ import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.Result.Success import com.example.hpostesting.util.Result.Success
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.devicediagnostics.AdditionalDetails import com.example.hpostesting.data.model.devicediagnostics.AdditionalDetails
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDiagnosticsBinding import `in`.sminnovations.hpostesting.databinding.FragmentDiagnosticsBinding

View File

@@ -3,7 +3,7 @@ package com.example.hpostesting.presentation.diagnostics
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsRequest
import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsResponse
@@ -25,7 +25,7 @@ class DiagnosticsViewModel @Inject constructor(
val deviceData = MutableLiveData<DeviceData?>() val deviceData = MutableLiveData<DeviceData?>()
val fireBaseUpload = MutableLiveData<String>() val fireBaseUpload = MutableLiveData<String>()
val deviceDiagnosticsResponse = MutableLiveData<com.example.hpostesting.data.Result<DeviceDiagnosticsResponse>>() val deviceDiagnosticsResponse = MutableLiveData<Result<DeviceDiagnosticsResponse>>()
// private val batteryStatus: Intent? = // private val batteryStatus: Intent? =
// IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter -> // IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
// context.registerReceiver(null, ifilter) // context.registerReceiver(null, ifilter)

View File

@@ -10,7 +10,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.model.patient.toHemoCubeTestData import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import `in`.sminnovations.hpostesting.databinding.FragmentDigitalCardBinding import `in`.sminnovations.hpostesting.databinding.FragmentDigitalCardBinding
import java.text.SimpleDateFormat import java.text.SimpleDateFormat

View File

@@ -1,9 +1,11 @@
package com.example.hpostesting.presentation.hemocube package com.example.hpostesting.presentation.hemocube
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -12,15 +14,15 @@ import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.TestStatus import com.example.hpostesting.data.constant.TestStatus
import com.example.hpostesting.data.model.TestState import com.example.hpostesting.data.model.TestState
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.utils.MyDialogListener import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils import com.example.hpostesting.presentation.utils.UIUtils
@@ -90,8 +92,11 @@ class HemoCubeFragment : Fragment() {
observeViewModel() observeViewModel()
} }
@SuppressLint("SetTextI18n")
private fun initViews() { private fun initViews() {
binding.btnSubmit.setOnClickListener { binding.btnSubmit.setOnClickListener {
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
activity?.runOnUiThread { activity?.runOnUiThread {
binding.progressBar.visibility = View.VISIBLE binding.progressBar.visibility = View.VISIBLE
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
@@ -106,8 +111,6 @@ class HemoCubeFragment : Fragment() {
binding.nameEditText.visibility = View.GONE binding.nameEditText.visibility = View.GONE
binding.tvTitle.visibility = View.GONE binding.tvTitle.visibility = View.GONE
binding.btnGo.visibility = View.GONE binding.btnGo.visibility = View.GONE
// binding.btnSubmit.isEnabled = false
// binding.btnSubmit.isClickable = false
binding.btnPlacebuffer.visibility = View.GONE binding.btnPlacebuffer.visibility = View.GONE
binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}" binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}"
@@ -147,6 +150,7 @@ class HemoCubeFragment : Fragment() {
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result -> hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") { if (result == "Success") {
uploadedToCloud = true uploadedToCloud = true
var accessToken = sharedPreferences.getString(Constants.ACCESS_TOKEN, "").toString()
showToast(R.string.test_upload) showToast(R.string.test_upload)
if (Constants.MOLBIO_INTEGRATION) { if (Constants.MOLBIO_INTEGRATION) {
hemoCubeViewModel.resultUpload.observe(viewLifecycleOwner) { hemoCubeViewModel.resultUpload.observe(viewLifecycleOwner) {
@@ -159,6 +163,8 @@ class HemoCubeFragment : Fragment() {
) )
} }
handleReadingFinish() handleReadingFinish()
hemoCubeViewModel.uploadLogs()
hemoCubeViewModel.downloadClientCertificate()
} }
is Result.Error -> { is Result.Error -> {
@@ -167,10 +173,11 @@ class HemoCubeFragment : Fragment() {
it.exception.let { message -> it.exception.let { message ->
Toast.makeText( Toast.makeText(
activity, activity,
"An error occurred: $message", "$message",
Toast.LENGTH_LONG Toast.LENGTH_LONG
) )
.show() .show()
Log.d("resultuploadfail1", message.toString())
} }
handleReadingFinish() handleReadingFinish()
} }
@@ -585,8 +592,7 @@ class HemoCubeFragment : Fragment() {
led1Gain4 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!! led1Gain4 = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
led2Gain4 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!! led2Gain4 = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
led3Gain4 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! led3Gain4 = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
led4Gain4 = led4Gain4 = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
} }
finishReading() finishReading()
@@ -764,6 +770,7 @@ class HemoCubeFragment : Fragment() {
val led3Average = log10(led3BufferForDevice.div(led3SampleForDevice)) val led3Average = log10(led3BufferForDevice.div(led3SampleForDevice))
val led4Average = log10(led4BufferForDevice.div(led4SampleForDevice)) val led4Average = log10(led4BufferForDevice.div(led4SampleForDevice))
val deviceRatio = led2Average / led1Average val deviceRatio = led2Average / led1Average
val borderlineMetric = (led1Average - led2Average) / deviceRatio
if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0) if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0)
?.get(0)!! ?.get(0)!!
@@ -861,7 +868,7 @@ class HemoCubeFragment : Fragment() {
} }
} }
var absorbanceLowerLimit = 0.0 val absorbanceLowerLimit = 0.0
if (led1Average < absorbanceLowerLimit || led2Average < absorbanceLowerLimit || led3Average < absorbanceLowerLimit || led4Average < absorbanceLowerLimit) { if (led1Average < absorbanceLowerLimit || led2Average < absorbanceLowerLimit || led3Average < absorbanceLowerLimit || led4Average < absorbanceLowerLimit) {
validationError = true validationError = true
activity?.runOnUiThread { activity?.runOnUiThread {
@@ -908,8 +915,13 @@ class HemoCubeFragment : Fragment() {
.toString() + ", " + currentDeviceData?.coefficients?.get(1).toString() .toString() + ", " + currentDeviceData?.coefficients?.get(1).toString()
this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio) this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio)
this.deviceRatioClass = deviceRatioClassification(deviceRatio) this.deviceRatioClass = deviceRatioClassification(deviceRatio)
this.borderlineMethod2Class = reclassifyWithBorderlineMethod2(deviceRatio, deviceRatioBorderlineThresholds(deviceRatio), led2Average)
this.slopeRatioClass = slopeClass this.slopeRatioClass = slopeClass
this.classificationResult = deviceRatioClass this.classificationResult = findResultWithAdditionalMethods(
deviceRatio,
deviceRatioClass,
borderlineMetric
)
hemoCubeViewModel.messages.postValue( hemoCubeViewModel.messages.postValue(
"${this.classificationResult} \n Device Ratio: ${ "${this.classificationResult} \n Device Ratio: ${
"%.3f".format( "%.3f".format(
@@ -950,17 +962,20 @@ class HemoCubeFragment : Fragment() {
} }
} }
fun findResultWithAdditionalMethods( fun reclassifyWithBorderlineMethod2(deviceRatio: Double?, deviceRatioClass: String?, led2Average: Double?): String {
deviceRatio: Double?,
deviceRatioClass: String?,
slopeRatio: Double?,
): String {
try { try {
// hemoCubeViewModel.messages.postValue("post classification checks") if (deviceRatio != null && led2Average != null) {
if (deviceRatio != null) { if (deviceRatioClass == "Negative Borderline") {
if (slopeRatio != null) { return if (led2Average >= 0.15)
if (deviceRatioClass == "Normal" && slopeRatio > 45.0) "Borderline. Normal"
return "Negative Borderline, Repeat Test" 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) { } catch (e: Exception) {
@@ -970,20 +985,74 @@ class HemoCubeFragment : Fragment() {
return deviceRatioClass.toString() 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 { try {
if (ratio != null) { 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) // setSubtitleTextColor(R.color.green_2)
return "Normal" return "Normal"
} }
if (ratio in 0.22..0.24) if (roundedRatio in 0.237..0.242)
return "Negative Borderline" return "Negative Borderline"
if (ratio in 0.24..0.32) if (roundedRatio in 0.242..0.318)
return "Sickle Cell Trait" 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" 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" return "Sickle Cell Disease"
} else { } else {
return "Invalid" return "Invalid"

View File

@@ -12,10 +12,10 @@ import androidx.lifecycle.viewModelScope
import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager import androidx.work.WorkManager
import com.example.hpostesting.data.CsvWriter import com.example.hpostesting.util.CsvWriter
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.HemoCubeBufferDao import com.example.hpostesting.data.dao.HemoCubeBufferDao
import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.dao.HemoCubeDao
@@ -88,6 +88,8 @@ class HemoCubeViewModel @Inject constructor(
private val _networkStatusLiveData = NetworkStatusLiveData(context) private val _networkStatusLiveData = NetworkStatusLiveData(context)
val allUserData = hemoCubeDao.getAll() val allUserData = hemoCubeDao.getAll()
val allLocalData = hemoCubeDao.getAll()
val allPendingUserToUpload = hemoCubeDao.getPendingUser()
val allKitTestData = hemoCubeBufferDao.getAll() val allKitTestData = hemoCubeBufferDao.getAll()
val deviceData = MutableLiveData<DeviceData?>() val deviceData = MutableLiveData<DeviceData?>()
@@ -137,7 +139,14 @@ class HemoCubeViewModel @Inject constructor(
fun uploadResult(molbioV2ResultRequest: MolbioV2ResultRequest) = viewModelScope.launch { fun uploadResult(molbioV2ResultRequest: MolbioV2ResultRequest) = viewModelScope.launch {
resultUpload.postValue(Result.Loading()) resultUpload.postValue(Result.Loading())
Log.d("API CALL", "UPLOADED RESULT") repository.uploadResults(molbioV2ResultRequest).let {
resultUpload.postValue(it)
}
}
fun uploadResultfornew(molbioV2ResultRequest: MolbioV2ResultRequest) = viewModelScope.launch {
resultUpload.postValue(Result.Loading())
repository.uploadResults(molbioV2ResultRequest).let { repository.uploadResults(molbioV2ResultRequest).let {
resultUpload.postValue(it) resultUpload.postValue(it)
} }
@@ -187,6 +196,9 @@ class HemoCubeViewModel @Inject constructor(
} }
} }
} }
// fun getPendingUser() = viewModelScope.launch {
// allPendingUserToUpload.postValue(hemoCubeDao.getPendingUser(true))
// }
fun uploadHemoCubeResultToDatabaseForBufferCheck( fun uploadHemoCubeResultToDatabaseForBufferCheck(
isOnline: Boolean, isOnline: Boolean,
@@ -291,6 +303,7 @@ class HemoCubeViewModel @Inject constructor(
testDetails?.prdClassification = DataHolder.hemoCubeTestData?.prdClassification.toString() testDetails?.prdClassification = DataHolder.hemoCubeTestData?.prdClassification.toString()
testDetails?.deviceRatioClass = DataHolder.hemoCubeTestData?.deviceRatioClass.toString() testDetails?.deviceRatioClass = DataHolder.hemoCubeTestData?.deviceRatioClass.toString()
testDetails?.slopeRatioClass = DataHolder.hemoCubeTestData?.slopeRatioClass.toString() testDetails?.slopeRatioClass = DataHolder.hemoCubeTestData?.slopeRatioClass.toString()
testDetails?.borderlineMethod2Class = DataHolder.hemoCubeTestData?.borderlineMethod2Class.toString()
testDetails?.errorMessages = DataHolder.hemoCubeTestData?.errorMessages.toString() testDetails?.errorMessages = DataHolder.hemoCubeTestData?.errorMessages.toString()
testDetails?.batteryLevel = DataHolder.hemoCubeTestData?.batteryLevel.toString() testDetails?.batteryLevel = DataHolder.hemoCubeTestData?.batteryLevel.toString()
testDetails?.batteryCapacity = DataHolder.hemoCubeTestData?.batteryCapacity.toString() testDetails?.batteryCapacity = DataHolder.hemoCubeTestData?.batteryCapacity.toString()
@@ -321,20 +334,24 @@ class HemoCubeViewModel @Inject constructor(
fireBaseUpload.postValue("Success") fireBaseUpload.postValue("Success")
testDetails.localFlag = true testDetails.localFlag = true
if (Constants.MOLBIO_INTEGRATION) { if (Constants.MOLBIO_INTEGRATION) {
// Sanitize testDetails before using it in the API call
val sanitizedTestDetails = sanitizeDoubleValues(testDetails)
// Now, use sanitizedTestDetails for the API call
uploadResult( uploadResult(
MolbioV2ResultRequest( MolbioV2ResultRequest(
mutableListOf( mutableListOf(
MolbioV2Result( MolbioV2Result(
rawData = testDetails, rawData = sanitizedTestDetails,
analysisId = testDetails._id, analysisId = sanitizedTestDetails._id,
analysisDate = testDetails.testTime, analysisDate = sanitizedTestDetails.testTime,
analysisStatus = testDetails.classificationResult, analysisStatus = sanitizedTestDetails.classificationResult,
thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[testDetails.deviceId].toString(), thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[sanitizedTestDetails.deviceId]?.toString(),
interpretation = testDetails.classificationResult, interpretation = sanitizedTestDetails.classificationResult,
testId = testDetails._id, testId = sanitizedTestDetails._id,
testTime = testDetails.testTime, testTime = sanitizedTestDetails.testTime,
collectionTime = testDetails.testTime, collectionTime = sanitizedTestDetails.testTime,
expiryTime = testDetails.testTime, expiryTime = sanitizedTestDetails.testTime,
) )
) )
) )
@@ -376,6 +393,19 @@ class HemoCubeViewModel @Inject constructor(
} }
} }
fun sanitizeDoubleValues(hemoCubeTestData: HemoCubeTestData): HemoCubeTestData {
hemoCubeTestData::class.java.declaredFields.forEach { field ->
if (field.type == Double::class.javaObjectType || field.type == Double::class.javaPrimitiveType) {
field.isAccessible = true
val value = field.get(hemoCubeTestData) as Double?
if (value != null && (value.isInfinite() || value.isNaN())) {
field.set(hemoCubeTestData, 0.0) // Replace with a suitable default value
}
}
}
return hemoCubeTestData
}
private fun updateLocalFlag(userId: String) = viewModelScope.launch { private fun updateLocalFlag(userId: String) = viewModelScope.launch {
hemoCubeDao.updateFieldById(id = userId, true) hemoCubeDao.updateFieldById(id = userId, true)
} }
@@ -408,6 +438,8 @@ class HemoCubeViewModel @Inject constructor(
Log.e("Testdb", "Error uploading data to Firestore: $response") Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error") fireBaseUpload.postValue("Error")
} }
else -> {}
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}") Log.e("Testdb", "Exception during data upload: ${e.message}")

View File

@@ -11,16 +11,18 @@ import android.content.ServiceConnection
import android.hardware.usb.UsbDevice import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager import android.hardware.usb.UsbManager
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.IBinder import android.os.IBinder
import android.util.Log import android.util.Log
import android.view.Menu import android.view.Menu
import android.widget.Toast import android.widget.Toast
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService
@@ -43,6 +45,7 @@ open class HemocubeActivity : AppCompatActivity() {
private val TAG = "HemoCube" private val TAG = "HemoCube"
private val broadcastReceiver = object : BroadcastReceiver() { private val broadcastReceiver = object : BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.O)
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
synchronized(this) { synchronized(this) {
@@ -82,6 +85,7 @@ open class HemocubeActivity : AppCompatActivity() {
super.attachBaseContext(newBase) super.attachBaseContext(newBase)
} }
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityHemocubeBinding.inflate(layoutInflater) binding = ActivityHemocubeBinding.inflate(layoutInflater)
@@ -106,6 +110,7 @@ open class HemocubeActivity : AppCompatActivity() {
} }
} }
@RequiresApi(Build.VERSION_CODES.O)
open fun connectUsb(permissionGranted: Boolean) { open fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted") Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager val manager = getSystemService(Context.USB_SERVICE) as UsbManager
@@ -125,6 +130,7 @@ open class HemocubeActivity : AppCompatActivity() {
} }
} }
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("MutableImplicitPendingIntent") @SuppressLint("MutableImplicitPendingIntent")
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) { private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent val mPendingIntent: PendingIntent
@@ -142,15 +148,21 @@ open class HemocubeActivity : AppCompatActivity() {
} }
val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION) val filter = IntentFilter(Constants.HEMOCUBE_USB_PERMISSION)
registerReceiver(broadcastReceiver, filter) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
registerReceiver(broadcastReceiver, filter, RECEIVER_EXPORTED)
}else{
registerReceiver(broadcastReceiver, filter)
}
manager.requestPermission(device, mPendingIntent) manager.requestPermission(device, mPendingIntent)
} }
fun setupService() { fun setupService() {
val intent = Intent(this, UsbService::class.java) val intent = Intent(this, UsbService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE) bindService(intent, connection, Context.BIND_AUTO_CREATE)
} }
@RequiresApi(Build.VERSION_CODES.O)
open fun reconnectDevice() { open fun reconnectDevice() {
mService.disconnect() mService.disconnect()
unbindService(connection) unbindService(connection)

View File

@@ -21,7 +21,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService import com.example.hpostesting.presentation.testRight.UsbService

View File

@@ -19,7 +19,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber import com.hoho.android.usbserial.driver.UsbSerialProber
@@ -132,7 +132,7 @@ class TestRightActivity : AppCompatActivity() {
this, this,
0, 0,
Intent(Constants.ACTION_USB_PERMISSION), Intent(Constants.ACTION_USB_PERMISSION),
PendingIntent.FLAG_MUTABLE PendingIntent.FLAG_IMMUTABLE
) )
} else { } else {
mPendingIntent = PendingIntent.getBroadcast( mPendingIntent = PendingIntent.getBroadcast(

View File

@@ -10,11 +10,11 @@ import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.TestRightCommands import com.example.hpostesting.data.constant.TestRightCommands
import com.example.hpostesting.data.model.ErrorMessage import com.example.hpostesting.data.model.ErrorMessage
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.utils.MyDialogListener import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils import com.example.hpostesting.presentation.utils.UIUtils
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint

View File

@@ -10,13 +10,13 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.TestRightCommands import com.example.hpostesting.data.constant.TestRightCommands
import com.example.hpostesting.data.model.ErrorMessage import com.example.hpostesting.data.model.ErrorMessage
import com.example.hpostesting.data.model.test.TestType import com.example.hpostesting.data.model.test.TestType
import com.example.hpostesting.presentation.MainActivity import com.example.hpostesting.presentation.MainActivity
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.utils.MyDialogListener import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils import com.example.hpostesting.presentation.utils.UIUtils
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint

View File

@@ -11,7 +11,7 @@ import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.test.TestRightResultType import com.example.hpostesting.data.model.test.TestRightResultType
import com.example.hpostesting.data.model.test.TestType import com.example.hpostesting.data.model.test.TestType

View File

@@ -5,8 +5,8 @@ import android.net.Uri
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.UserDao import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.model.CalculationVariableForTest import com.example.hpostesting.data.model.CalculationVariableForTest

View File

@@ -9,7 +9,7 @@ import android.util.Log
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.TestRightCommands import com.example.hpostesting.data.constant.TestRightCommands
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialPort import com.hoho.android.usbserial.driver.UsbSerialPort
import com.hoho.android.usbserial.util.SerialInputOutputManager import com.hoho.android.usbserial.util.SerialInputOutputManager
@@ -33,32 +33,53 @@ class UsbService : Service() {
var bus: UsbServiceListener? = null var bus: UsbServiceListener? = null
fun connect(driver: UsbSerialDriver, connection: UsbDeviceConnection) { fun connect(driver: UsbSerialDriver, connection: UsbDeviceConnection) {
mPort = driver.ports[0] // Most devices have just one port (port 0) try {
mPort.open(connection) mPort = driver.ports[0]
mPort.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE) mPort.open(connection)
isUsbConnected = true
Log.d(TAG, "My Usb Connected ${mPort.driver}")
val usbIoManager = SerialInputOutputManager(mPort, if (mPort.device.vendorId == 6790 && mPort.device.productId == 29987)
object : SerialInputOutputManager.Listener { mPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
override fun onNewData(data: ByteArray?) { else
listener?.onUsbRead(data) mPort.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
}
override fun onRunError(e: Exception?) { isUsbConnected = true
Log.e(TAG, "onRunError() called inside eventDrivenWrite()") Log.d(TAG, "Usb Connected ${mPort.driver}")
listener?.onUsbError(e)
}
}) val usbIoManager = SerialInputOutputManager(mPort,
usbIoManager.start(); 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() { fun disconnect() {
if (isUsbConnected) { try {
mPort.close() if (isUsbConnected) {
isUsbConnected = false; mPort.close()
Log.d(TAG, "My Usb disconnected:: ${mPort.driver}") 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

@@ -20,7 +20,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.hemocube.HemoCubeFragment import com.example.hpostesting.presentation.hemocube.HemoCubeFragment

View File

@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@@ -13,15 +14,15 @@ import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.TestStatus import com.example.hpostesting.data.constant.TestStatus
import com.example.hpostesting.data.model.TestState import com.example.hpostesting.data.model.TestState
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.hemocube.HemocubeActivity import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import com.example.hpostesting.presentation.utils.MyDialogListener import com.example.hpostesting.presentation.utils.MyDialogListener
@@ -1155,6 +1156,8 @@ class TrueHemeFragment : Fragment() {
} }
private fun reconnect() { private fun reconnect() {
(activity as HemocubeActivity).reconnectDevice() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
(activity as HemocubeActivity).reconnectDevice()
}
} }
} }

View File

@@ -12,10 +12,10 @@ import androidx.lifecycle.viewModelScope
import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager import androidx.work.WorkManager
import com.example.hpostesting.data.CsvWriter import com.example.hpostesting.util.CsvWriter
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.HemoCubeBufferDao import com.example.hpostesting.data.dao.HemoCubeBufferDao
import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.dao.HemoCubeDao

View File

@@ -1,12 +1,6 @@
package com.example.hpostesting.data.api package com.example.hpostesting.presentation.utils
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.presentation.UsbServiceListener
interface PropertyProvider {
fun getProperty(key: String): String
}
interface DeviceCommunicationHandler { interface DeviceCommunicationHandler {
fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener) fun sendAndListenToDevice(command: HemoCubeCommands, listener: UsbServiceListener)

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.presentation package com.example.hpostesting.presentation.utils
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
@@ -125,13 +125,8 @@ class NatsManager(datacollector: DashboardActivity) {
if (nc?.status == Connection.Status.CONNECTED) { if (nc?.status == Connection.Status.CONNECTED) {
Log.d("NATSCONNECTION", "NATS is successfully connected.") Log.d("NATSCONNECTION", "NATS is successfully connected.")
val d = nc?.createDispatcher { msg: Message? ->
println("Nats dispatcher $msg")
}
nc?.subscribe("device.hpos.${deviceId}.ping") nc?.subscribe("device.hpos.${deviceId}.ping")
// Log.d(TAG, "Nats subscribed with ping-"+d)
nc?.publish( nc?.publish(
"server.hpos.${deviceId}.ping", "server.hpos.${deviceId}.ping",
"ALIVE".toByteArray(StandardCharsets.UTF_8) "ALIVE".toByteArray(StandardCharsets.UTF_8)
@@ -140,7 +135,10 @@ class NatsManager(datacollector: DashboardActivity) {
"server.hpos.${deviceId}.health", "server.hpos.${deviceId}.health",
"ALIVE".toByteArray(StandardCharsets.UTF_8) "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 -> d?.subscribe("device.hpos.${deviceId}.ping") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8) val response = String(msg.data, StandardCharsets.UTF_8)
datacollector.setResponse(response) datacollector.setResponse(response)
@@ -172,10 +170,11 @@ class NatsManager(datacollector: DashboardActivity) {
println("Message received (up to 100 times): $response") 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) val response = String(msg.data, StandardCharsets.UTF_8)
datacollector.setResponse(response) 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 { } else {
Log.d("NATSCONNECTION", "NATS is not connected. Current status: ${nc?.status}") Log.d("NATSCONNECTION", "NATS is not connected. Current status: ${nc?.status}")

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.presentation package com.example.hpostesting.presentation.utils
interface UsbServiceListener { interface UsbServiceListener {
fun onUsbRead(data: ByteArray?) fun onUsbRead(data: ByteArray?)

View File

@@ -0,0 +1,27 @@
package com.example.hpostesting.presentation.utils
import android.content.Context
import android.util.Log
import android.widget.Toast
import com.example.hpostesting.presentation.utils.UsbServiceListener
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

@@ -1,11 +0,0 @@
package com.example.hpostesting
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
fun main(){
val dateFormat = SimpleDateFormat("MM:HHddMMyyyy", Locale.getDefault())
val currentDate = Date()
print(dateFormat.format(currentDate))
}

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data package com.example.hpostesting.util
import android.content.Context import android.content.Context
import android.os.Environment import android.os.Environment

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data package com.example.hpostesting.util
import android.content.Context import android.content.Context

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data package com.example.hpostesting.util
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences

View File

@@ -0,0 +1,7 @@
package com.example.hpostesting.util
interface PropertyProvider {
fun getProperty(key: String): String
}

View File

@@ -1,7 +1,6 @@
package com.example.hpostesting.util package com.example.hpostesting.util
import android.content.res.AssetManager import android.content.res.AssetManager
import com.example.hpostesting.data.api.PropertyProvider
import java.io.InputStream import java.io.InputStream
import java.util.Properties import java.util.Properties

View File

@@ -1,4 +1,4 @@
package com.example.hpostesting.data package com.example.hpostesting.util
sealed class Result<out T : Any> { sealed class Result<out T : Any> {
data class Success<out T : Any>(val data: T) : Result<T>() data class Success<out T : Any>(val data: T) : Result<T>()

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM14,17L7,17v-2h7v2zM17,13L7,13v-2h10v2zM17,9L7,9L7,7h10v2z"/>
</vector>

View File

@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".presentation.dashboard.DashboardActivity"> >
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -16,7 +16,17 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.HPOS.PopupOverlay" /> app:popupTheme="@style/Theme.HPOS.PopupOverlay" >
<TextView
android:id="@+id/version_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="--"
android:textStyle="bold"
android:layout_gravity="end"
android:textSize="18sp"
android:layout_marginEnd="15dp"/>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/titleText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="Upload Pending List(Local data)"
android:layout_marginTop="5dp"
android:textSize="21sp"
android:textColor="@color/black"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_order_offline"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/titleText"
android:layout_alignParentStart="true"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/offline_user_list_view" />
<TextView
android:id="@+id/noDataText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="All up-to-date"
android:textSize="22sp"
android:textColor="@color/black"
/>
</RelativeLayout>

View File

@@ -217,6 +217,7 @@
android:text="no device message" android:text="no device message"
android:textColor="@color/black" android:textColor="@color/black"
android:textSize="11sp" android:textSize="11sp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/error_message" /> app:layout_constraintTop_toBottomOf="@id/error_message" />

View File

@@ -38,10 +38,20 @@
android:visibility="gone" android:visibility="gone"
android:padding="24dp"> android:padding="24dp">
<ImageView
android:id="@+id/btnLogout1"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="10dp"
android:src="@drawable/baseline_logout_24"
app:layout_constraintTop_toTopOf="@+id/internetNotAvailableCL"
app:layout_constraintEnd_toEndOf="parent"
/>
<TextView <TextView
android:id="@+id/tv_title_no_internet" android:id="@+id/tv_title_no_internet"
style="@style/title1" style="@style/title1"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
@@ -125,6 +135,27 @@
<!-- app:layout_constraintBottom_toBottomOf="@+id/rv_order_offline"--> <!-- app:layout_constraintBottom_toBottomOf="@+id/rv_order_offline"-->
<!-- app:layout_constraintStart_toStartOf="parent" />--> <!-- app:layout_constraintStart_toStartOf="parent" />-->
<TextView
android:id="@+id/label1"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/new_kit"
app:layout_constraintBottom_toTopOf="@+id/btnNewKitoffline"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnNewKitoffline"
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"
app:elevation="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout

View File

@@ -12,9 +12,13 @@
android:id="@+id/nav_profile" android:id="@+id/nav_profile"
android:icon="@drawable/control_panel" android:icon="@drawable/control_panel"
android:title="@string/profile" /> android:title="@string/profile" />
<item
android:id="@+id/nav_activity"
android:icon="@drawable/shows_activity_24"
android:title="@string/action_activity" />
<item <item
android:id="@+id/nav_settings" android:id="@+id/nav_settings"
android:icon="@drawable/baseline_settings_24" android:icon="@drawable/baseline_settings_24"
android:title="@string/menu_settings" /> android:title="@string/menu_settings" />
</group> </group>
</menu> </menu>

View File

@@ -32,6 +32,11 @@
android:name="com.example.hpostesting.presentation.dashboard.SlideshowFragment" android:name="com.example.hpostesting.presentation.dashboard.SlideshowFragment"
android:label="@string/action_settings" android:label="@string/action_settings"
tools:layout="@layout/fragment_slideshow" /> tools:layout="@layout/fragment_slideshow" />
<fragment
android:id="@+id/nav_activity"
android:name="com.example.hpostesting.presentation.dashboard.ActivitiesFragment"
android:label="@string/action_activity"
tools:layout="@layout/fragment_activities" />
<activity <activity
android:id="@+id/mainActivity" android:id="@+id/mainActivity"
android:name="com.example.hpostesting.presentation.MainActivity" android:name="com.example.hpostesting.presentation.MainActivity"

View File

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

View File

@@ -270,6 +270,7 @@
<string name="add_blood_group">ರಕ್ತ ಗುಂಡನ್ನು ಸೇರಿಸಿ</string> <string name="add_blood_group">ರಕ್ತ ಗುಂಡನ್ನು ಸೇರಿಸಿ</string>
<string name="ok">ಸರಿ</string> <string name="ok">ಸರಿ</string>
<string name="downloadcsv">CSV ಡೌನ್ಲೋಡ್ ಮಾಡಿ</string> <string name="downloadcsv">CSV ಡೌನ್ಲೋಡ್ ಮಾಡಿ</string>
<string name="action_activity">Activities</string>
<!-- Add translations for other strings --> <!-- Add translations for other strings -->
</resources> </resources>

View File

@@ -273,4 +273,5 @@
<string name="select_language">Select your preferred language</string> <string name="select_language">Select your preferred language</string>
<string name="app_language">App Language</string> <string name="app_language">App Language</string>
<string name="ok">OK</string> <string name="ok">OK</string>
<string name="action_activity">Activities</string>
</resources> </resources>

View File

@@ -3,18 +3,15 @@ package com.example.hpostesting
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer import com.example.hpostesting.util.NetworkStatusLiveData
import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.repository.Repository import com.example.hpostesting.data.repository.Repository
import com.example.hpostesting.presentation.autodac.AutoDacViewModel import com.example.hpostesting.presentation.autodac.AutoDacViewModel
import io.mockk.* import io.mockk.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.TestCoroutineDispatcher import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.setMain import kotlinx.coroutines.test.setMain

View File

@@ -1,7 +1,7 @@
package com.example.hpostesting package com.example.hpostesting
import android.content.Context import android.content.Context
import com.example.hpostesting.data.CsvWriter import com.example.hpostesting.util.CsvWriter
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test

View File

@@ -1,26 +1,5 @@
package com.example.hpostesting package com.example.hpostesting
import android.content.Context
import android.content.SharedPreferences
import androidx.fragment.app.testing.FragmentScenario
import androidx.fragment.app.testing.launchFragmentInContainer
import androidx.lifecycle.MutableLiveData
import androidx.test.core.app.ApplicationProvider
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.presentation.deviceinfo.DeviceActivity
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDeviceBinding
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.*
import org.mockito.MockitoAnnotations
class DeviceFragmentTest { class DeviceFragmentTest {
// //
// @Mock // @Mock

View File

@@ -2,7 +2,7 @@ package com.example.hpostesting
import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse
import com.example.hpostesting.data.repository.Repository import com.example.hpostesting.data.repository.Repository

View File

@@ -1,11 +1,7 @@
package com.example.hpostesting package com.example.hpostesting
import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import com.example.hpostesting.presentation.hemocube.HemoCubeFragment 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.assertEquals
import junit.framework.TestCase.assertNull import junit.framework.TestCase.assertNull
import org.junit.Before import org.junit.Before
@@ -17,18 +13,9 @@ import org.mockito.MockitoAnnotations
class HemoCubeFragmentTest { class HemoCubeFragmentTest {
@Mock
lateinit var mockContext: Context
@Mock @Mock
private lateinit var mockSharedPreferences: SharedPreferences 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 private lateinit var hemoCubeFragment: HemoCubeFragment
@Before @Before
@@ -51,7 +38,7 @@ class HemoCubeFragmentTest {
val deviceId = hemoCubeFragment.extractV2HardwareId("SNS HPP1-9000 SNE") val deviceId = hemoCubeFragment.extractV2HardwareId("SNS HPP1-9000 SNE")
// Assert // Assert
TestCase.assertEquals("HPP1-9000", deviceId) assertEquals("HPP1-9000", deviceId)
} }
@Test @Test
@@ -71,7 +58,7 @@ class HemoCubeFragmentTest {
) )
// Assert // Assert
TestCase.assertEquals("HPP1-0001", deviceId) assertEquals("HPP1-0001", deviceId)
} }
@Test @Test
@@ -84,8 +71,8 @@ class HemoCubeFragmentTest {
val result = hemoCubeFragment.allReadingsComplete(repeatReadingCount, readingsPerSample) val result = hemoCubeFragment.allReadingsComplete(repeatReadingCount, readingsPerSample)
// Assert // Assert
TestCase.assertEquals(true, result) assertEquals(true, result)
TestCase.assertEquals(hemoCubeFragment.allReadingsComplete(0, 1), false) assertEquals(hemoCubeFragment.allReadingsComplete(0, 1), false)
} }
@Test @Test
@@ -316,6 +303,13 @@ class HemoCubeFragmentTest {
assertEquals("HPP-000-5001", result) assertEquals("HPP-000-5001", result)
} }
@Test
fun testDeviceRatioClassificationNormalWithStartRange() {
val ratio = 0.16
val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Normal", result)
}
@Test @Test
fun testDeviceRatioClassificationNormal() { fun testDeviceRatioClassificationNormal() {
val ratio = 0.22 val ratio = 0.22
@@ -331,19 +325,33 @@ class HemoCubeFragmentTest {
} }
@Test @Test
fun testDeviceRatioClassificationSickleCellTrait() { fun testDeviceRatioClassificationSickleCellTraitLowerBound() {
val ratio = 0.25 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) val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Sickle Cell Trait", result) assertEquals("Sickle Cell Trait", result)
} }
@Test @Test
fun testDeviceRatioClassificationPositiveForSickleCell() { fun testDeviceRatioClassificationPositiveForSickleCell() {
val ratio = 0.37 val ratio = 0.359
val result = hemoCubeFragment.deviceRatioClassification(ratio) val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Positive for Sickle Cell. HPLC for Confirmation", result) 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 @Test
fun testDeviceRatioClassificationSickleCellDisease() { fun testDeviceRatioClassificationSickleCellDisease() {
val ratio = 0.45 val ratio = 0.45
@@ -359,44 +367,166 @@ class HemoCubeFragmentTest {
} }
@Test @Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsNegativeBorderlineRepeatTest() { fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineNormal() {
// `when`(hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Normal", 70.0)).thenReturn("Negative Borderline, Repeat Test") val result =
val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Normal", 70.0) hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline", 2.5)
assertEquals("Negative Borderline, Repeat Test", result) 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 @Test
fun findResultWithAdditionalMethods_NormalDeviceRatio_ReturnsNormalBelowSlopeRatioThreshold() { 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) val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Normal", 30.0)
assertEquals("Normal", result) assertEquals("Normal", result)
} }
@Test @Test
fun findResultWithAdditionalMethods_NBL_ReturnsNBL() { fun findResultWithAdditionalMethods_NBL_ReturnsNBL() {
// `when`(hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Abnormal", 70.0)).thenReturn("Invalid") val result = hemoCubeFragment.findResultWithAdditionalMethods(
val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline, Repeat Test", 70.0) 0.5,
"Negative Borderline, Repeat Test",
70.0
)
assertEquals("Negative Borderline, Repeat Test", result) assertEquals("Negative Borderline, Repeat Test", result)
} }
@Test @Test
fun findResultWithAdditionalMethods_SCT_ReturnsSCT() { fun findResultWithAdditionalMethods_SCT_ReturnsSCT() {
// `when`(hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Abnormal", 70.0)).thenReturn("Invalid") val result =
val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Sickle Cell Trait", 70.0) hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Sickle Cell Trait", 70.0)
assertEquals("Sickle Cell Trait", result) assertEquals("Sickle Cell Trait", result)
} }
@Test @Test
fun findResultWithAdditionalMethods_PBL_ReturnsPBL() { fun findResultWithAdditionalMethods_PBL_ReturnsPBL() {
// `when`(hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Abnormal", 70.0)).thenReturn("Invalid") val result = hemoCubeFragment.findResultWithAdditionalMethods(
val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Positive for Sickle Cell. HPLC for Confirmation", 70.0) 0.5,
assertEquals("Positive for Sickle Cell. HPLC for Confirmation", result) "Positive for Sickle Cell. HPLC for Confirmation",
1.35
)
assertEquals("Borderline. Sickle Cell Trait", result)
} }
@Test @Test
fun findResultWithAdditionalMethods_SCD_ReturnsSCD() { fun findResultWithAdditionalMethods_SCD_ReturnsSCD() {
// `when`(hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Abnormal", 70.0)).thenReturn("Invalid") val result =
val result = hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Sickle Cell Disease", 70.0) hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Sickle Cell Disease", 70.0)
assertEquals("Sickle Cell Disease", result) 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 @@ package com.example.hpostesting
import android.content.Context import android.content.Context
import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.example.hpostesting.data.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.model.login.LoginResponse import com.example.hpostesting.data.model.login.LoginResponse
import com.example.hpostesting.data.repository.Repository import com.example.hpostesting.data.repository.Repository
import com.example.hpostesting.domain.LogFileManager import com.example.hpostesting.domain.LogFileManager

View File

@@ -1,22 +1,5 @@
package com.example.hpostesting package com.example.hpostesting
import android.content.Context
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import java.math.RoundingMode
import java.text.DecimalFormat
class TestRightViewModelTest { class TestRightViewModelTest {
// private val viewModel = TestRightViewModel() // private val viewModel = TestRightViewModel()
// private val data = InputData() // private val data = InputData()

View File

@@ -3,9 +3,9 @@ buildscript {
kotlin_version = '1.8.21' kotlin_version = '1.8.21'
} }
dependencies { 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.gms:google-services:4.4.1'
classpath 'com.google.firebase:firebase-appdistribution-gradle:4.0.1' classpath 'com.google.firebase:firebase-appdistribution-gradle:4.1.0'
} }
repositories { repositories {
mavenCentral() mavenCentral()

View File

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

BIN
keystore.jks Normal file

Binary file not shown.