Compare commits

..

5 Commits

Author SHA1 Message Date
smileomi18@gmail.com
a25402fc26 production errors 2023-09-12 13:21:40 +05:30
smileomi18@gmail.com
388af0adf6 production errors 2023-09-12 13:04:57 +05:30
smileomi18@gmail.com
57a0c2103a production errors 2023-09-12 12:58:56 +05:30
smileomi18@gmail.com
057abbd87c Calculated ratio error code added 2023-09-07 13:51:07 +05:30
mohamedkaif356
c3775eeea1 Error code added 2023-09-07 13:31:02 +05:30
113 changed files with 1116 additions and 5947 deletions

2
.idea/gradle.xml generated
View File

@@ -5,6 +5,7 @@
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" />
<option name="modules">
@@ -13,7 +14,6 @@
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>

43
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="app/src/main/res/drawable/ic_baseline_auto_graph_24.xml" value="0.1555" />
<entry key="app/src/main/res/drawable/ic_baseline_cancel_24.xml" value="0.1965" />
<entry key="app/src/main/res/drawable/ic_baseline_check_circle_24.xml" value="0.243" />
<entry key="app/src/main/res/drawable/ic_baseline_dot_24.xml" value="0.1785" />
<entry key="app/src/main/res/drawable/ic_baseline_file_download_24.xml" value="0.243" />
<entry key="app/src/main/res/drawable/ic_baseline_home_24.xml" value="0.243" />
<entry key="app/src/main/res/drawable/ic_baseline_new_label_24.xml" value="0.243" />
<entry key="app/src/main/res/drawable/ic_baseline_usb_24.xml" value="0.157" />
<entry key="app/src/main/res/drawable/ic_baseline_usb_off_24.xml" value="0.157" />
<entry key="app/src/main/res/drawable/progressbar_drawable.xml" value="0.1885" />
<entry key="app/src/main/res/drawable/result_background_green.xml" value="0.243" />
<entry key="app/src/main/res/drawable/result_background_red.xml" value="0.1785" />
<entry key="app/src/main/res/drawable/result_background_tellow.xml" value="0.1785" />
<entry key="app/src/main/res/font/inter_bold.xml" value="0.33487179487179486" />
<entry key="app/src/main/res/layout/activity_main.xml" value="0.165" />
<entry key="app/src/main/res/layout/activity_splash.xml" value="0.24375" />
<entry key="app/src/main/res/layout/activity_test_right.xml" value="0.24375" />
<entry key="app/src/main/res/layout/fragment_graph.xml" value="0.19791666666666666" />
<entry key="app/src/main/res/layout/fragment_test_right_exp_reference.xml" value="0.25" />
<entry key="app/src/main/res/layout/fragment_test_right_exp_sample.xml" value="0.24583333333333332" />
<entry key="app/src/main/res/layout/fragment_test_right_exp_scanner.xml" value="0.24583333333333332" />
<entry key="app/src/main/res/layout/fragment_test_right_process.xml" value="0.24375" />
<entry key="app/src/main/res/layout/fragment_test_right_results.xml" value="0.30512820512820515" />
<entry key="app/src/main/res/layout/table_item.xml" value="0.22407407407407406" />
<entry key="app/src/main/res/menu/menu.xml" value="0.25" />
<entry key="app/src/main/res/menu/my_menu.xml" value="0.25" />
<entry key="app/src/main/res/mipmap-anydpi-v26/hpos_icon.xml" value="0.1505" />
<entry key="app/src/main/res/mipmap-anydpi-v26/hpos_icon_round.xml" value="0.1505" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

2
app/.gitignore vendored
View File

@@ -1,3 +1,3 @@
/build
/google-services*
/google-services.json
/idea

View File

@@ -14,13 +14,12 @@ android {
compileSdk 34
namespace 'in.sminnovations.hpostesting'
// prod - production, preprod - preproduction, quality - qc
defaultConfig {
applicationId "in.sminnovations.hpostesting"
minSdk 21
targetSdk 34
versionCode 56
versionName "2.1.56"
versionCode 2
versionName "2.0.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -49,25 +48,18 @@ android {
abortOnError false
checkReleaseBuilds false
}
packagingOptions {
exclude 'mockito-extensions/org.mockito.plugins.MockMaker'
}
}
dependencies {
implementation "com.google.dagger:hilt-android:2.46"
kapt "com.google.dagger:hilt-android-compiler:2.46"
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2'
implementation 'androidx.fragment:fragment-ktx:1.6.2'
//firebase
implementation platform('com.google.firebase:firebase-bom:32.1.0')
implementation("com.google.firebase:firebase-perf-ktx")
implementation("com.google.firebase:firebase-crashlytics-ktx")
implementation("com.google.firebase:firebase-analytics-ktx")
implementation 'com.google.firebase:firebase-firestore-ktx'
@@ -78,35 +70,21 @@ dependencies {
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
implementation 'com.google.android.things:androidthings:1.0'
implementation 'com.google.firebase:firebase-appdistribution:16.0.0-beta11'
implementation("com.google.firebase:firebase-appdistribution-api-ktx:16.0.0-beta11")
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'
// Testing
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
// Mockito dependencies
testImplementation 'org.mockito:mockito-core:3.12.4'
androidTestImplementation 'org.mockito:mockito-android:3.12.4'
androidTestImplementation 'org.mockito:mockito-inline:3.12.4'
testImplementation "androidx.arch.core:core-testing:2.2.0"
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.1'
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"
implementation 'com.opencsv:opencsv:5.5'
implementation 'com.opencsv:opencsv:4.6'
implementation 'com.github.mik3y:usb-serial-for-android:3.5.1'
implementation "androidx.fragment:fragment-ktx:1.6.2"
implementation "androidx.fragment:fragment-ktx:1.6.1"
// CSV read, write
implementation 'com.opencsv:opencsv:5.5'
implementation 'com.opencsv:opencsv:4.6'
// Barcode scanner
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
@@ -115,32 +93,25 @@ dependencies {
implementation 'com.google.android.gms:play-services-code-scanner:16.1.0'
//Room
implementation "androidx.room:room-ktx:2.6.1"
implementation "androidx.room:room-runtime:2.6.1"
kapt ("androidx.room:room-compiler:2.6.1")
implementation "androidx.room:room-ktx:2.6.0-beta01"
implementation "androidx.room:room-runtime:2.6.0-beta01"
kapt ("androidx.room:room-compiler:2.6.0-beta01")
//image
implementation 'com.github.bumptech.glide:glide:4.13.2'
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2'
// Navigation Component
implementation "androidx.navigation:navigation-fragment-ktx:2.7.6"
implementation "androidx.navigation:navigation-ui-ktx:2.7.6"
implementation "androidx.navigation:navigation-fragment-ktx:2.7.2"
implementation "androidx.navigation:navigation-ui-ktx:2.7.2"
//Dagger - Hilt
implementation "com.google.dagger:hilt-android:2.46"
kapt "com.google.dagger:hilt-android-compiler:2.46"
kapt "androidx.hilt:hilt-compiler:1.1.0"
kapt "androidx.hilt:hilt-compiler:1.0.0"
// Retrofit + GSON
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
implementation("com.squareup.okhttp3:okhttp:4.9.3")
implementation "androidx.preference:preference-ktx:1.2.1"
implementation 'io.nats:jnats:2.11.2'
implementation("androidx.work:work-runtime-ktx:2.9.0")
implementation("io.nats:jnats:2.11.2")
}

View File

@@ -5,9 +5,6 @@
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.BATTERY_STATS"
tools:ignore="ProtectedPermissions" />
<uses-feature android:name="android.hardware.camera" />
@@ -33,11 +30,10 @@
android:theme="@style/Theme.HPOSTesting"
tools:targetApi="31">
<activity
android:name="com.example.hpostesting.presentation.hemocube.DigitalCardActivity"
android:exported="false" />
<activity
android:name="com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity"
android:exported="false" />
android:name="com.example.hpostesting.presentation.BloodCollectingMethodActivity"
android:exported="true"
android:noHistory="true"
android:theme="@style/Theme.HPOS.NoActionBar" />
<activity
android:name="com.example.hpostesting.presentation.hemocube.HemocubeActivity"
android:exported="false"
@@ -45,13 +41,6 @@
android:parentActivityName="com.example.hpostesting.presentation.MainActivity"
android:theme="@style/Theme.HPOS.NoActionBar"
android:windowSoftInputMode="adjustPan" />
<activity
android:name="com.example.hpostesting.presentation.buffercheck.HemocubeBufferCheckActivity"
android:exported="false"
android:noHistory="true"
android:parentActivityName="com.example.hpostesting.presentation.MainActivity"
android:theme="@style/Theme.HPOS.NoActionBar"
android:windowSoftInputMode="adjustPan" />
<activity
android:name="com.example.hpostesting.presentation.KitScanActivity"
android:exported="false"
@@ -61,8 +50,7 @@
android:name="com.example.hpostesting.presentation.dashboard.DashboardActivity"
android:exported="false"
android:label="@string/title_activity_dashboard"
android:theme="@style/Theme.HPOS.NoActionBar"
tools:ignore="MissingClass" />
android:theme="@style/Theme.HPOS.NoActionBar" />
<service
android:name="com.example.hpostesting.presentation.testRight.UsbService"
@@ -111,7 +99,7 @@
</activity>
<activity
android:name="com.journeyapps.barcodescanner.CaptureActivity"
android:screenOrientation="portrait"
android:screenOrientation="fullSensor"
android:stateNotNeeded="true"
tools:replace="android:screenOrientation" />
</application>

View File

@@ -1 +0,0 @@
BASE_URL= https://datacollection.micropcr.com/api/

View File

@@ -15,8 +15,6 @@ import javax.inject.Singleton
@HiltAndroidApp
class HPOSTestingApplication: Application() {
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
override fun onCreate() {
super.onCreate()
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)

View File

@@ -0,0 +1,46 @@
package com.example.hpostesting.data
import android.util.Log
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.util.MyUtils
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class FileUploader {
private val TAG = "FileUploader"
val repository = DatabaseRepository()
suspend fun start() {
val listOfFiles = repository.getAllFromPendingQueue()
for (each in listOfFiles){
// Checking internet connectivity & mobile as same or not
if (MyUtils.isInternetConnected() && each.mobileId == DataHolder.mobileUniqueId) {
Log.d(TAG, "uploading file ${each.pendingId}")
GlobalScope.launch {
val response = repository.uploadFileToStorage(each.patientId, each.filePath)
when (response) {
is Response.Success -> {
Log.d(TAG, "File Uploaded ${each.pendingId}")
repository.removeFromPendingQueue(each.pendingId)
}
is Response.Error -> {
Log.d(TAG, response.exception.toString())
}
}
}.join()
} else {
return
}
}
return
}
}

View File

@@ -1,7 +0,0 @@
package com.example.hpostesting.data
sealed class Result<out T : Any> {
data class Success<out T : Any>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
class Loading<T : Any> : Result<T>()
}

View File

@@ -1,21 +0,0 @@
package com.example.hpostesting.data.api
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse
import com.example.hpostesting.data.model.login.LoginRequest
import com.example.hpostesting.data.model.login.LoginResponse
import retrofit2.http.Body
import retrofit2.http.POST
interface MolbioAuthApi {
@POST("deviceManagement/device/provision")
suspend fun deviceProvision(
@Body deviceProvisionRequest: DeviceProvisionRequest
): DeviceProvisionResponse
@POST("deviceService/device/login")
suspend fun login(
@Body loginRequest: LoginRequest
): LoginResponse
}

View File

@@ -1,39 +0,0 @@
package com.example.hpostesting.data.api
import com.example.hpostesting.data.model.log.UploadLogsResponse
import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultRequest
import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultResponse
import com.example.hpostesting.data.model.updates.CheckUpdateRequest
import com.example.hpostesting.data.model.updates.CheckUpdateResponse
import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import okhttp3.MultipartBody
import okhttp3.ResponseBody
import retrofit2.http.Body
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Part
interface MolbioResultApi {
@PUT("deviceService/results/HPOS")
suspend fun uploadResults(
@Body molbioV2ResultRequest: MolbioV2ResultRequest
): MolbioV2ResultResponse
@POST("deviceService/device/checkUpdate")
suspend fun checkUpdate(
@Body checkUpdateRequest: CheckUpdateRequest
): CheckUpdateResponse
@POST("deviceService/device/getUpdate")
suspend fun deviceUpdate(
@Body deviceUpdateRequest: DeviceUpdateRequest
): ResponseBody
@Multipart
@POST("deviceService/device/uploadLogs")
suspend fun uploadLogs(
@Part logFile: MultipartBody.Part
): UploadLogsResponse
}

View File

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

View File

@@ -4,22 +4,8 @@ object Constants {
const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION"
const val HOMOCUBE_USB_PERMISSION = "shanmukha.in.sickle_cell_homocube.USB_PERMISSION"
const val BASE_URL = "www.google.com"
const val ABHA_APP_PACKAGE = "in.ndhm.phr"
const val serialNumber = "NKH5555AH"
const val deviceTypeName = "HPOS"
const val uid = "NKH5555AH"
const val deviceProvisionEmail = "HPOS_provisioner@bigtec.co.in"
const val deviceProvisionPassword = "f2ab0e7f9d69"
const val deviceID = "HCV-000-3001"
const val devicePassword = "810516d8f4c7"
const val ACCESS_TOKEN = "accessToken"
const val NATS_TOKEN = "natsToken"
const val NATS_TOKEN_EXPIRE_DATE = "natsTokenExpireDate"
const val WRITE_TIMEOUT_MILLIS = 30000 // 30 sec
const val READ_TIMEOUT_MILLIS = 60000 // 1 min
const val DELAY_BETWEEN_COMMANDS: Long = 1000
@@ -43,8 +29,6 @@ object Constants {
const val DEVICE_VENDOR_ID = 1027
const val HOMO_CUBE_ID = 29987
const val VENDOR_ID = 6790
const val HEMO_CUBE_V2_PRODUCT_ID = 24577
const val HEMO_CUBE_V2_VENDOR_ID = 1027
const val ERROR_NORMAL = 400
const val ERROR_CRITICAL = 401
@@ -54,7 +38,6 @@ object Constants {
const val USER_ID = "usernameId"
val STATICID = listOf(
"ADMIN",
"VIZ-1000-0004",
"VIZ-1000-0005",
"VIZ-1000-0006",
@@ -64,30 +47,6 @@ object Constants {
"HC-V1-004",
"HC-V1-005",
"HC-V1-006",
"HC-V1-007",
"HC-V1-008",
"HC-V1-009",
"HC-V1-010",
"HC-V1-011",
"HC-V1-012",
"HC-V1-013",
"HC-V1-014",
"HC-V1-015",
"HC-V1-016",
"HC-V1-017",
"HC-V1-018",
"HC-V1-019",
"HC-V1-020",
"HCV-000-3001",
"HCV-000-3002",
"HCV-000-3003",
"HCV-000-3004",
"HCV-000-3005",
"HCV-000-3006",
"HCV-000-3007",
"HCV-000-3008",
"HCV-000-3009",
"HCV-000-3010"
)
const val password = "SMI@12345"
@@ -96,153 +55,8 @@ object Constants {
const val KIT_COUNT = "KitCount"
const val BUFFER_VALUE_1 = "BufferValue1"
const val BUFFER_VALUE_2 = "BufferValue2"
const val BUFFER_VALUE_3 = "BufferValue3"
const val BUFFER_VALUE_4 = "BufferValue4"
const val DEVICE_ID = "DEVICE_ID"
const val BUFFER_LED_LOWER_BOUND = 21000
const val BUFFER_LED_UPPER_BOUND = 24500
const val TEST_STATUS_CODE_TEST_STARTED = 1.0
const val TEST_STATUS_CODE_CONFIG_STARTED = 2.0
const val TEST_STATUS_CODE_CONFIG_COMPLETED = 3.0
const val TEST_STATUS_CODE_BUFFER_STARTED = 4.0
const val TEST_STATUS_CODE_BUFFER_COMPLETED = 5.0
const val TEST_STATUS_CODE_BUFFER_PRINT_STARTED = 6.0
const val TEST_STATUS_CODE_BUFFER_PRINT_COMPLETED = 7.0
const val TEST_STATUS_CODE_SAMPLE_STARTED = 8.0
const val TEST_STATUS_CODE_SAMPLE_COMPLETED = 9.0
const val TEST_STATUS_CODE_SAMPLE_PRINT_STARTED = 10.0
const val TEST_STATUS_CODE_SAMPLE_PRINT_COMPLETED = 11.0
const val TEST_STATUS_CODE_TEST_COMPLETED = 12.0
val DEVICE_CONFIGURATION: Map<String, List<List<Double>>> = mapOf<String, List<List<Double>>>(
"HCV-000-3001" to listOf(
listOf(1.313, -0.89), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2012, 0.0092), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3002" to listOf(
listOf(0.723142, -0.09135), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.1964, 0.011565), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3003" to listOf(
listOf(0.723142, -0.09135), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.1964, 0.011565), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3004" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3005" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3006" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3007" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3008" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3009" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
"HCV-000-3010" to listOf(
listOf(1.7272, -1.1977), // LED1, 435nm
listOf(0.581462456, -0.58502), // LED2, 415nm
listOf(0.2304, -0.0145), // LED3, 555nm
listOf(1.0, 0.0) // LED4
),
)
const val INCUBATION_TIME_MIN = 0
const val INCUBATION_TIME_MAX = 1400
const val BATTERY_LEVEL_MIN = 0
val BUFFER_INTENSITY_THRESHOLDS: Map<String, List<List<Int>>> = mapOf<String, List<List<Int>>>(
"HCV-000-3001" to listOf(
listOf(20000, 25074),
listOf(20000, 24596),
listOf(20000, 26065),
listOf(20000, 27093),
),
"HCV-000-3002" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3003" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3004" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3005" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3006" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3007" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3008" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3009" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
),
"HCV-000-3010" to listOf(
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
listOf(24500, 26250),
)
)
const val BLOOD_COLLECTING_METHOD = "bloodCollectingMethod"
const val VENOUS_BLOOD = "venousBlood"
const val FINGER_PRICK_BLOOD = "fingerPrickBlood"
}

View File

@@ -2,8 +2,7 @@ package com.example.hpostesting.data.constant
enum class HemoCubeCommands(val command: String) {
startBuffer("B\r"),
runDiagnostics("D\r"),
getBuffer("Q\r"),
startSample("S\r"),
getSample("P\r"),
getDeviceId("I\r"),
}

View File

@@ -1,30 +0,0 @@
package com.example.hpostesting.data.constant
import android.content.Context
import android.content.SharedPreferences
import java.util.Locale
object LanguageManager {
private const val LANGUAGE_PREF_KEY = "language_pref"
fun setLocale(context: Context, languageCode: String) {
val locale = Locale(languageCode)
Locale.setDefault(locale)
val resources = context.resources
val configuration = resources.configuration
configuration.setLocale(locale)
context.createConfigurationContext(configuration)
}
fun persistLanguagePreference(context: Context, languageCode: String) {
val prefs: SharedPreferences = context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
prefs.edit().putString(LANGUAGE_PREF_KEY, languageCode).apply()
}
fun getSavedLanguage(context: Context): String {
val prefs: SharedPreferences = context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
return prefs.getString(LANGUAGE_PREF_KEY, "en") ?: "en"
}
}

View File

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

View File

@@ -11,7 +11,7 @@ import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.google.android.datatransport.runtime.dagger.Provides
import javax.inject.Singleton
@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 15, exportSchema = false)
@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 3, exportSchema = false)
@TypeConverters(Converters::class)
abstract class MyDatabase : RoomDatabase() {
abstract fun userDao(): UserDao

View File

@@ -1,6 +0,0 @@
package com.example.hpostesting.data.model.deviceprovision
data class Credentials(
val password: String? = "",
val username: String? = ""
)

View File

@@ -1,17 +0,0 @@
package com.example.hpostesting.data.model.deviceprovision
data class Device(
val assigned: Boolean? = false,
val createdAt: String? = "",
val createdBy: Int? = 0,
val deviceType: DeviceType? = DeviceType(),
val deviceTypeId: Int? = 0,
val deviceUser: DeviceUser? = DeviceUser(),
val enabled: Boolean? = false,
val id: Int? = 0,
val name: String? = "",
val serialNumber: String? = "",
val uid: String? = "",
val updatedAt: String? = "",
val updatedBy: Int? = 0
)

View File

@@ -1,6 +0,0 @@
package com.example.hpostesting.data.model.deviceprovision
data class DeviceProvisionData(
val credentials: Credentials? = Credentials(),
val device: Device? = Device()
)

View File

@@ -1,9 +0,0 @@
package com.example.hpostesting.data.model.deviceprovision
data class DeviceProvisionRequest(
val deviceTypeName: String? = "",
val email: String? = "",
val password: String? = "",
val serialNumber: String? = "",
val uid: String? = ""
)

View File

@@ -1,12 +0,0 @@
package com.example.hpostesting.data.model.deviceprovision
import com.google.gson.annotations.SerializedName
data class DeviceProvisionResponse(
@SerializedName("Data")
val data: DeviceProvisionData? = DeviceProvisionData(),
@SerializedName("Message")
val message: String? = "",
@SerializedName("Result")
val result: String? = ""
)

View File

@@ -1,12 +0,0 @@
package com.example.hpostesting.data.model.deviceprovision
data class DeviceType(
val createdAt: String? = "",
val createdBy: Int? = 0,
val description: String? = "",
val enabled: Boolean? = false,
val id: Int? = 0,
val name: String? = "",
val updatedAt: String? = "",
val updatedBy: Int? = 0
)

View File

@@ -1,15 +0,0 @@
package com.example.hpostesting.data.model.deviceprovision
data class DeviceUser(
val createdAt: String? = "",
val createdBy: Int? = 0,
val deviceId: Int? = 0,
val enabled: Boolean? = false,
val id: Int? = 0,
val lastLogin: Any? = Any(),
val natsToken: String? = "",
val natsTokenExpiry: String? = "",
val updatedAt: String? = "",
val updatedBy: Int? = 0,
val username: String? = ""
)

View File

@@ -1,9 +0,0 @@
package com.example.hpostesting.data.model.diagnostics
data class DiagnosticsData (
var deviceId: String = "",
var appVersion: String? = "",
var deviceType: String = "HEMOCUBE",
var deviceData: String = "",
var runTime: String = ""
)

View File

@@ -1,5 +0,0 @@
package com.example.hpostesting.data.model.log
data class UploadLogsData(
val filename: String? = ""
)

View File

@@ -1,12 +0,0 @@
package com.example.hpostesting.data.model.log
import com.google.gson.annotations.SerializedName
data class UploadLogsResponse(
@SerializedName("Data")
val data: UploadLogsData? = UploadLogsData(),
@SerializedName("Message")
val message: String? = "",
@SerializedName("Result")
val result: String? = ""
)

View File

@@ -1,16 +0,0 @@
package com.example.hpostesting.data.model.login
data class Device(
val assigned: Boolean? = false,
val createdAt: String? = "",
val createdBy: Int? = 0,
val deviceType: DeviceType? = DeviceType(),
val deviceTypeId: Int? = 0,
val enabled: Boolean? = false,
val id: Int? = 0,
val name: String? = "",
val serialNumber: String? = "",
val uid: String? = "",
val updatedAt: String? = "",
val updatedBy: Int? = 0
)

View File

@@ -1,12 +0,0 @@
package com.example.hpostesting.data.model.login
data class DeviceType(
val createdAt: String? = "",
val createdBy: Int? = 0,
val description: String? = "",
val enabled: Boolean? = false,
val id: Int? = 0,
val name: String? = "",
val updatedAt: String? = "",
val updatedBy: Int? = 0
)

View File

@@ -1,16 +0,0 @@
package com.example.hpostesting.data.model.login
data class DeviceUser(
val createdAt: String? = "",
val createdBy: Int? = 0,
val device: Device? = Device(),
val deviceId: Int? = 0,
val enabled: Boolean? = false,
val id: Int? = 0,
val lastLogin: String? = "",
val natsToken: String? = "",
val natsTokenExpiry: String? = "",
val updatedAt: String? = "",
val updatedBy: Int? = 0,
val username: String? = ""
)

View File

@@ -1,6 +0,0 @@
package com.example.hpostesting.data.model.login
data class LoginData(
val accessToken: String? = "",
val deviceUser: DeviceUser? = DeviceUser()
)

View File

@@ -1,12 +0,0 @@
package com.example.hpostesting.data.model.login
data class LoginRequest(
val lab: String? = "",
val latitude: String? = "",
val location: String? = "",
val longitude: String? = "",
val mode: String? = "",
val password: String? = "",
val serialNumber: String? = "",
val username: String? = ""
)

View File

@@ -1,12 +0,0 @@
package com.example.hpostesting.data.model.login
import com.google.gson.annotations.SerializedName
data class LoginResponse(
@SerializedName("Data")
val data: LoginData? = LoginData(),
@SerializedName("Message")
val message: String? = "",
@SerializedName("Result")
val result: String? = ""
)

View File

@@ -1,38 +0,0 @@
package com.example.hpostesting.data.model.molbioresult
import com.example.hpostesting.data.model.patient.HemoCubeTestData
data class MolbioV2Result(
val age: Int? = 31,
val analysisDate: String? = "",
val analysisId: String? = "",
val analysisStatus: String? = "",
val analysisType: String? = "HPOS",
val analysisTypeMethod: String? = "",
val bloodGroup: String? = "",
val coefficients: List<Int>? = listOf(22, 22),
val collectionLocation: List<Any>? = listOf(),
val collectionTime: String? = "",
val collector: String? = "",
val curveFitting: String? = "Linear",
val deviceName: String? = "HPOS",
val expiryTime: String? = "",
val gender: String? = "",
val interpretation: String? = "",
val `operator`: String? = "",
val patientId: Int? = 4545,
val pregnancy: Boolean? = false,
val rawData: HemoCubeTestData? = HemoCubeTestData(),
val recommendation: String? = "NA",
val sampleId: String? = "",
val sampleType: String? = "",
val sickleCellHistory: Boolean? = false,
val testId: String? = "",
val testResult: String? = "",
val testStatus: String? = "",
val testTime: String? = "",
val testType: String? = "",
val thresholds: String? = "",
val underMedication: Boolean? = false,
val volume: Int? = 2
)

View File

@@ -1,42 +0,0 @@
package com.example.hpostesting.data.model.molbioresult
import com.example.hpostesting.data.model.patient.HemoCubeTestData
data class MolbioV2ResultData(
val age: Int? = 0,
val analysisDate: String? = "",
val analysisStatus: String? = "",
val analysisType: String? = "",
val analysisTypeMethod: String? = "",
val bloodGroup: String? = "",
val coefficients: List<Int>? = listOf(),
val collectionLocation: List<Any>? = listOf(),
val collectionTime: String? = "",
val collector: String? = "",
val createdAt: String? = "",
val createdBy: Int? = 0,
val curveFitting: String? = "",
val deviceId: Int? = 0,
val expiryTime: String? = "",
val gender: String? = "",
val id: Int? = 0,
val interpretation: String? = "",
val `operator`: String? = "",
val patientId: Int? = 0,
val pregnancy: Boolean? = false,
val rawData: HemoCubeTestData? = HemoCubeTestData(),
val recommendation: String? = "",
val sampleId: String? = "",
val sampleType: String? = "",
val sickleCellHistory: Boolean? = false,
val testId: String? = "",
val testResult: String? = "",
val testStatus: String? = "",
val testTime: String? = "",
val testType: String? = "",
val thresholds: String? = "",
val underMedication: Boolean? = false,
val updatedAt: String? = "",
val updatedBy: Int? = 0,
val volume: Int? = 0
)

View File

@@ -1,5 +0,0 @@
package com.example.hpostesting.data.model.molbioresult
data class MolbioV2ResultRequest(
val results: List<MolbioV2Result>? = listOf()
)

View File

@@ -1,12 +0,0 @@
package com.example.hpostesting.data.model.molbioresult
import com.google.gson.annotations.SerializedName
data class MolbioV2ResultResponse(
@SerializedName("Data")
val data: List<MolbioV2ResultData>? = listOf(),
@SerializedName("Message")
val message: String? = "",
@SerializedName("Result")
val result: String? = ""
)

View File

@@ -1,55 +0,0 @@
package com.example.hpostesting.data.model.molbioresult
import com.example.hpostesting.data.model.patient.UserData
data class RawData(
var _id: String = "",
var name: String = "",
var incubationTime: String = "",
var bloodGroup: String = "",
var birthYear: String = "",
var state: String = "",
var abhaId: String = "",
var userImageURL: String = "",
var location: UserData.Location? = null,
var reportUploadTime: String? = "",
var testType: String? = "HEMOCUBE",
var testTime: String? = "",
var testStatus: Boolean? = false,
var gender: String = "",
var localFlag: Boolean = false,
var deviceId: String? = "",
var appVersion:String? = "",
var deviceSerialNumber: String = "",
var deviceType: String = "HEMOCUBE",
var kitSerial: String = "",
var resultData: String = "",
var led1Buffer: Double? = null,
var led2Buffer: Double? = null,
var led3Buffer: Double? = null,
var led4Buffer: Double? = null,
var led1Sample: Double? = null,
var led2Sample: Double? = null,
var led3Sample: Double? = null,
var led4Sample: Double? = null,
var led1Average: Double? = null,
var led2Average: Double? = null,
var led3Average: Double? = null,
var led4Average: Double? = null,
var abs1: Double? = null,
var abs2: Double? = null,
var abs3: Double? = null,
var abs4: Double? = null,
var deviceRatio: Double? = null,
var calculatedRatio: Double? = null,
var predictedDenovixRatio: Double? = null,
var coefficients: String? = "",
var classificationResult: String = "",
var prdClassification: String = "",
var errorMessages: String = "",
var batteryLevel: String = "",
var batteryCapacity: String = "",
var batteryMaxCapacity: String = "",
var batteryTemperature: String = "",
var batteryVoltage: String = "",
)

View File

@@ -1,21 +0,0 @@
package com.example.hpostesting.data.model.patient
data class BufferCheckData(
var kitno: String = "",
var deviceId: String? = "",
var appVersion:String? = "",
var deviceSerialNumber: String = "",
var deviceType: String = "HEMOCUBE",
var resultData: String = "",
var led1Buffer: Double? = null,
var led2Buffer: Double? = null,
var led1Sample: Double? = null,
var led2Sample: Double? = null,
var led1Average: Double? = null,
var led2Average: Double? = null,
var deviceRatio: Double? = null,
var calculatedRatio: Double? = null,
var coefficients: String? = "",
var classificationResult: String = "",
var testTime: String = ""
)

View File

@@ -3,23 +3,18 @@ package com.example.hpostesting.data.model.patient
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "hemo_cube_test_table")
@Entity(tableName = "HemocubeTest_table")
data class HemoCubeTestData(
@PrimaryKey
var _id: String = "",
var name: String = "",
var incubationTime: String = "",
var bloodGroup: String = "",
var birthYear: String = "",
var state: String = "",
var abhaId: String = "",
var userImageURL: String = "",
var location: UserData.Location? = null,
var reportUploadTime: String? = "",
var testType: String? = "HEMOCUBE",
var testTime: String? = "",
var testStatus: Boolean? = false,
var gender: String = "",
var localFlag: Boolean = false,
var deviceId: String? = "",
var appVersion:String? = "",
@@ -29,31 +24,10 @@ data class HemoCubeTestData(
var resultData: String = "",
var led1Buffer: Double? = null,
var led2Buffer: Double? = null,
var led3Buffer: Double? = null,
var led4Buffer: Double? = null,
var led1Sample: Double? = null,
var led2Sample: Double? = null,
var led3Sample: Double? = null,
var led4Sample: Double? = null,
var led1Average: Double? = null,
var led2Average: Double? = null,
var led3Average: Double? = null,
var led4Average: Double? = null,
var abs1: Double? = null,
var abs2: Double? = null,
var abs3: Double? = null,
var abs4: Double? = null,
var deviceRatio: Double? = null,
var calculatedRatio: Double? = null,
var predictedDenovixRatio: Double? = null,
var coefficients: String? = "",
var classificationResult: String = "",
var prdClassification: String = "",
var errorMessages: String = "",
var batteryLevel: String = "",
var batteryCapacity: String = "",
var batteryMaxCapacity: String = "",
var batteryTemperature: String = "",
var batteryVoltage: String = "",
var molbioFlag: Boolean = false
var calculatedRatio: Double? = null
)

View File

@@ -9,12 +9,8 @@ data class UserData(
@PrimaryKey
var _id: String = "",
var name: String = "",
var incubationTime: String = "",
var birthYear: String = "",
var abhaId: String = "",
var bloodGroup: String = "",
var userImageURL: String = "",
var gender: String ="",
var location: Location? = null,
var createdBy: String? = "",
var reportUploadTime: String? = "",
@@ -22,14 +18,12 @@ data class UserData(
var testStatus: Boolean? = false,
var mobileId: String = "",
var deviceId: String = "",
var state: String = "",
var deviceSerialNumber: String = "",
var kitSerial: String = "",
var csvPath: String = "",
var reportPath: String = "",
var result: TestRightResultType? = null,
var resultRatio: Double? = null,
var prdClassification: String = ""
var resultRatio: Double? = null
) {
enum class Gender {
MALE,
@@ -49,11 +43,5 @@ fun UserData.toHemoCubeTestData() = HemoCubeTestData(
birthYear = birthYear,
userImageURL = userImageURL,
testStatus = testStatus,
location = location,
gender = gender,
state = state,
abhaId = abhaId,
bloodGroup = bloodGroup,
prdClassification = prdClassification,
testTime = testTime
location = location
)

View File

@@ -0,0 +1,55 @@
package com.example.hpostesting.data.model.test
import com.example.hpostesting.data.model.Location
import java.util.Date
data class TestDetails(
val testID: String,
var testStatus: Status,
val patientID: String,
val patientName: String,
val patientAge: Int?,
var resultRatio: Double?,
var result: TestRightResultType?,
val reportPath: String?,
val csvPath: String?,
val logPath: String?,
// Meta Data
var deviceId: String?,
val mobileId: String,
var kitSerial: String?,
val location: Location?,
val appVersion: String,
val registeredTime: Date?,
var uploadTime: Date?
) {
constructor() : this(
"",
Status.PENDING,
"",
"",
null,
null,
null,
null,
null,
null,
null,
"",
null,
null,
"",
null,
null
)
}
enum class Status {
COMPLETED,
PENDING,
INPROGRESS
}

View File

@@ -0,0 +1,11 @@
package com.example.hpostesting.data.model.test
data class TestInfo(
val value: String,
val number1: String,
val number2: String,
val result: String,
val resultConfirmatory: String,
val directoryPath: String,
val fullPath: String
)

View File

@@ -1,5 +0,0 @@
package com.example.hpostesting.data.model.updates
data class CheckUpdateData(
val version: String? = ""
)

View File

@@ -1,5 +0,0 @@
package com.example.hpostesting.data.model.updates
data class CheckUpdateRequest(
val currentVersion: String? = ""
)

View File

@@ -1,12 +0,0 @@
package com.example.hpostesting.data.model.updates
import com.google.gson.annotations.SerializedName
data class CheckUpdateResponse(
@SerializedName("Data")
val data: CheckUpdateData? = CheckUpdateData(),
@SerializedName("Message")
val message: String? = "",
@SerializedName("Result")
val result: String? = ""
)

View File

@@ -1,5 +0,0 @@
package com.example.hpostesting.data.model.updates
data class DeviceUpdateRequest(
val serial_no: String? = ""
)

View File

@@ -1,150 +1,75 @@
package com.example.hpostesting.data.repository
import android.content.Context
import android.net.Uri
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi
import androidx.room.Room
import com.example.hpostesting.data.dao.MyDatabase
import com.example.hpostesting.data.model.PendingUploads
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.log.UploadLogsResponse
import com.example.hpostesting.data.model.login.LoginRequest
import com.example.hpostesting.data.model.login.LoginResponse
import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultRequest
import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultResponse
import com.example.hpostesting.data.model.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.updates.CheckUpdateRequest
import com.example.hpostesting.data.model.updates.CheckUpdateResponse
import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.android.datatransport.runtime.dagger.Provides
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.google.firebase.storage.ktx.storage
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.tasks.await
import okhttp3.MultipartBody
import okhttp3.ResponseBody
import kotlinx.coroutines.withContext
import java.io.File
import java.net.ConnectException
import java.net.SocketTimeoutException
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Singleton
class NetworkException(message: String, cause: Throwable) : Exception(message, cause)
class DatabaseRepository @Inject constructor(
@Named("Auth")private val molbioAuthApi: MolbioAuthApi,
private val molbioResultApi: MolbioResultApi
) : Repository {
class DatabaseRepository : Repository {
private val db: FirebaseFirestore = Firebase.firestore
private val storage = Firebase.storage
private suspend fun <T : Any> safeApiCall(apiCall: suspend () -> T): Result<T> {
suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String> {
return try {
val response = apiCall.invoke()
Result.Success(response)
} catch (e: SocketTimeoutException) {
Result.Error(NetworkException("Network timeout", e))
} catch (e: ConnectException) {
Result.Error(NetworkException("Network connection failed", e))
} catch (e: Exception) {
Result.Error(e)
}
}
suspend fun deviceProvision(deviceProvisionRequest: DeviceProvisionRequest): Result<DeviceProvisionResponse> {
return safeApiCall { molbioAuthApi.deviceProvision(deviceProvisionRequest) }
}
suspend fun login(loginRequest: LoginRequest): Result<LoginResponse> {
return safeApiCall { molbioAuthApi.login(loginRequest) }
}
suspend fun uploadResults(molbioV2ResultRequest: MolbioV2ResultRequest): Result<MolbioV2ResultResponse> {
return safeApiCall { molbioResultApi.uploadResults(molbioV2ResultRequest) }
}
suspend fun checkUpdate(checkUpdateRequest: CheckUpdateRequest): Result<CheckUpdateResponse> {
return safeApiCall { molbioResultApi.checkUpdate(checkUpdateRequest) }
}
suspend fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest): Result<ResponseBody> {
return safeApiCall { molbioResultApi.deviceUpdate(deviceUpdateRequest) }
}
suspend fun uploadLogs(logFile: MultipartBody.Part): Result<UploadLogsResponse> {
return safeApiCall { molbioResultApi.uploadLogs(logFile) }
}
override suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String> {
return try {
val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
val userdata = db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true)
}
}
db.collection("testData").add(data).await()
Response.Success(data._id)
db.collection("testData").add(data!!).await()
Response.Success(data!!._id)
} catch (e: Exception) {
Response.Error(e)
}
}
override suspend fun addTestToDatabase(data: UserData?): Response<String> {
suspend fun addTestToDatabase(data: UserData?): Response<String> {
return try {
val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
val userdata = db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true)
}
}
db.collection("testData").add(data).await()
Response.Success(data._id)
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> {
return try {
db.collection("buffers").add(data!!).await()
Response.Success(data.kitno)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
}
override suspend fun addDiagnostics(data: DiagnosticsData?): Response<String> {
return try {
db.collection("diagnostics").add(data!!).await()
Response.Success(data.deviceId)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
}
override suspend fun uploadFileToStorage(
patientID: String, filePath: String
): Response<Boolean> {
suspend fun uploadFileToStorage(patientID: String, filePath: String): Response<Boolean> {
try {
val file = Uri.fromFile(File(filePath))
val riversRef = storage.reference.child("$patientID/${file.lastPathSegment}")
riversRef.putFile(file).await()
return Response.Success(true)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
e.printStackTrace()
return Response.Error(e)
}
}
@@ -156,7 +81,7 @@ class DatabaseRepository @Inject constructor(
Response.Success(true)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
e.printStackTrace()
Response.Error(e)
}
}
@@ -175,7 +100,7 @@ class DatabaseRepository @Inject constructor(
pendingList
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
e.printStackTrace()
pendingList
}
}
@@ -186,7 +111,7 @@ class DatabaseRepository @Inject constructor(
Response.Success(true)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
e.printStackTrace()
Response.Error(e)
}
}
@@ -195,11 +120,15 @@ class DatabaseRepository @Inject constructor(
return db.collection("devices").get().await().toObjects(DeviceData::class.java)
}
override suspend fun getDeviceDataById(deviceId: String): DeviceData? {
suspend fun getDeviceDataById(deviceId: String): DeviceData? {
val querySnapshot = db.collection("devices").get().await()
val allDeviceDataList = querySnapshot.toObjects(DeviceData::class.java)
// Find the DeviceData object with the specified deviceId
return allDeviceDataList.find { it.deviceId == deviceId }
}
}

View File

@@ -1,22 +1,5 @@
package com.example.hpostesting.data.repository
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
interface Repository {
suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String>
suspend fun addTestToDatabase(data: UserData?): Response<String>
suspend fun addTestToDatabaseforBufferCheck(data: BufferCheckData?): Response<String>
suspend fun addDiagnostics(data: DiagnosticsData?): Response<String>
suspend fun uploadFileToStorage(patientID: String, filePath: String): Response<Boolean>
suspend fun getDeviceDataById(deviceId: String): DeviceData?
// suspend fun addToDatabase(data: PatientDetails)
}

View File

@@ -1,23 +0,0 @@
package com.example.hpostesting.domain
import android.content.SharedPreferences
import com.example.hpostesting.data.constant.Constants
import okhttp3.Interceptor
import okhttp3.Response
class AuthInterceptor(private val sharedPreferences: SharedPreferences) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
val token = sharedPreferences.getString(Constants.ACCESS_TOKEN, null)
if (token != null) {
request = request.newBuilder()
.addHeader("Authorization", "Bearer $token")
.build()
}
return chain.proceed(request)
}
}

View File

@@ -1,28 +0,0 @@
package com.example.hpostesting.domain
import android.content.Context
import android.util.Log
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
class CheckUpdateWorker(
context: Context,
workerParams: WorkerParameters
) : CoroutineWorker(context, workerParams) {
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
try {
for (i in 1..900){
delay(1000)
Log.d("Work for every second", "doWork: Running")
}
Result.success()
} catch (e: Exception) {
Result.failure()
}
}
}

View File

@@ -1,38 +0,0 @@
package com.example.hpostesting.domain
import android.content.Context
import android.util.Log
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
class LogFileManager(private val context: Context) {
fun createLogFile(): File? {
val unixTime = System.currentTimeMillis() / 1000L
val logFileName = "hpos_$unixTime.log"
return try {
val process = Runtime.getRuntime().exec("logcat -d -v threadtime")
val logBuilder = StringBuilder()
val input = process.inputStream
val bufferedReader = input.bufferedReader()
bufferedReader.forEachLine { line ->
logBuilder.append(line).append("\n")
}
val logContent = logBuilder.toString()
val file = File(context.filesDir, logFileName)
val fileOutputStream = FileOutputStream(file)
fileOutputStream.write(logContent.toByteArray())
fileOutputStream.close()
file
} catch (e: IOException) {
Log.e("LogFileManager", "Error creating log file: ${e.message}")
null
}
}
}

View File

@@ -2,34 +2,20 @@ package com.example.hpostesting.domain.di
import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import android.content.res.AssetManager
import androidx.room.Room
import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi
import com.example.hpostesting.data.api.PropertyProvider
import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.dao.MyDatabase
import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.datasource.LocalFileDataSource
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.data.repository.LocalFileRepository
import com.example.hpostesting.data.repository.Repository
import com.example.hpostesting.domain.AuthInterceptor
import com.example.hpostesting.domain.LogFileManager
import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpostesting.util.PropertyProviderImpl
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
import javax.inject.Named
import javax.inject.Singleton
@Module
@@ -41,7 +27,9 @@ object AppModule {
fun provideMyDatabase(@ApplicationContext context: Context): MyDatabase {
return Room.databaseBuilder(
context, MyDatabase::class.java, "my_database"
).fallbackToDestructiveMigration().build()
)
.fallbackToDestructiveMigration()
.build()
}
@Provides
@@ -78,89 +66,7 @@ object AppModule {
@Provides
@Singleton
fun provideDatabaseRepository(
@Named("Auth") molbioAuthApi: MolbioAuthApi,
molbioResultApi: MolbioResultApi
): DatabaseRepository {
return DatabaseRepository(molbioAuthApi = molbioAuthApi, molbioResultApi = molbioResultApi)
fun provideDatabaseRepository(): DatabaseRepository {
return DatabaseRepository()
}
@Provides
@Singleton
fun provideRepository(
@Named("Auth") molbioAuthApi: MolbioAuthApi,
molbioResultApi: MolbioResultApi
): Repository {
return DatabaseRepository(molbioAuthApi, molbioResultApi)
}
@Provides
@Singleton
fun provideAssetManager(@ApplicationContext context: Context): AssetManager {
return context.assets
}
@Provides
@Singleton
fun providePropertyProvider(assetManager: AssetManager): PropertyProvider {
return PropertyProviderImpl(assetManager)
}
@Provides
@Singleton
fun provideSharedPreferences(@ApplicationContext context: Context): SharedPreferences {
return context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
}
@Provides
@Singleton
fun provideAuthInterceptor(sharedPreferences: SharedPreferences): AuthInterceptor {
return AuthInterceptor(sharedPreferences)
}
@Provides
@Singleton
@Named("Auth")
fun provideAuthOkHttpClient(authInterceptor: AuthInterceptor): OkHttpClient {
return OkHttpClient.Builder().addInterceptor(authInterceptor)
.connectTimeout(30, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).build()
}
@Provides
@Singleton
fun provideOkHttpClient(): OkHttpClient =
OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS).build()
@Provides
@Singleton
fun provideRetrofit(
propertyProvider: PropertyProvider,@Named("Auth") client: OkHttpClient
): Retrofit {
return Retrofit.Builder().baseUrl(propertyProvider.getProperty("BASE_URL")).client(client)
.addConverterFactory(GsonConverterFactory.create()).build()
}
@Provides
@Singleton
@Named("Auth")
fun provideAuthRetrofit(propertyProvider: PropertyProvider, client: OkHttpClient): Retrofit {
return Retrofit.Builder().baseUrl(propertyProvider.getProperty("BASE_URL")).client(client)
.addConverterFactory(GsonConverterFactory.create()).build()
}
@Provides
@Singleton
@Named("Auth")
fun provideAuthApi(@Named("Auth") retrofit: Retrofit): MolbioAuthApi =
retrofit.create(MolbioAuthApi::class.java)
@Provides
@Singleton
fun provideResultApi(retrofit: Retrofit): MolbioResultApi =
retrofit.create(MolbioResultApi::class.java)
@Provides
@Singleton
fun provideLogFileManager(context: Context): LogFileManager = LogFileManager(context)
}

View File

@@ -0,0 +1,57 @@
package com.example.hpostesting.presentation
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import com.example.hpostesting.presentation.testRight.TestRightActivity
import `in`.sminnovations.hpostesting.databinding.ActivityBloodCollectingMethodBinding
class BloodCollectingMethodActivity : AppCompatActivity() {
private lateinit var binding: ActivityBloodCollectingMethodBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityBloodCollectingMethodBinding.inflate(layoutInflater)
setContentView(binding.root)
init()
}
private fun init() {
setSupportActionBar(binding.toolbar)
binding.btnGo.setOnClickListener {
DataHolder.usbConnected.observe(this) {
if (it) {
if (binding.venousBloodRadioButton.isChecked) {
moveToNext(Constants.VENOUS_BLOOD)
} else {
moveToNext(Constants.FINGER_PRICK_BLOOD)
}
} else {
Toast.makeText(this, "No Device Connected", Toast.LENGTH_SHORT).show()
}
}
}
}
private fun moveToNext(bloodCollectingMethod: String) {
DataHolder.deviceType.observe(this) { deviceType ->
when (deviceType) {
Constants.DEVICE_TYPE_HOMOCUBE -> {
val intent = Intent(applicationContext, HemocubeActivity::class.java)
intent.putExtra(Constants.BLOOD_COLLECTING_METHOD, bloodCollectingMethod)
startActivity(intent)
}
Constants.DEVICE_TYPE_TEST_RIGHT -> {
val intent = Intent(applicationContext, TestRightActivity::class.java)
intent.putExtra(Constants.BLOOD_COLLECTING_METHOD, bloodCollectingMethod)
startActivity(intent)
}
}
}
}
}

View File

@@ -1,6 +1,5 @@
package com.example.hpostesting.presentation
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
@@ -11,10 +10,7 @@ import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import com.example.hpostesting.presentation.testRight.TestRightActivity
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.google.android.material.snackbar.Snackbar
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.journeyapps.barcodescanner.ScanContract
@@ -34,7 +30,7 @@ class KitScanActivity : AppCompatActivity() {
ScanContract()
) { result: ScanIntentResult ->
if (result.contents.isNullOrEmpty()) {
Toast.makeText(this, R.string.cancelled_unable_scan, Toast.LENGTH_LONG).show()
Toast.makeText(this, "Cancelled: Unable to scan, Try Again!!", Toast.LENGTH_LONG).show()
} else {
Log.d(TAG, result.contents)
processScannedData(result.contents)
@@ -45,12 +41,6 @@ class KitScanActivity : AppCompatActivity() {
binding.nameEditText.setText(contents)
}
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -74,25 +64,14 @@ class KitScanActivity : AppCompatActivity() {
// putString(Constants.BUFFER_VALUE_1, "")
// putString(Constants.BUFFER_VALUE_2, "")
// apply()
// }
// }
try {
if (checkHemoCubeKitData()) {
try {
DataHolder.selectedTest!!.kitSerial =
sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
moveToNext()
} else {
// Handle the case when checkHemoCubeKitData() returns false
with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "")
putInt(Constants.KIT_COUNT, 0)
putString(Constants.BUFFER_VALUE_1, "")
putString(Constants.BUFFER_VALUE_2, "")
apply()
}
}
} catch (e: NullPointerException) {
// Handle the NullPointerException here
e.printStackTrace() // You can log the exception for debugging
@@ -101,10 +80,20 @@ class KitScanActivity : AppCompatActivity() {
val rootView = findViewById<View>(android.R.id.content)
Snackbar.make(rootView, errorMessage, Snackbar.LENGTH_LONG).show()
// Optionally, show a user-friendly error message to the user
// Toast.makeText(applicationContext, "An error occurred", Toast.LENGTH_SHORT).show()
// Toast.makeText(applicationContext, "An error occurred", Toast.LENGTH_SHORT).show()
}
} else {
with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "")
putInt(Constants.KIT_COUNT, 0)
putString(Constants.BUFFER_VALUE_1, "")
putString(Constants.BUFFER_VALUE_2, "")
apply()
}
}
binding.nameEditText.setText("SMI/SC/")
setSupportActionBar(binding.toolbar)
@@ -116,42 +105,7 @@ class KitScanActivity : AppCompatActivity() {
binding.btnGo.setOnClickListener {
val serialNumber = binding.nameEditText.text.toString().trim()
if (serialNumber.isNotEmpty() && isSerialValid(serialNumber)) {
if (DataHolder.selectedTest == null) {
with(sharedPreference.edit()) {
putString(
Constants.KIT_NUMBER, binding.nameEditText.text.toString()
)
putInt(Constants.KIT_COUNT, 1)
apply()
}
Toast.makeText(
applicationContext,
R.string.kit_updated,
Toast.LENGTH_SHORT
).show()
val i = Intent(applicationContext, DashboardActivity::class.java)
startActivity(i)
finish()
} else {
DataHolder.kitSerial = binding.nameEditText.text.toString()
DataHolder.selectedTest?.kitSerial = binding.nameEditText.text.toString()
with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, binding.nameEditText.text.toString())
putInt(Constants.KIT_COUNT, 1)
apply()
}
moveToNext()
}
} else {
Toast.makeText(this, R.string.invalid_kit_number, Toast.LENGTH_LONG).show()
return@setOnClickListener
}
if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid(
serialNumber
)
) {
if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid(serialNumber)) {
DataHolder.kitSerial = binding.nameEditText.text.toString()
DataHolder.selectedTest?.kitSerial = binding.nameEditText.text.toString()
with(sharedPreference.edit()) {
@@ -161,16 +115,15 @@ class KitScanActivity : AppCompatActivity() {
}
moveToNext()
} else {
Toast.makeText(this, R.string.invalid_kit_number, Toast.LENGTH_LONG).show()
Toast.makeText(this, "Invalid KIT Number", Toast.LENGTH_LONG).show()
}
}
}
private fun checkHemoCubeKitData(): Boolean {
return sharedPreference.getString(Constants.KIT_NUMBER, "")
?.isNotBlank() == true && sharedPreference.getInt(
Constants.KIT_COUNT, 0
) > 0 && sharedPreference.getInt(Constants.KIT_COUNT, 0) < 35
?.isNotBlank() == true && sharedPreference.getInt(Constants.KIT_COUNT, 0) > 0
&& sharedPreference.getInt(Constants.KIT_COUNT, 0) < 35
}
private fun isSerialValid(s: String): Boolean {
@@ -182,22 +135,10 @@ class KitScanActivity : AppCompatActivity() {
}
private fun moveToNext() {
DataHolder.deviceType.observe(this) { deviceType ->
when (deviceType) {
Constants.DEVICE_TYPE_HOMOCUBE -> {
val i = Intent(applicationContext, HemocubeActivity::class.java)
val i = Intent(applicationContext, BloodCollectingMethodActivity::class.java)
startActivity(i)
}
Constants.DEVICE_TYPE_TEST_RIGHT -> {
val i = Intent(applicationContext, TestRightActivity::class.java)
startActivity(i)
}
}
}
}
private fun startScanningNow() {
val options = ScanOptions()
options.setDesiredBarcodeFormats(ScanOptions.QR_CODE)
@@ -217,7 +158,7 @@ class KitScanActivity : AppCompatActivity() {
private fun checkDataNotNull(): Boolean {
return if (DataHolder.selectedTest?._id == null) {
Toast.makeText(
applicationContext, R.string.select_patient, Toast.LENGTH_SHORT
applicationContext, "Please Select patient before starting test", Toast.LENGTH_SHORT
).show()
val i = Intent(applicationContext, DashboardActivity::class.java)

View File

@@ -1,6 +1,5 @@
package com.example.hpostesting.presentation
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import android.Manifest
import android.content.*
import android.content.pm.PackageManager
@@ -10,6 +9,8 @@ import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
@@ -17,7 +18,6 @@ import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.test.TestType
import com.google.android.gms.location.*
@@ -45,12 +45,6 @@ class MainActivity : AppCompatActivity() {
}
}
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
@@ -91,10 +85,17 @@ class MainActivity : AppCompatActivity() {
}
}
if (DataHolder.selectedTest == null) {
startActivity(Intent(this, DashboardActivity::class.java))
finish()
}
// val crashButton = Button(this)
// crashButton.text = "Test Crash"
// crashButton.setOnClickListener {
// throw RuntimeException("Test Crash") // Force a crash
// }
//
// addContentView(crashButton, ViewGroup.LayoutParams(
// ViewGroup.LayoutParams.MATCH_PARENT,
// ViewGroup.LayoutParams.WRAP_CONTENT))
}
private fun checkAndUpdateUsbConnection() {
@@ -104,7 +105,6 @@ class MainActivity : AppCompatActivity() {
val deviceType = when {
availableDrivers.isNotEmpty() -> {
val device = availableDrivers[0].device
Toast.makeText(this, R.string.device, Toast.LENGTH_SHORT).show()
when {
device.productId == Constants.HOMO_CUBE_ID && device.vendorId == Constants.VENDOR_ID -> {
binding.cvItem1.visibility = View.VISIBLE
@@ -115,15 +115,6 @@ class MainActivity : AppCompatActivity() {
Constants.DEVICE_TYPE_HOMOCUBE
}
device.productId == Constants.HEMO_CUBE_V2_PRODUCT_ID && device.vendorId == Constants.HEMO_CUBE_V2_VENDOR_ID -> {
binding.cvItem1.visibility = View.VISIBLE
binding.cvItem3.visibility = View.VISIBLE
binding.cvItem2.visibility = View.GONE
binding.cvItem4.visibility = View.GONE
DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_HOMOCUBE)
Constants.DEVICE_TYPE_HOMOCUBE
}
device.productId == Constants.DEVICE_PRODUCT_ID && device.vendorId == Constants.DEVICE_VENDOR_ID -> {
Log.d(
TAG,
@@ -153,7 +144,7 @@ class MainActivity : AppCompatActivity() {
else -> {
Log.d(TAG, "Device NOT Connected")
Toast.makeText(this, R.string.device_not, Toast.LENGTH_SHORT).show()
Toast.makeText(this, "Device Not Connected", Toast.LENGTH_SHORT).show()
DataHolder.usbConnected.value = false
null
}
@@ -170,14 +161,12 @@ class MainActivity : AppCompatActivity() {
DataHolder.selectedTestType = TestType.SICKLECERT
val i = Intent(applicationContext, KitScanActivity::class.java)
startActivity(i)
finish()
}
binding.cvItem2.setOnClickListener {
DataHolder.selectedTestType = TestType.SICKLEFIND
val i = Intent(applicationContext, KitScanActivity::class.java)
startActivity(i)
finish()
}
DataHolder.usbConnected.observe(this) {
@@ -241,7 +230,7 @@ class MainActivity : AppCompatActivity() {
) != PackageManager.PERMISSION_GRANTED
) {
// Handle location permission request if needed
Toast.makeText(this, R.string.enable_location, Toast.LENGTH_SHORT).show()
Toast.makeText(this, "Please enable location services", Toast.LENGTH_SHORT).show()
requestCoarseLocationPermission()
requestFineLocationPermission()
return
@@ -261,15 +250,12 @@ class MainActivity : AppCompatActivity() {
// }
fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
location?.let {
if (DataHolder.selectedTest != null) {
DataHolder.selectedTest!!.location =
UserData.Location(location.latitude, location.longitude)
} else {
startActivity(Intent(this, DashboardActivity::class.java))
finish()
}
DataHolder.location =
UserData.Location(location.latitude, location.longitude)
} ?: run {
@@ -287,6 +273,8 @@ class MainActivity : AppCompatActivity() {
}
private fun requestLocationUpdates() {
@@ -328,7 +316,7 @@ class MainActivity : AppCompatActivity() {
requestFineLocationPermission()
} else {
// Coarse location permission denied
Toast.makeText(this, R.string.coarse_location_denied, Toast.LENGTH_SHORT)
Toast.makeText(this, "Coarse location permission denied", Toast.LENGTH_SHORT)
.show()
}
}
@@ -339,7 +327,7 @@ class MainActivity : AppCompatActivity() {
getLocation()
} else {
// Fine location permission denied
Toast.makeText(this, R.string.location_denied, Toast.LENGTH_SHORT)
Toast.makeText(this, "Fine location permission denied", Toast.LENGTH_SHORT)
.show()
}
}

View File

@@ -1,134 +0,0 @@
package com.example.hpostesting.presentation
import android.util.Log
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import io.nats.client.AuthHandler
import io.nats.client.Connection
import io.nats.client.Message
import io.nats.client.NKey
import io.nats.client.Nats
import io.nats.client.Options
import java.io.IOException
import java.nio.charset.StandardCharsets
import java.security.GeneralSecurityException
class NatsManager(datacollector: DashboardActivity) {
val TAG = "Nats Service"
var nc: Connection? = null
val datacollector = datacollector
var connect = false
fun connect() {
Log.d(TAG, "TRY TO CONNECT")
Thread {
val seedString = "SUAK5IDCMHY4T2WA2LHNXGICGHKR3TPJFNSP6AUQP523RLANO4PSR6IEYA"
val seedBytes = seedString.toCharArray()
val theNKey = NKey.fromSeed(seedBytes) // really should load from somewhere
val options = Options.Builder()
.server("nats://192.168.10.117:4222")
.authHandler(object : AuthHandler {
override fun getID(): CharArray? {
return try {
theNKey?.publicKey
} catch (ex: GeneralSecurityException) {
null
} catch (ex: IOException) {
null
} catch (ex: NullPointerException) {
null
}
}
override fun sign(nonce: ByteArray): ByteArray? {
return try {
theNKey?.sign(nonce)
} catch (ex: GeneralSecurityException) {
null
} catch (ex: IOException) {
null
} catch (ex: NullPointerException) {
null
}
}
override fun getJWT(): CharArray? {
return null
}
})
.build()
try {
nc = Nats.connect(options)
Log.d(TAG, "Connected to Nats server ${options.servers.first()}")
connect = true
datacollector.setConnect(true)
nc?.publish(
"server.hpos.HCV-000-3001.ping",
"ALIVE".toByteArray(StandardCharsets.UTF_8)
)
nc?.publish(
"server.hpos.HCV-000-3001.health",
"ALIVE".toByteArray(StandardCharsets.UTF_8)
)
Log.d(TAG, "Published msg server.hpos.HCV-000-3001.ping on topic Testing")
val d = nc?.createDispatcher { msg: Message? ->
println("PRITIMOI SARKAR $msg")
}
d?.subscribe("device.hpos.HCV-000-3001.update") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8)
datacollector. setResponse(response)
println("Message received (up to 100 times): $response")
}
d?.subscribe("device.hpos.HCV-000-3001.uploadlogs") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8)
datacollector.setResponse(response + "uPLOAD")
println("Message received (up to 100 times): $response")
}
d?.subscribe("device.hpos.HCV-000-3001.disable") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8)
datacollector.setResponse(response)
println("Message received (up to 100 times): $response")
}
d?.subscribe("device.hpos.HCV-000-3001.updatecustomer") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8)
datacollector.setResponse(response)
println("Message received (up to 100 times): $response")
}
d?.subscribe("device.hpos.HCV-000-3001.checkupdate") { msg ->
val response = String(msg.data, StandardCharsets.UTF_8)
datacollector.setResponse(response)
println("Message received (up to 100 times): $response")
}
} catch (exp: Exception) {
println(exp.printStackTrace())
connect = false
datacollector.setConnect(true)
}
}.start()
}
fun pub(topic: String, msg: String) {
nc?.publish(topic, msg.toByteArray(StandardCharsets.UTF_8))
Log.d(TAG, "Published msg ${msg} on topic ${topic}")
}
fun close() {
nc?.close()
Log.d(TAG, "Nats connection close")
}
}

View File

@@ -1,8 +1,6 @@
package com.example.hpostesting.presentation
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
@@ -15,9 +13,11 @@ import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.util.MyUtils
import `in`.sminnovations.hpostesting.R
import com.google.firebase.firestore.FirebaseFirestoreSettings
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.ActivitySplashBinding
class SplashActivity : AppCompatActivity() {
@@ -34,12 +34,6 @@ class SplashActivity : AppCompatActivity() {
private var allPermissionsGranted = false
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySplashBinding.inflate(layoutInflater)
@@ -83,7 +77,7 @@ class SplashActivity : AppCompatActivity() {
} else {
Toast.makeText(
this,
R.string.permission_grant,
"You must grant permission to access all files to use the app",
Toast.LENGTH_SHORT
).show()
finish()
@@ -145,7 +139,7 @@ class SplashActivity : AppCompatActivity() {
if (allGranted) {
moveToLandingPage()
} else {
Toast.makeText(this, R.string.permission_required, Toast.LENGTH_SHORT).show()
Toast.makeText(this, "All permissions are required to use the app.", Toast.LENGTH_SHORT).show()
finish()
}
}

View File

@@ -1,125 +0,0 @@
package com.example.hpostesting.presentation.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.navigation.findNavController
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.OfflineUserListViewBinding
import org.apache.commons.collections4.MapUtils.getString
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
class OfflineUserListAdapter(private val view: View, private val batLevel: Int) :
RecyclerView.Adapter<OfflineUserListAdapter.OfflineUserListViewHolder>() {
inner class OfflineUserListViewHolder(val binding: OfflineUserListViewBinding) :
RecyclerView.ViewHolder(binding.root)
private val differCallback = object : DiffUtil.ItemCallback<HemoCubeTestData>() {
override fun areItemsTheSame(
oldItem: HemoCubeTestData, newItem: HemoCubeTestData
): Boolean {
return oldItem._id == newItem._id
}
override fun areContentsTheSame(
oldItem: HemoCubeTestData, newItem: HemoCubeTestData
): Boolean {
return oldItem == newItem
}
}
val differ = AsyncListDiffer(this, differCallback)
private val context: Context? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OfflineUserListViewHolder {
return OfflineUserListViewHolder(
OfflineUserListViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)
}
override fun getItemCount(): Int {
return differ.currentList.size
}
override fun onBindViewHolder(holder: OfflineUserListViewHolder, position: Int) {
val userList = differ.currentList[position]
holder.binding.apply {
userID.text = "User ID: ${userList._id}"
bloodGroup.text = "Blood group: ${userList.bloodGroup}"
time.text = "Time: ${userList.incubationTime}"
userCard.setOnClickListener {
if (batLevel < 40) {
Toast.makeText(
view.context,
context?.getString(R.string.low_battery_warning),
Toast.LENGTH_SHORT
).show()
return@setOnClickListener
}
if (userList.testStatus != null) {
if (userList.testStatus!!) {
Toast.makeText(
view.context,
context?.getString(R.string.test_already_conducted),
Toast.LENGTH_SHORT
).show()
} else {
if (userList.incubationTime != "") {
if (isBetween15And30Minutes(userList.incubationTime) < Constants.INCUBATION_TIME_MIN) {
Toast.makeText(
view.context,
context?.getString(R.string.incubation_not_completed),
Toast.LENGTH_SHORT
).show()
} else if (isBetween15And30Minutes(userList.incubationTime) > Constants.INCUBATION_TIME_MAX) {
Toast.makeText(
view.context,
context?.getString(R.string.incubation_crossed_30_minutes),
Toast.LENGTH_SHORT
).show()
} else {
DataHolder.selectedTest = UserData(
_id = userList._id,
bloodGroup = userList.bloodGroup,
incubationTime = userList.incubationTime
)
view.findNavController()
.navigate(R.id.action_nav_home_to_mainActivity)
}
} else {
Toast.makeText(
view.context,
context?.getString(R.string.incubation_not_started),
Toast.LENGTH_SHORT
).show()
}
}
}
}
}
}
private fun isBetween15And30Minutes(createdAt: String): Long {
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
val createdAtDate: Date = formatter.parse(createdAt)!!
val currentTime = Calendar.getInstance().time
val diffMillis = currentTime.time - createdAtDate.time
return diffMillis / (60 * 1000)
}
}

View File

@@ -1,10 +1,6 @@
package com.example.hpostesting.presentation.adapter
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Context
import android.content.Context.INPUT_METHOD_SERVICE
import android.view.inputmethod.InputMethodManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -14,31 +10,17 @@ import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.UserItemViewBinding
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import android.widget.AutoCompleteTextView
import androidx.core.content.ContextCompat.getSystemService
import androidx.core.content.getSystemService
import androidx.fragment.app.FragmentActivity
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.firestore.FirebaseFirestore
class UserListAdapter(
private val context: Context,
private val hemoCubeViewModel: HemoCubeViewModel,
options: FirestoreRecyclerOptions<UserData>,
private val view: View,
private val batLevel: Int,
private val requireActivity: FragmentActivity
) : FirestoreRecyclerAdapter<UserData, UserListAdapter.OrderItemViewHolder>(options) {
private val view: View
) :
FirestoreRecyclerAdapter<UserData, UserListAdapter.OrderItemViewHolder>(options) {
class OrderItemViewHolder(val binding: UserItemViewBinding) :
RecyclerView.ViewHolder(binding.root)
@@ -54,206 +36,27 @@ class UserListAdapter(
holder.binding.apply {
userName.text = "Name: ${model.name}"
userId.text = "User ID:${model._id}"
if (model.incubationTime == "") {
btnBlood.visibility = View.VISIBLE
} else {
userId.text =
"User ID:${model._id} \n Time: ${isBetween15And30Minutes(model.incubationTime)} \n Started at: ${
SimpleDateFormat("HH:mm:ss").format(
SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).parse(model.incubationTime)!!
)
}"
btnBlood.visibility = View.GONE
}
Glide.with(view).load(model.userImageURL).into(userImage)
if (model.testStatus!!) {
teststatus.text = view.context.getString(R.string.test_concluded)
teststatus.text = "Test concluded"
} else {
teststatus.text = view.context.getString(R.string.test_pending)
}
holder.binding.btnBlood.setOnClickListener {
val view: View? = requireActivity.currentFocus
// on below line checking if view is not null.
if (view != null) {
// on below line we are creating a variable
// for input manager and initializing it.
val inputMethodManager =
context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
// on below line hiding our keyboard.
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
}
val inflater = LayoutInflater.from(context)
val dialogView = inflater.inflate(R.layout.dialog_custom, null)
val builder = AlertDialog.Builder(context)
.setView(dialogView)
.setTitle(R.string.blood_group)
val etBloodGroup = dialogView.findViewById<AutoCompleteTextView>(R.id.et_blood_group)
builder.setPositiveButton(R.string.ok) { dialog, which ->
val bloodGroup = etBloodGroup.text.toString()
if (bloodGroup.equals("Select Blood Group") ||bloodGroup.equals("ರಕ್ತ ಗುಂಪು ಆಯ್ಕೆಮಾಡಿ") || bloodGroup.isNullOrBlank()) {
if (view != null) {
etBloodGroup.error =view.context.getString(R.string.blood_group_error)
}
if (view != null) {
Toast.makeText(context, view.context.getString(R.string.blood_group_toast), Toast.LENGTH_SHORT).show()
}
} else {
// Check if hemoCubeViewModel and testDetails are not null
val db: FirebaseFirestore = FirebaseFirestore.getInstance()
db.collection("patientData")
.whereEqualTo("_id", model._id)
.get()
.addOnSuccessListener { userdata ->
try {
val document = userdata.documents[0]
db.collection("patientData")
.document(document.id)
.update("bloodGroup", bloodGroup,
"incubationTime", SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time).toString()
)
.addOnSuccessListener {
if (view != null) {
Toast.makeText(
view.context,
context?.getString(R.string.blood_group_updated_successfully),
Toast.LENGTH_SHORT
).show()
}
btnBlood.visibility = View.GONE
}
.addOnFailureListener { e ->
if (view != null) {
Toast.makeText(
view.context,
context?.getString(R.string.failed_to_update_blood_group),
Toast.LENGTH_SHORT
).show()
}
}
} catch (e: IndexOutOfBoundsException) {
// Handle the case where no documents are found for the specified ID
if (view != null) {
Toast.makeText(
view.context,
context?.getString(R.string.no_user_data_found),
Toast.LENGTH_SHORT
).show()
}
}
}
.addOnFailureListener { e ->
Toast.makeText(
context,
"Error fetching user data: ${e.message}",
Toast.LENGTH_SHORT
).show()
}
}
// Handle the selected blood group here
}
builder.setNegativeButton(R.string.cancel) { dialog, which ->
dialog.dismiss()
}
val alertDialog = builder.create()
alertDialog.show()
}
btnStartIncubation.setOnClickListener {
// it.visibility = View.GONE
// Firebase.firestore.collection("patientData").whereEqualTo("_id", model._id).get()
// .addOnSuccessListener { data ->
// if (data.documents.isNotEmpty()) {
// data.documents.forEach { userData ->
// Firebase.firestore.collection("patientData").document(userData.id)
// .update(
// "incubationTime", SimpleDateFormat(
// "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
// ).format(Calendar.getInstance().time).toString()
// ).addOnSuccessListener {
// Toast.makeText(
// view.context, "Incubation started", Toast.LENGTH_SHORT
// ).show()
// startListening()
// }
// }
// }
// }
teststatus.text = "Test is Pending"
}
userCard.setOnClickListener {
if (false) {
Toast.makeText(
view.context,
context?.getString(R.string.low_battery_warning),
Toast.LENGTH_SHORT
).show()
return@setOnClickListener
}
if (model.testStatus != null) {
if (model.testStatus!!) {
Toast.makeText(
view.context,
context?.getString(R.string.test_already_conducted),
Toast.LENGTH_SHORT
).show()
} else {
if (model.incubationTime != "") {
if (isBetween15And30Minutes(model.incubationTime) < 15) {
Toast.makeText(
view.context,
context?.getString(R.string.incubation_not_completed),
Toast.LENGTH_SHORT
).show()
} else if (isBetween15And30Minutes(model.incubationTime) > 30) {
Toast.makeText(
view.context,
context?.getString(R.string.incubation_crossed_30_minutes),
"Test has been already conducted for this user",
Toast.LENGTH_SHORT
).show()
} else {
DataHolder.selectedTest = model
view.findNavController()
.navigate(R.id.action_nav_home_to_mainActivity)
}
} else {
Toast.makeText(
view.context,
context?.getString(R.string.incubation_not_started),
Toast.LENGTH_SHORT
).show()
view.findNavController().navigate(R.id.action_nav_home_to_mainActivity)
}
}
}
}
}
}
private fun isBetween15And30Minutes(createdAt: String): Long {
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
val createdAtDate: Date = formatter.parse(createdAt)!!
val currentTime = Calendar.getInstance().time
val diffMillis = currentTime.time - createdAtDate.time
return diffMillis / (60 * 1000)
}
}

View File

@@ -1,354 +0,0 @@
package com.example.hpostesting.presentation.buffercheck
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import kotlin.math.log10
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
class HemoCubeBufferCheckFragment : Fragment() {
private lateinit var binding: FragmentHemoCubeReferenceBinding
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences
private var currentDeviceData: DeviceData? = null
private var resultData: String = ""
private var kitno: String = ""
private var isOnline = false
private val messages = MutableLiveData<String>()
private var isTestOngoing = false
private var startListening = MutableLiveData(false)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View {
binding = FragmentHemoCubeReferenceBinding.inflate(inflater, container, false)
sharedPreferences =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViews()
observeViewModel()
}
private fun initViews() {
binding.nameEditText.setText("SMI/SC/")
binding.tvTitle.visibility = View.GONE
binding.tvName.visibility = View.GONE
binding.btnGo.setOnClickListener {
val serialNumber = binding.nameEditText.text.toString().trim()
if (serialNumber.isNotEmpty() && isSerialValid(serialNumber)) {
kitno = serialNumber
listenToHemoCube()
startBufferProcess()
} else {
Toast.makeText(context, R.string.invalid_kit_number, Toast.LENGTH_LONG).show()
return@setOnClickListener
}
activity?.runOnUiThread {
binding.tvSubtitle2.visibility = View.GONE
binding.etAbhaId.visibility = View.GONE
binding.tvTitle.visibility = View.GONE
binding.tvTitle2.visibility = View.GONE
binding.btnGo.visibility = View.GONE
}
}
activity?.runOnUiThread {
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
}
binding.btnSubmit.setOnClickListener {
}
binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false
}
private fun observeViewModel() {
hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) {
currentDeviceData = it
}
hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
if (isNetworkAvailable) {
hemoCubeViewModel.getDeviceData(sharedPreferences.getString(Constants.USER_ID, ""))
} else {
Toast.makeText(
requireContext(), R.string.internt_not, Toast.LENGTH_SHORT
).show()
}
isOnline = isNetworkAvailable
}
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
showToast(R.string.kit_uploaded)
}
if (result == "Local") {
showToast(R.string.kit_upload_failed)
}
binding.progressBar.visibility = View.GONE
}
messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it
}
}
private fun listenToHemoCube() {
if (DataHolder.hemoCubeTestData == null) {
DataHolder.hemoCubeTestData = DataHolder.selectedTest?.toHemoCubeTestData()
}
val fullReadOutput = StringBuilder()
startListening.postValue(true)
try {
(activity as HemocubeBufferCheckActivity).mService.listenToHemoCube(object :
UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
fullReadOutput.append(stringData)
handleUsbData(stringData, fullReadOutput)
}
}
override fun onUsbError(e: Exception?) {
}
})
} catch (e: Exception) {
showToast(R.string.test_ongoing)
Firebase.crashlytics.recordException(e)
}
}
private fun handleUsbData(stringData: String, fullReadOutput: StringBuilder) {
if (stringData.contains("#")) {
messages.postValue(stringData)
isTestOngoing = true
}
resultData += fullReadOutput.toString()
when {
stringData.contains("#Buffer Completed") -> showStartSampleDialog()
stringData.contains("#Sample Completed") -> {
activity?.runOnUiThread {
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
}
fetchResult()
}
stringData.contains("RESULT") || resultData.contains("REND") -> {
var validString: String
val results: List<String>
if (stringData.contains("RESULT")) {
validString = isValidResult(stringData)
if (validString.isEmpty()) {
results = resultData.split("\n")
validString = parseResult(results)
}
} else {
results = resultData.split("\n")
validString = parseResult(results)
}
if (validString.isNotEmpty()) {
handleValidResult(validString)
}
}
}
}
private fun showStartSampleDialog() {
activity?.runOnUiThread {
UIUtils.createAlertDialog(requireContext(),
"Start Sample",
"Do you want to start sample reading?",
getString(R.string.no),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
listenToHemoCube()
startSampleProcess()
}
})
}
}
private fun handleValidResult(validString: String) {
try {
val result = validString.split(" ")
if (result.size == 8) {
val deviceId = result[2]
val led1BufferForDevice = result[3].toDoubleOrNull()
val led2BufferForDevice = result[4].toDoubleOrNull()
val led1Sample = result[5].toDoubleOrNull()
val led2Sample = result[6].toDoubleOrNull()
val led1Average = log10(led1BufferForDevice?.div(led1Sample!!) ?: 0.0)
val led2Average = log10(led2BufferForDevice?.div(led2Sample!!) ?: 0.0)
val deviceRatio = led1Average / led2Average
val calculateRatio = calculateRatio(deviceRatio)
val classificationResult = findResult(calculateRatio)
messages.postValue(classificationResult)
val bufferData = BufferCheckData(
deviceId= deviceId,
kitno = kitno,
led1Buffer = led1BufferForDevice,
led2Buffer = led2BufferForDevice,
led1Average = led1Average,
led2Average = led2Average,
led1Sample = led1Sample,
led2Sample = led2Sample,
deviceRatio = deviceRatio,
calculatedRatio = calculateRatio,
coefficients = currentDeviceData?.coefficients?.get(0).toString() + ", " + currentDeviceData?.coefficients?.get(1).toString(),
classificationResult = classificationResult,
deviceSerialNumber = sharedPreferences.getString(Constants.USER_ID, "").toString(),
testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
)
hemoCubeViewModel.uploadHemoCubeResultToDatabaseforbuffercheckN(bufferData)
}
} catch (e: Exception) {
Toast.makeText(
requireContext(), "Error while processing device data", Toast.LENGTH_SHORT
).show()
Firebase.crashlytics.recordException(e)
}
}
private fun findResult(calculatedRatio: Double?): String {
try {
if (calculatedRatio != null) {
if (calculatedRatio < 0.085) return "Kit Failed"
if (calculatedRatio in 0.085..0.155) return "Kit Passed"
if (calculatedRatio in 0.155..0.175) return "Kit Failed"
if (calculatedRatio in 0.175..0.22) return "Kit Failed"
if (calculatedRatio in 0.22..0.25) return "Kit Failed"
if (calculatedRatio in 0.25..0.35) return "Kit Failed"
if (calculatedRatio > 0.35) return "Kit Failed"
} else {
return "NULL"
}
} catch (e: Exception) {
showToast(R.string.error_classification)
Firebase.crashlytics.recordException(e)
return "ERROR"
}
return "NULL"
}
private fun showToast(messageResId: Int) {
Toast.makeText(requireContext(), getString(messageResId), Toast.LENGTH_SHORT).show()
}
private fun startBufferProcess() {
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startBuffer,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
}
})
}
private fun startSampleProcess() {
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startSample,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
}
})
}
private fun fetchResult() {
(activity as HemocubeBufferCheckActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.getSample,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
}
})
}
private fun calculateRatio(ratio: Double): Double {
val coefficient1 = currentDeviceData?.coefficients?.get(0) ?: 0.0
val coefficient2 = currentDeviceData?.coefficients?.get(1) ?: 1.0
return coefficient1 * ratio + coefficient2
}
private fun parseResult(frames: List<String>): String {
val lines = mutableListOf<String>()
for (frame in frames.reversed()) {
if (frame.contains("REND") || frame.contains("RESULT")) lines += frame
if (frame.contains("RESULT")) {
break
}
}
val line = lines.reversed().joinToString("").trim()
if (line.contains("RESULT") && line.split(" ").size == 8) {
return line
}
return ""
}
private fun isSerialValid(s: String): Boolean {
if (s.length != 17) {
binding.nameEditText.error = getString(R.string.invalid_kit)
return false
}
return true
}
private fun isValidResult(line: String): String {
return if (line.contains("RESULT") && line.split(" ").size == 8) {
line
} else {
""
}
}
}

View File

@@ -1,171 +0,0 @@
package com.example.hpostesting.presentation.buffercheck
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.ServiceConnection
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import android.view.Menu
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityHemocubeBinding
@AndroidEntryPoint
open class HemocubeBufferCheckActivity : AppCompatActivity() {
private lateinit var binding: ActivityHemocubeBinding
private val viewModel by viewModels<HemoCubeViewModel>()
private var myMenu: Menu? = null
private lateinit var mDriver: UsbSerialDriver
private var mConnection: UsbDeviceConnection? = null
lateinit var mService: UsbService
private val TAG = "HemoCube"
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
synchronized(this) {
val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
device?.apply {
connectUsb(true)
DataHolder.usbConnected.postValue(true)
}
} else {
DataHolder.usbConnected.postValue(true)
}
}
}
}
private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as UsbService.UsbServiceBinder
mService = binder.getService()
viewModel.isServiceConnected = true
mConnection.let { mService.connect(mDriver, mConnection!!) }
moveToNext()
}
override fun onServiceDisconnected(arg0: ComponentName) {
viewModel.isServiceConnected = false
}
}
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHemocubeBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.myToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
setupListener()
connectUsb(false)
}
private fun setupListener() {
DataHolder.usbConnected.observe(this) {
Log.d("USB OBSERVE", "HemoCube called -> $it")
if (it) {
myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24)
} else {
myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
Toast.makeText(this, R.string.device_disconnected, Toast.LENGTH_SHORT).show()
}
}
}
open fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager
val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager)
if (availableDrivers.isEmpty()) {
Toast.makeText(this, R.string.no_device_found, Toast.LENGTH_SHORT).show()
} else {
mDriver = availableDrivers[0]
mConnection = manager.openDevice(mDriver.device)
if (mConnection == null) {
requestUserPermission(manager, mDriver.device)
} else {
setupService()
}
}
}
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
PendingIntent.getBroadcast(
this, 0, Intent(Constants.HOMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
)
} else {
PendingIntent.getBroadcast(
this,
0,
Intent(Constants.HOMOCUBE_USB_PERMISSION),
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
)
}
val filter = IntentFilter(Constants.HOMOCUBE_USB_PERMISSION)
registerReceiver(broadcastReceiver, filter)
manager.requestPermission(device, mPendingIntent)
}
private fun setupService() {
val intent = Intent(this, UsbService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return
supportFragmentManager.beginTransaction().replace(binding.fghemocube.id, HemoCubeBufferCheckFragment())
.commit()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.my_menu, menu)
return true
}
override fun onDestroy() {
super.onDestroy()
if (viewModel.isServiceConnected) {
mService.disconnect()
unbindService(connection)
viewModel.isServiceConnected = false
}
}
}

View File

@@ -1,10 +1,7 @@
package com.example.hpostesting.presentation.dashboard
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.drawerlayout.widget.DrawerLayout
import androidx.navigation.findNavController
@@ -12,45 +9,24 @@ import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.NatsManager
import com.google.android.material.navigation.NavigationView
import com.google.android.material.progressindicator.LinearProgressIndicator
import com.google.android.play.core.appupdate.AppUpdateManager
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
import com.google.firebase.appdistribution.FirebaseAppDistribution
import com.google.firebase.appdistribution.FirebaseAppDistributionException
import com.google.firebase.crashlytics.FirebaseCrashlytics
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
open interface IDataCollector {
fun setConnect(connect: Boolean)
fun setResponse(response: String)
}
@AndroidEntryPoint
class DashboardActivity : AppCompatActivity(), IDataCollector {
class DashboardActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityDashboardBinding
var responses: String = ""
lateinit var nats: NatsManager
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDashboardBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.appBarDashboard.toolbar)
nats = NatsManager(this)
// nats.connect()
// nats.pub("server.hpos.HCV-000-3001.ping", "THIS IS A TEST MSG")
val drawerLayout: DrawerLayout = binding.drawerLayout
val navView: NavigationView = binding.navView
@@ -77,55 +53,4 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
override fun onResume() {
super.onResume()
val firebaseAppDistribution = FirebaseAppDistribution.getInstance()
firebaseAppDistribution.updateIfNewReleaseAvailable()
.addOnProgressListener { updateProgress ->
if (updateProgress.apkBytesDownloaded > 0) {
Toast.makeText(
this,
"${updateProgress.updateStatus}. ${updateProgress.apkBytesDownloaded / 1048576} /${updateProgress.apkFileTotalBytes / 1048576} MB",
Toast.LENGTH_SHORT
).show()
}
}
.addOnFailureListener { e ->
// (Optional) Handle errors.
if (e is FirebaseAppDistributionException) {
when (e.errorCode) {
FirebaseAppDistributionException.Status.NOT_IMPLEMENTED -> {
// SDK did nothing. This is expected when building for Play.
}
else -> {
// Handle other errors.
Toast.makeText(
this,
"AppDistribution error, status: ${e.errorCode}",
Toast.LENGTH_SHORT
).show()
}
}
FirebaseCrashlytics.getInstance().recordException(e)
}
}
.addOnSuccessListener {
// Toast.makeText(this, "App Update: Success!", Toast.LENGTH_SHORT).show()
}
}
override fun setConnect(connect: Boolean) {
if(connect){
Log.i("NATS Connection", connect.toString())
}
}
override fun setResponse(response: String) {
responses = responses+response+"\n"
println(responses)
}
}

View File

@@ -1,13 +1,12 @@
package com.example.hpostesting.presentation.dashboard
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.hpostesting.presentation.buffercheck.HemocubeBufferCheckActivity
import com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity
import androidx.lifecycle.ViewModelProvider
//import com.example.hpostesting.presentation.dashboard.ui.gallery.GalleryViewModel
import `in`.sminnovations.hpostesting.databinding.FragmentGalleryBinding
class GalleryFragment : Fragment() {
@@ -33,15 +32,6 @@ class GalleryFragment : Fragment() {
// galleryViewModel.text.observe(viewLifecycleOwner) {
//// textView.text = it
// }
binding.btnSubmit.setOnClickListener {
startActivity(Intent(requireContext(), HemocubeBufferCheckActivity::class.java))
}
binding.btnDiagnostics.setOnClickListener {
startActivity(Intent(requireContext(), DiagnosticsActivity::class.java))
}
return root
}

View File

@@ -2,13 +2,9 @@ package com.example.hpostesting.presentation.dashboard
import android.app.AlertDialog
import android.content.Context
import android.content.Context.BATTERY_SERVICE
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import android.os.BatteryManager
import android.os.Bundle
import android.util.Base64
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -17,31 +13,18 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.login.LoginRequest
import com.example.hpostesting.data.model.login.LoginResponse
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.updates.CheckUpdateRequest
import com.example.hpostesting.presentation.KitScanActivity
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 com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.firestore.Query
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.google.firebase.perf.ktx.performance
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
@AndroidEntryPoint
@@ -51,11 +34,6 @@ class HomeFragment : Fragment() {
private val viewModel: TestRightViewModel by activityViewModels()
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var rvAdapter: UserListAdapter
private var batLevel: Int =
0 // Initialize with a default value, or obtain the actual battery level
private lateinit var adapter: OfflineUserListAdapter
private lateinit var sharedPreference: SharedPreferences
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
@@ -69,33 +47,21 @@ class HomeFragment : Fragment() {
return super.onCreateView(inflater, container, savedInstanceState)
}
sharedPreference =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
sharedPreference = requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
DataHolder.selectedTest = null
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.allUserData.observe(viewLifecycleOwner) { userData ->
if (userData.isNotEmpty()) {
}
deleteIncompleteRegistrations(userData)
}
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData ->
deleteHemoCubeIncompleteRegistrations(userData)
if (userData.isNotEmpty()) {
val userList = mutableListOf<HemoCubeTestData>()
userData.forEach {
if (it.testStatus == false) {
userList.add(it)
}
}
val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager
val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
adapter = OfflineUserListAdapter(binding.root, batLevel)
adapter.differ.submitList(userList)
binding.rvOrderOffline.adapter = adapter
}
}
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isConnected ->
if (isConnected) {
@@ -104,182 +70,26 @@ class HomeFragment : Fragment() {
loadUserData()
setSearch()
checkForLocalDBData()
checkForTokenAndUpdate()
} else {
binding.internetAvailableCL.visibility = View.GONE
binding.internetNotAvailableCL.visibility = View.VISIBLE
setUserId()
}
}
hemoCubeViewModel.fireBaseBulkUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
Toast.makeText(
requireContext(), R.string.test_upload, Toast.LENGTH_SHORT
).show()
}
if (result == "Error") {
Toast.makeText(requireContext(), R.string.test_upload_failed, Toast.LENGTH_SHORT)
.show()
}
}
binding.btnLogout.setOnClickListener {
logoutUser(requireContext())
}
binding.uploadData.setOnClickListener {
showUploadDialog(requireContext())
}
binding.btnNewKit.setOnClickListener {
with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "")
putInt(Constants.KIT_COUNT, 0)
apply()
}
startActivity(Intent(requireContext(), KitScanActivity::class.java))
requireActivity().finish()
}
}
private fun checkForTokenAndUpdate() {
val accessToken = sharedPreference.getString(Constants.ACCESS_TOKEN, "").toString()
val natsToken = sharedPreference.getString(Constants.NATS_TOKEN, "").toString()
val natsTokenExpireDate = sharedPreference.getString(Constants.NATS_TOKEN_EXPIRE_DATE, "").toString()
if (accessToken.isEmpty() && natsToken.isEmpty()) {
hemoCubeViewModel.login(createLoginRequestData())
} else {
if (isTokenExpired(accessToken)) {
hemoCubeViewModel.login(createLoginRequestData())
} else {
hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData())
hemoCubeViewModel.uploadLogs()
hemoCubeViewModel.startPeriodicCheckUpdate()
}
}
hemoCubeViewModel.loginResponse.observe(viewLifecycleOwner) { response ->
when (response) {
is Result.Success -> {
updateTokens(response)
checkForTokenAndUpdate()
}
is Result.Error -> {
response.exception.let { message ->
Toast.makeText(activity, "An error occurred: $message", Toast.LENGTH_LONG)
.show()
}
}
is Result.Loading -> {
}
else -> {}
}
}
hemoCubeViewModel.checkUpdate.observe(viewLifecycleOwner) { response ->
when (response) {
is Result.Success -> {
Toast.makeText(
requireContext(), response.data.data?.version, Toast.LENGTH_SHORT
).show()
}
is Result.Error -> {
response.exception.let { message ->
Toast.makeText(activity, "An error occurred: $message", Toast.LENGTH_LONG)
.show()
}
}
is Result.Loading -> {
}
else -> {}
}
}
hemoCubeViewModel.uploadLogs.observe(viewLifecycleOwner) { response ->
when (response) {
is Result.Success -> {
Toast.makeText(
requireContext(),
"Log uploaded ${response.data.data?.filename}",
Toast.LENGTH_SHORT
).show()
}
is Result.Error -> {
response.exception.let { message ->
Toast.makeText(activity, "An error occurred: $message", Toast.LENGTH_LONG)
.show()
}
}
is Result.Loading -> {
}
else -> {}
}
}
}
fun isTokenExpired(token: String): Boolean {
val parts = token.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val decodedPayload = String(Base64.decode(parts[1], Base64.DEFAULT))
val jsonPayload = JSONObject(decodedPayload)
val exp = jsonPayload.optLong("exp", 0)
val currentTimeSeconds = System.currentTimeMillis() / 1000
return exp <= currentTimeSeconds
}
private fun updateTokens(response: Result.Success<LoginResponse>) {
with(sharedPreference.edit()) {
putString(Constants.ACCESS_TOKEN, response.data.data?.accessToken)
putString(Constants.NATS_TOKEN, response.data.data?.deviceUser?.natsToken)
putString(Constants.NATS_TOKEN_EXPIRE_DATE, response.data.data?.deviceUser?.natsTokenExpiry)
apply()
}
}
private fun createLoginRequestData(): LoginRequest {
return LoginRequest(
password = Constants.devicePassword,
serialNumber = Constants.deviceID,
username = Constants.deviceID
)
}
private fun createCheckUpdateRequestData(): CheckUpdateRequest {
val pInfo = requireActivity().packageManager.getPackageInfo(
requireActivity().packageName, 0
)
val version = pInfo.versionName
return CheckUpdateRequest(
currentVersion = version
)
}
private fun setUserId() {
binding.btnSubmit.setOnClickListener {
val userId = binding.userId.text.toString()
val bloodGroup = binding.etBloodGroup.text
if (userId.length >= 18 && !bloodGroup.equals("Select Blood Group") || !bloodGroup.isNullOrBlank()) {
hemoCubeViewModel.addUser(
HemoCubeTestData(
_id = userId,
bloodGroup = bloodGroup.toString(),
incubationTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time).toString()
)
)
// val userData = UserData(_id = userId)
// DataHolder.selectedTest = userData
// findNavController().navigate(R.id.action_nav_home_to_mainActivity)
if (userId.length >= 18) {
val userData = UserData(_id = userId)
DataHolder.selectedTest = userData
findNavController().navigate(R.id.action_nav_home_to_mainActivity)
} else {
val errorMessage = getString(R.string.user_id_error_message)
Toast.makeText(requireContext(), errorMessage, Toast.LENGTH_SHORT).show()
@@ -287,16 +97,8 @@ class HomeFragment : Fragment() {
}
}
}
private fun loadUserData() {
try {
val dateFormat = SimpleDateFormat("yyyy-MM-dd")
val currentDate = Date()
val formattedDate = dateFormat.format(currentDate)
val query = Firebase.firestore.collection("patientData")
.whereGreaterThanOrEqualTo("createdAt", formattedDate)
.orderBy("createdAt", Query.Direction.DESCENDING)
// val query = Firebase.firestore.collection("patientData").whereEqualTo("testStatus", false)
val query = Firebase.firestore.collection("patientData").whereEqualTo("testStatus", false)
query.get().addOnSuccessListener {
if (it.documents.isEmpty()) {
binding.pendingTest.visibility = View.VISIBLE
@@ -307,95 +109,48 @@ class HomeFragment : Fragment() {
val recyclerViewOptions =
FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java)
.build()
val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager
val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
rvAdapter = view?.let {
UserListAdapter(
requireContext(),
hemoCubeViewModel,
recyclerViewOptions,
it,
batLevel,
requireActivity()
)
}!!
rvAdapter = UserListAdapter(recyclerViewOptions, binding.root)
binding.rvOrder.adapter = rvAdapter
rvAdapter.startListening()
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
}
}
private fun saveUserId(userId: String) {
with(sharedPreference.edit()) {
putString(Constants.USER_ID, userId)
apply()
}
}
private fun logoutUser(context: Context) {
val builder = AlertDialog.Builder(context)
builder.setTitle(R.string.log_out)
builder.setMessage(R.string.do_log_out)
builder.setPositiveButton(R.string.yes) { dialog, _ ->
builder.setTitle("Log Out")
builder.setMessage("Do you want to LogOut the Application?")
builder.setPositiveButton("Yes") { dialog, _ ->
saveUserId("")
findNavController().navigate(R.id.action_nav_home_to_loginFragment)
dialog.dismiss()
}
builder.setNegativeButton(R.string.no) { dialog, _ ->
builder.setNegativeButton("No") { dialog, _ ->
dialog.dismiss()
}
val dialog = builder.create()
dialog.show()
}
private fun getData(search: String?, field: String) {
val userSearchTrace = Firebase.performance.newTrace("user_search_trace")
userSearchTrace.start()
search?.replaceFirstChar {
val capitalizedSearch = search?.replaceFirstChar {
if (search.lowercase()
.startsWith(it.lowercase())
) it.titlecase(Locale.getDefault()) else it.toString()
}
val currentDate = Date()
val dateFormat = SimpleDateFormat("yyyyMMdd")
val partition = dateFormat.format(currentDate)
val searchTerm = partition + search
val searchField = field + "Search"
val query =
Firebase.firestore.collection("patientData").orderBy(searchField).startAt(searchTerm)
.endAt(searchTerm + "\uf8ff")
query.get().addOnSuccessListener {
userSearchTrace.stop()
}
val query = Firebase.firestore.collection("patientData").orderBy(field).startAt(search)
.endAt(search + "\uf8ff")
val recyclerViewOptions =
FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java)
.build()
val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager
batLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
rvAdapter = view?.let {
UserListAdapter(
requireContext(),
hemoCubeViewModel,
recyclerViewOptions,
it,
batLevel,
requireActivity()
)
}!!
rvAdapter = UserListAdapter(recyclerViewOptions, binding.root)
binding.rvOrder.adapter = rvAdapter
rvAdapter.startListening()
userSearchTrace.stop()
}
private fun setSearch() {
binding.searchProduct.setOnQueryTextListener(object :
androidx.appcompat.widget.SearchView.OnQueryTextListener {
@@ -407,16 +162,13 @@ class HomeFragment : Fragment() {
binding.aadharIdRadioButton.isChecked -> "aadharId"
else -> null
}
field?.let { getData(query, it) }
false
} else {
loadUserData()
false
}
}
override fun onQueryTextChange(query: String?): Boolean {
return if (!query.isNullOrEmpty()) {
val field = when {
@@ -434,7 +186,6 @@ class HomeFragment : Fragment() {
}
})
}
private fun checkForLocalDBData() {
viewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
val uploadDataVisibility = if (userDataList.isEmpty()) View.GONE else View.VISIBLE
@@ -442,12 +193,10 @@ class HomeFragment : Fragment() {
}
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
val uploadDataVisibility =
if (userDataList.any { !it.localFlag && it.testStatus == true }) View.VISIBLE else View.GONE
val uploadDataVisibility = if (userDataList.isEmpty()) View.GONE else View.VISIBLE
binding.uploadData.visibility = uploadDataVisibility
}
}
private fun showUploadDialog(context: Context) {
val builder = AlertDialog.Builder(context)
builder.setTitle(R.string.upload_db_registration_title)
@@ -476,19 +225,28 @@ class HomeFragment : Fragment() {
}
dialog.dismiss()
Toast.makeText(
requireContext(), R.string.upload_success_message, Toast.LENGTH_SHORT
requireContext(),
R.string.upload_success_message,
Toast.LENGTH_SHORT
).show()
}
}
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
if (userDataList.isEmpty()) {
dialog.dismiss()
} else {
userDataList.forEach { userData ->
if (!userData.localFlag) {
userData.localFlag = true
hemoCubeViewModel.bulkAddResultTestToDb(userData)
}
}
dialog.dismiss()
Toast.makeText(
requireContext(),
R.string.upload_success_message,
Toast.LENGTH_SHORT
).show()
}
}
}
@@ -502,7 +260,7 @@ class HomeFragment : Fragment() {
private fun deleteHemoCubeIncompleteRegistrations(userDataList: List<HemoCubeTestData>) {
userDataList.forEach { userData ->
if (userData._id.isEmpty()) {
if (userData.testTime?.isEmpty() == false) {
hemoCubeViewModel.deleteById(userData._id)
}
}

View File

@@ -1,66 +1,42 @@
package com.example.hpostesting.presentation.dashboard
import android.content.Context
import android.content.pm.PackageManager
import android.os.Bundle
import android.widget.Toast
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.example.hpostesting.data.constant.LanguageManager
import `in`.sminnovations.hpostesting.R
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.example.hpostesting.presentation.dashboard.ui.slideshow.SlideshowViewModel
import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding
private var isLanguageChanged = false
class SlideshowFragment : Fragment() {
class SlideshowFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
val preferenceScreen = preferenceManager.createPreferenceScreen(requireContext())
private var _binding: FragmentSlideshowBinding? = null
val languagePreference = ListPreference(requireContext())
languagePreference.key = "language_preference"
languagePreference.title = getString(R.string.app_language)
languagePreference.summary = getString(R.string.select_language)
languagePreference.entries = arrayOf("English", "Kannada", "Hindi")
languagePreference.entryValues = arrayOf("en", "kn", "hi")
languagePreference.setDefaultValue("en")
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
languagePreference.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, newValue ->
val languageCode = newValue as String
updateLanguage(requireContext(), languageCode)
true
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val slideshowViewModel =
ViewModelProvider(this).get(SlideshowViewModel::class.java)
_binding = FragmentSlideshowBinding.inflate(inflater, container, false)
val root: View = binding.root
// val textView: TextView = binding.textSlideshow
// slideshowViewModel.text.observe(viewLifecycleOwner) {
// textView.text = it
// }
return root
}
preferenceScreen.addPreference(languagePreference)
setPreferenceScreen(preferenceScreen)
// App Version Preference
val appVersionPreference = Preference(requireContext())
appVersionPreference.title = "App Version"
appVersionPreference.summary = getAppVersion(requireContext())
preferenceScreen.addPreference(languagePreference)
preferenceScreen.addPreference(appVersionPreference)
setPreferenceScreen(preferenceScreen)
if (isLanguageChanged) {
Toast.makeText(requireContext(), R.string.language_update, Toast.LENGTH_SHORT).show()
}
}
private fun updateLanguage(context: Context, languageCode: String) {
LanguageManager.persistLanguagePreference(context, languageCode)
LanguageManager.setLocale(context, languageCode)
requireActivity().recreate() // Recreate activity to apply language changes
isLanguageChanged = true
}
private fun getAppVersion(context: Context): String {
return try {
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
pInfo.versionName
} catch (e: PackageManager.NameNotFoundException) {
"N/A"
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -23,8 +23,7 @@ class LoginFragment : Fragment() {
savedInstanceState: Bundle?
): View {
_binding = FragmentLoginBinding.inflate(inflater, container, false)
sharedPreference =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
sharedPreference = requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
return binding.root
}
@@ -48,10 +47,10 @@ class LoginFragment : Fragment() {
performLogin(loginId, password)
} else {
if (loginId.isBlank()) {
binding.loginId.error = R.string.enter_proper_login_id.toString()
binding.loginId.error = "Please enter a proper Login ID"
}
if (password.isBlank()) {
binding.password.error = R.string.enter_proper_password.toString()
binding.password.error = "Please enter a proper password"
}
}
}
@@ -73,10 +72,10 @@ class LoginFragment : Fragment() {
navigateToHomeFragment()
return
} else {
Toast.makeText(requireContext(), R.string.wrong_password, Toast.LENGTH_SHORT).show()
Toast.makeText(requireContext(), "Wrong Password", Toast.LENGTH_SHORT).show()
}
}
Toast.makeText(requireContext(), R.string.wrong_user_id, Toast.LENGTH_SHORT).show()
Toast.makeText(requireContext(), "Wrong UserID", Toast.LENGTH_SHORT).show()
}
private fun saveUserId(userId: String) {

View File

@@ -1,183 +0,0 @@
package com.example.hpostesting.presentation.diagnostics
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.ServiceConnection
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import android.view.Menu
import android.widget.Toast
import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.hemocube.HemoCubeFragment
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDiagnosticsBinding
@AndroidEntryPoint
class DiagnosticsActivity : AppCompatActivity() {
private lateinit var binding: ActivityDiagnosticsBinding
val viewModel: DiagnosticsViewModel by viewModels()
private var myMenu: Menu? = null
private lateinit var mDriver: UsbSerialDriver
private var mConnection: UsbDeviceConnection? = null
lateinit var mService: UsbService
private val TAG = "HemoCube"
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
synchronized(this) {
val device: UsbDevice? = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
device?.apply {
connectUsb(true)
DataHolder.usbConnected.postValue(true)
}
} else {
onErrorReported("permission denied for device")
DataHolder.usbConnected.postValue(true)
}
}
}
}
private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as UsbService.UsbServiceBinder
mService = binder.getService()
viewModel.isServiceConnected = true
mConnection.let { mService.connect(mDriver, mConnection!!) }
moveToNext()
}
override fun onServiceDisconnected(arg0: ComponentName) {
viewModel.isServiceConnected = false
}
}
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDiagnosticsBinding.inflate(layoutInflater)
setContentView(binding.root)
// setSupportActionBar(binding.myToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
setupListener()
connectUsb(false)
}
private fun setupListener() {
DataHolder.usbConnected.observe(this) {
Log.d("USB OBSERVE", "HemoCube called -> $it")
if (it) {
myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24)
} else {
myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
Toast.makeText(this, "Device is Disconnected", Toast.LENGTH_SHORT).show()
}
}
}
open fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager
val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager)
if (availableDrivers.isEmpty()) {
onErrorReported("No Device is Connected")
} else {
mDriver = availableDrivers[0]
mConnection = manager.openDevice(mDriver.device)
if (mConnection == null) {
requestUserPermission(manager, mDriver.device)
} else {
setupService()
}
}
}
fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
if (!isFinishing) onBackPressed()
}
private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return
supportFragmentManager.beginTransaction().replace(binding.fgDiagnostics.id, DiagnosticsFragment())
.commit()
}
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
mPendingIntent = PendingIntent.getBroadcast(
this, 0, Intent(Constants.HOMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
)
} else {
mPendingIntent = PendingIntent.getBroadcast(
this,
0,
Intent(Constants.HOMOCUBE_USB_PERMISSION),
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
)
}
val filter = IntentFilter(Constants.HOMOCUBE_USB_PERMISSION)
registerReceiver(broadcastReceiver, filter)
manager.requestPermission(device, mPendingIntent)
}
fun setupService() {
val intent = Intent(this, UsbService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.my_menu, menu)
return true
}
override fun onDestroy() {
super.onDestroy()
if (viewModel.isServiceConnected) {
mService.disconnect()
unbindService(connection)
viewModel.isServiceConnected = false
}
}
}

View File

@@ -1,197 +0,0 @@
package com.example.hpostesting.presentation.diagnostics
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.UsbServiceListener
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDiagnosticsBinding
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
class DiagnosticsFragment : Fragment() {
private lateinit var binding: FragmentDiagnosticsBinding
private val diagnosticsViewModel: DiagnosticsViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences
private var currentDeviceData: DeviceData? = null
private var resultData: String = ""
private val messages = MutableLiveData<String>()
private var startListening = MutableLiveData(false)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View {
binding = FragmentDiagnosticsBinding.inflate(inflater, container, false)
sharedPreferences =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViews()
observeViewModel()
}
private fun initViews() {
binding.btnSubmit.visibility = View.GONE
listenToHemoCube()
getDeviceId()
binding.btnSubmit.setOnClickListener {
binding.btnSubmit.visibility = View.GONE
runDeviceDiagnostics()
}
}
private fun observeViewModel() {
diagnosticsViewModel.deviceData.observe(viewLifecycleOwner) {
currentDeviceData = it
}
messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it
Log.e("diagnostics",binding.tvSubtitle4.text.toString())
}
diagnosticsViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
showToast("Diagnostics data uploaded successfully")
}
if (result == "Local") {
showToast("Diagnostics uploading failed, note it down manually")
}
binding.progressBar.visibility = View.GONE
}
}
private fun getDeviceId() {
diagnosticsViewModel.progressBar.postValue(true)
(activity as DiagnosticsActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.getDeviceId,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
diagnosticsViewModel.messages.postValue(stringData)
binding.tvSubtitle4.text = stringData
}
}
override fun onUsbError(e: Exception?) {
diagnosticsViewModel.progressBar.postValue(false)
}
})
}
private fun runDeviceDiagnostics() {
diagnosticsViewModel.progressBar.postValue(true)
(activity as DiagnosticsActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.runDiagnostics,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
override fun onUsbError(e: Exception?) {
diagnosticsViewModel.progressBar.postValue(false)
}
})
}
private fun listenToHemoCube() {
val fullReadOutput = StringBuilder()
startListening.postValue(true)
try {
(activity as DiagnosticsActivity).mService.listenToHemoCube(object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
diagnosticsViewModel.messages.postValue(stringData)
fullReadOutput.append(stringData)
resultData += stringData
binding.tvSubtitle4.text = resultData
if (stringData.contains("SN")) {
val slData = stringData.split(" ")
if (slData.size > 1) {
val hardwareId = slData[1].trim()
with(sharedPreferences.edit()) {
putString(Constants.DEVICE_ID, hardwareId)
apply()
}
}
activity?.runOnUiThread {
binding.btnSubmit.visibility = View.VISIBLE
}
}
}
if (resultData.contains("END") || fullReadOutput.contains("END")) {
diagnosticsViewModel.addDiagnosticsDataToDb(DiagnosticsData(
deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString(),
deviceData = resultData,
runTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
))
}
// val inputData = mutableListOf<String>()
// while (true) {
// if (fullReadOutput.toString().lowercase() == "end") {
// break
// }
// inputData.add(fullReadOutput.toString())
// }
//
// val parsedData = parseData(inputData)
// Log.i("D-Data", parsedData.toString())
}
override fun onUsbError(e: Exception?) {
diagnosticsViewModel.progressBar.postValue(false)
}
})
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
}
}
fun parseData(inputData: List<String>): List<Pair<String, String>> {
val pattern = Regex("([A-Z]+)\\s(\\d+)")
val parsedData = mutableListOf<Pair<String, String>>()
for (item in inputData) {
val matchResult = pattern.find(item)
if (matchResult != null) {
val (letters, numbers) = matchResult.destructured
parsedData.add(Pair(letters, numbers))
}
}
return parsedData
}
private fun showToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
}

View File

@@ -1,65 +0,0 @@
package com.example.hpostesting.presentation.diagnostics
import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.data.repository.DatabaseRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import javax.inject.Inject
@HiltViewModel
class DiagnosticsViewModel @Inject constructor(
private val hemoCubeDao: HemoCubeDao,
private val repository: DatabaseRepository,
context: Context
) : ViewModel() {
var isServiceConnected = false
val progressBar = MutableLiveData(false)
val messages = MutableLiveData<String>()
private val sharedPreference: SharedPreferences =
context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
private val _networkStatusLiveData = NetworkStatusLiveData(context)
val allUserData = hemoCubeDao.getAll()
val deviceData = MutableLiveData<DeviceData?>()
val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData
val fireBaseUpload = MutableLiveData<String>()
fun addDiagnosticsDataToDb(data: DiagnosticsData) {
viewModelScope.launch {
try {
when (val response = repository.addDiagnostics(data)) {
is Response.Success -> {
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
}
is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
}
}
} catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Error")
}
}
}
}

View File

@@ -1,47 +0,0 @@
package com.example.hpostesting.presentation.hemocube
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.IBinder
import android.view.Menu
import androidx.activity.viewModels
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDigitalCardBinding
import `in`.sminnovations.hpostesting.databinding.ActivityHemocubeBinding
class DigitalCardActivity : AppCompatActivity() {
private lateinit var binding: ActivityDigitalCardBinding
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDigitalCardBinding.inflate(layoutInflater)
setContentView(binding.root)
moveToNext()
}
private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return
supportFragmentManager.beginTransaction().replace(binding.fghemocube.id, DigitalCardFragment())
.commit()
}
}

View File

@@ -1,83 +0,0 @@
package com.example.hpostesting.presentation.hemocube
import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
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.DataHolder
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentDigitalCardBinding
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
class DigitalCardFragment : Fragment() {
private lateinit var binding: FragmentDigitalCardBinding
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences
private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
): View {
binding = FragmentDigitalCardBinding.inflate(inflater, container, false)
sharedPreferences =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViews()
}
@SuppressLint("SetTextI18n")
private fun initViews() {
activity?.runOnUiThread {
binding.progressBar.visibility = View.VISIBLE
}
Log.d("DigitalCardFragment", "Name: ${DataHolder.hemoCubeTestData?.name}")
Log.d("DigitalCardFragment", "DOB: ${testDetails?.birthYear}")
Log.d("DigitalCardFragment", "Gender: ${testDetails?.gender}")
Log.d("DigitalCardFragment", "State: ${testDetails?.state}")
Log.d("DigitalCardFragment", "ABHA ID: ${testDetails?.abhaId}")
Log.d("DigitalCardFragment", "Blood Group: ${testDetails?.bloodGroup}")
Log.d("DigitalCardFragment", "Sickle-Cell: ${testDetails?.classificationResult}")
// Log.d("DigitalCardFragment", "Issue Date: $formattedDate")
activity?.runOnUiThread {
binding.progressBar.visibility = View.GONE
binding.name.text = "Name: ${DataHolder.hemoCubeTestData?.name}"
binding.dob.text = "DOB: ${testDetails?.birthYear}"
binding.gender.text = "Gender: ${testDetails?.gender}"
binding.State.text = "State: ${testDetails?.state}"
binding.abhaid.text = "ABHA ID: ${testDetails?.abhaId}"
binding.blood.text = "Blood Group: ${testDetails?.bloodGroup}"
binding.sicklecell.text = "Sickle-Cell: ${DataHolder.hemoCubeTestData?.prdClassification.toString()}"
}
// Update the UI with the fetched details
val originalDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
val originalDate: Date? = originalDateFormat.parse(SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time))
// Format the parsed date to "mm date, year"
val desiredDateFormat = SimpleDateFormat("MMM dd, yyyy", Locale.getDefault())
val formattedDate: String = originalDate?.let { desiredDateFormat.format(it) } ?: "N/A"
activity?.runOnUiThread {
binding.issueDate.text = "Issue Date: ${formattedDate}"
}
}
}

View File

@@ -1,110 +1,51 @@
package com.example.hpostesting.presentation.hemocube
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.os.BatteryManager
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.HemoCubeDao
import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionRequest
import com.example.hpostesting.data.model.deviceprovision.DeviceProvisionResponse
import com.example.hpostesting.data.model.log.UploadLogsResponse
import com.example.hpostesting.data.model.login.LoginRequest
import com.example.hpostesting.data.model.login.LoginResponse
import com.example.hpostesting.data.model.molbioresult.MolbioV2Result
import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultRequest
import com.example.hpostesting.data.model.molbioresult.MolbioV2ResultResponse
import com.example.hpostesting.data.model.patient.BufferCheckData
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.data.model.updates.CheckUpdateRequest
import com.example.hpostesting.data.model.updates.CheckUpdateResponse
import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpostesting.data.repository.Repository
import com.example.hpostesting.domain.CheckUpdateWorker
import com.example.hpostesting.domain.LogFileManager
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.ResponseBody
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@HiltViewModel
class HemoCubeViewModel @Inject constructor(
private val hemoCubeDao: HemoCubeDao,
private val repository: Repository,
private val databaseRepository: DatabaseRepository,
private val logFileManager: LogFileManager,
context: Context
private val repository: DatabaseRepository,
context: Context,
) : ViewModel() {
var isServiceConnected = false
val progressBar = MutableLiveData(false)
private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
val messages = MutableLiveData<String>()
private val sharedPreference: SharedPreferences =
context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
private val workManager = WorkManager.getInstance(context)
// init {
// startPeriodicCheckUpdate()
// }
val deviceProvisionResponse = MutableLiveData<Result<DeviceProvisionResponse>>()
val loginResponse = MutableLiveData<Result<LoginResponse>>()
val resultUpload = MutableLiveData<Result<MolbioV2ResultResponse>>()
val checkUpdate = MutableLiveData<Result<CheckUpdateResponse>>()
val deviceUpdate = MutableLiveData<Result<ResponseBody>>()
val uploadLogs = MutableLiveData<Result<UploadLogsResponse>?>()
private val sharedPreference: SharedPreferences = context.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
// Get the device ID of the device you want to retrieve data for (e.g., the first device in the list)
private val _networkStatusLiveData = NetworkStatusLiveData(context)
val allUserData = hemoCubeDao.getAll()
val deviceData = MutableLiveData<DeviceData?>()
val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData
val deviceMessages = MutableLiveData<String?>()
val fireBaseUpload = MutableLiveData<String>()
val fireBaseBulkUpload = MutableLiveData<String>()
private val batteryStatus: Intent? =
IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
context.registerReceiver(null, ifilter)
}
fun uploadHemoCubeResultToDatabase(
isOnline: Boolean, testStatus: Boolean, kitSerial: String?
) = viewModelScope.launch {
fun uploadHemoCubeResultToDatabase(isOnline: Boolean, testStatus: Boolean, kitSerial: String?) =
viewModelScope.launch {
if (kitSerial != null) {
testDetails?.kitSerial = kitSerial
}
@@ -112,10 +53,8 @@ class HemoCubeViewModel @Inject constructor(
try {
if (isOnline) {
parseData()
addResultTestToDb()
} else {
parseData()
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
@@ -127,75 +66,11 @@ class HemoCubeViewModel @Inject constructor(
}
}
fun deviceProvision(deviceProvisionRequest: DeviceProvisionRequest) = viewModelScope.launch {
deviceProvisionResponse.postValue(Result.Loading())
databaseRepository.deviceProvision(deviceProvisionRequest).let {
deviceProvisionResponse.postValue(it)
}
}
fun login(loginRequest: LoginRequest) = viewModelScope.launch {
loginResponse.postValue(Result.Loading())
databaseRepository.login(loginRequest).let {
loginResponse.postValue(it)
}
}
fun uploadResult(molbioV2ResultRequest: MolbioV2ResultRequest) = viewModelScope.launch {
resultUpload.postValue(Result.Loading())
databaseRepository.uploadResults(molbioV2ResultRequest).let {
resultUpload.postValue(it)
}
}
fun checkUpdate(checkUpdateRequest: CheckUpdateRequest) = viewModelScope.launch {
checkUpdate.postValue(Result.Loading())
databaseRepository.checkUpdate(checkUpdateRequest).let {
checkUpdate.postValue(it)
}
}
fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest) = viewModelScope.launch {
deviceUpdate.postValue(Result.Loading())
databaseRepository.deviceUpdate(deviceUpdateRequest).let {
deviceUpdate.postValue(it)
}
}
fun startPeriodicCheckUpdate() {
val periodicRequest = PeriodicWorkRequestBuilder<CheckUpdateWorker>(
repeatInterval = 1, repeatIntervalTimeUnit = TimeUnit.MINUTES
).build()
workManager.enqueueUniquePeriodicWork(
"checkUpdateWorker", ExistingPeriodicWorkPolicy.KEEP, periodicRequest
)
}
fun uploadLogs() = viewModelScope.launch {
uploadLogs.postValue(Result.Loading())
val logFile = logFileManager.createLogFile().let { file ->
val requestBody = file?.asRequestBody("multipart/form-data".toMediaTypeOrNull())
val multipartFile =
requestBody?.let { MultipartBody.Part.createFormData("logFile", file.name, it) }
multipartFile?.let { partFile ->
databaseRepository.uploadLogs(partFile).let { result ->
uploadLogs.postValue(result)
}
}
}
}
fun uploadHemoCubeResultToDatabaseforbuffercheckN(bufferCheckData: BufferCheckData) =
viewModelScope.launch {
addResultTestToDbforbuffercheck(bufferCheckData)
}
fun getDeviceData(deviceId: String?) = viewModelScope.launch {
deviceData.postValue(deviceId?.let { repository.getDeviceDataById(it) })
}
private fun parseData() {
private fun addResultTestToDb() {
testDetails?.deviceRatio = DataHolder.hemocubeResult
testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString()
testDetails?.location = DataHolder.location
@@ -204,39 +79,17 @@ class HemoCubeViewModel @Inject constructor(
).format(Calendar.getInstance().time)
testDetails?.appVersion = DataHolder.hemoCubeTestData?.appVersion
testDetails?.deviceId = DataHolder.hemoCubeTestData?.deviceId
testDetails?.deviceSerialNumber =
sharedPreference.getString(Constants.USER_ID, "").toString()
testDetails?.deviceSerialNumber = sharedPreference.getString(Constants.USER_ID, "").toString()
testDetails?.kitSerial = sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
testDetails?.led1Buffer = DataHolder.hemoCubeTestData?.led1Buffer
testDetails?.led2Buffer = DataHolder.hemoCubeTestData?.led2Buffer
testDetails?.led3Buffer = DataHolder.hemoCubeTestData?.led3Buffer
testDetails?.led4Buffer = DataHolder.hemoCubeTestData?.led4Buffer
testDetails?.led1Sample = DataHolder.hemoCubeTestData?.led1Sample
testDetails?.led2Sample = DataHolder.hemoCubeTestData?.led2Sample
testDetails?.led3Sample = DataHolder.hemoCubeTestData?.led3Sample
testDetails?.led4Sample = DataHolder.hemoCubeTestData?.led4Sample
testDetails?.led1Average = DataHolder.hemoCubeTestData?.led1Average
testDetails?.led2Average = DataHolder.hemoCubeTestData?.led2Average
testDetails?.led3Average = DataHolder.hemoCubeTestData?.led3Average
testDetails?.led4Average = DataHolder.hemoCubeTestData?.led4Average
testDetails?.abs1 = DataHolder.hemoCubeTestData?.abs1
testDetails?.abs2 = DataHolder.hemoCubeTestData?.abs2
testDetails?.abs3 = DataHolder.hemoCubeTestData?.abs3
testDetails?.abs4 = DataHolder.hemoCubeTestData?.abs4
testDetails?.deviceRatio = DataHolder.hemoCubeTestData?.deviceRatio
testDetails?.predictedDenovixRatio = DataHolder.hemoCubeTestData?.predictedDenovixRatio
testDetails?.calculatedRatio = DataHolder.hemoCubeTestData?.calculatedRatio
testDetails?.coefficients = DataHolder.hemoCubeTestData?.coefficients
testDetails?.classificationResult = DataHolder.hemoCubeTestData?.classificationResult!!
testDetails?.prdClassification = DataHolder.hemoCubeTestData?.prdClassification.toString()
testDetails?.batteryLevel = DataHolder.hemoCubeTestData?.batteryLevel.toString()
testDetails?.batteryCapacity = DataHolder.hemoCubeTestData?.batteryCapacity.toString()
testDetails?.batteryMaxCapacity = DataHolder.hemoCubeTestData?.batteryMaxCapacity.toString()
testDetails?.batteryTemperature = DataHolder.hemoCubeTestData?.batteryTemperature.toString()
testDetails?.batteryVoltage = DataHolder.hemoCubeTestData?.batteryVoltage.toString()
}
private fun addResultTestToDb() {
viewModelScope.launch {
try {
testDetails!!.reportUploadTime = SimpleDateFormat(
@@ -247,64 +100,22 @@ class HemoCubeViewModel @Inject constructor(
is Response.Success -> {
val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0)
with(sharedPreference.edit()) {
putInt(Constants.KIT_COUNT, kitCount.plus(1))
putInt(Constants.KIT_COUNT, kitCount.plus(1) ?: 0)
apply()
}
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
testDetails.localFlag = true
uploadResult(
MolbioV2ResultRequest(
listOf(
MolbioV2Result(
rawData = testDetails,
analysisId = testDetails._id,
analysisDate = testDetails.testTime,
analysisStatus = testDetails.classificationResult,
thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[testDetails.deviceId].toString(),
interpretation = testDetails.classificationResult,
testId = testDetails._id,
testTime = testDetails.testTime,
collectionTime = testDetails.testTime,
expiryTime = testDetails.testTime,
)
)
)
)
hemoCubeDao.insertAll(testDetails)
}
is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
hemoCubeDao.insertAll(testDetails)
}
else -> {}
}
} catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Error")
}
}
}
private fun addResultTestToDbforbuffercheck(bufferCheckData: BufferCheckData) {
viewModelScope.launch {
try {
when (val response = repository.addTestToDatabaseforBufferCheck(bufferCheckData)) {
is Response.Success -> {
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
}
is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response")
Log.e("Testdb", "Error uploading data to Firestore: ${response}")
fireBaseUpload.postValue("Error")
}
else -> {}
else -> {
Log.e("Testdb", "Unknown response from repository: $response")
fireBaseUpload.postValue("Unknown")
}
}
} catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}")
@@ -320,75 +131,15 @@ class HemoCubeViewModel @Inject constructor(
).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(userData)) {
is Response.Success -> {
fireBaseBulkUpload.postValue("Success")
updateLocalFlag(userData._id)
fireBaseUpload.postValue("Success")
}
else -> {
fireBaseBulkUpload.postValue("Error")
else -> {}
}
}
}
}
private fun updateLocalFlag(userId: String) = viewModelScope.launch {
hemoCubeDao.updateFieldById(id = userId, true)
}
fun updateMolbioFlag(userId: String) = viewModelScope.launch {
hemoCubeDao.updateMolbioFlag(id = userId, true)
}
fun addUser(userData: HemoCubeTestData) = viewModelScope.launch {
hemoCubeDao.insertAll(userData)
}
fun deleteById(userId: String) = viewModelScope.launch {
hemoCubeDao.deleteById(id = userId)
}
fun getBatteryLevel(): Float? {
val batteryPct: Float? = batteryStatus?.let { intent ->
val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
level * 100 / scale.toFloat()
}
return batteryPct
}
fun getBatteryTemperature(): Float? {
val batteryTemp: Float? = batteryStatus?.let { intent ->
val temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0)
temperature.toFloat() / 10
}
return batteryTemp
}
fun getBatteryVoltage(context: Context): Float {
val batteryIntent =
context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
val voltage = batteryIntent?.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0) ?: 0
// milli-volts to volts
return voltage.toFloat() / 1000
}
fun getBatteryCapacity(context: Context): Int {
val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER)
}
fun getBatteryMaxCapacity(context: Context): Float {
val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val designCapacity = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
val currentCapacity =
batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER)
// Calculate the estimated maximum battery capacity in mAh
return currentCapacity.toFloat() / designCapacity.toFloat() * 100
}
}

View File

@@ -21,7 +21,6 @@ import androidx.core.content.ContextCompat
import androidx.core.view.get
import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.presentation.testRight.UsbService
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber
@@ -30,7 +29,7 @@ import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityHemocubeBinding
@AndroidEntryPoint
open class HemocubeActivity : AppCompatActivity() {
class HemocubeActivity : AppCompatActivity() {
private lateinit var binding: ActivityHemocubeBinding
private val viewModel by viewModels<HemoCubeViewModel>()
private var myMenu: Menu? = null
@@ -41,6 +40,8 @@ open class HemocubeActivity : AppCompatActivity() {
private val TAG = "HemoCube"
var bloodCollectingMethod = ""
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
@@ -73,17 +74,12 @@ open class HemocubeActivity : AppCompatActivity() {
viewModel.isServiceConnected = false
}
}
override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode)
super.attachBaseContext(newBase)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHemocubeBinding.inflate(layoutInflater)
setContentView(binding.root)
bloodCollectingMethod = intent.getStringExtra(Constants.BLOOD_COLLECTING_METHOD).toString()
setSupportActionBar(binding.myToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
setupListener()
@@ -104,7 +100,7 @@ open class HemocubeActivity : AppCompatActivity() {
}
}
open fun connectUsb(permissionGranted: Boolean) {
private fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager
val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager)
@@ -125,13 +121,15 @@ open class HemocubeActivity : AppCompatActivity() {
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
val mPendingIntent: PendingIntent
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
mPendingIntent = PendingIntent.getBroadcast(
this, 0, Intent(Constants.HOMOCUBE_USB_PERMISSION), PendingIntent.FLAG_MUTABLE
val mPendingIntent: PendingIntent = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
PendingIntent.getBroadcast(
this,
0,
Intent(Constants.HOMOCUBE_USB_PERMISSION),
PendingIntent.FLAG_MUTABLE
)
} else {
mPendingIntent = PendingIntent.getBroadcast(
PendingIntent.getBroadcast(
this,
0,
Intent(Constants.HOMOCUBE_USB_PERMISSION),
@@ -144,39 +142,24 @@ open class HemocubeActivity : AppCompatActivity() {
manager.requestPermission(device, mPendingIntent)
}
fun setupService() {
private fun setupService() {
val intent = Intent(this, UsbService::class.java)
// startService(intent)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
open fun reconnectDevice() {
mService.disconnect()
unbindService(connection)
viewModel.isServiceConnected = false
connectUsb(true)
}
private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return
if (supportFragmentManager.isDestroyed)
return
supportFragmentManager.beginTransaction().replace(binding.fghemocube.id, HemoCubeFragment())
.commit()
supportFragmentManager.beginTransaction()
.replace(binding.fghemocube.id, HemoCubeFragment()).commit()
}
override fun onBackPressed() {
val fragment = supportFragmentManager.findFragmentById(R.id.fghemocube)
if (fragment is HemoCubeFragment) {
fragment.handleBackButtonPress()
} else {
super.onBackPressed()
}
}
fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
if (!isFinishing) onBackPressed()
if (!isFinishing)
onBackPressed()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {

View File

@@ -1,6 +1,5 @@
package com.example.hpostesting.presentation.testRight
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
@@ -15,6 +14,7 @@ import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.test.TestRightResultType
import com.example.hpostesting.data.model.test.TestType
import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.util.MyUtils.calculateAgeFromYOB
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore

View File

@@ -2,6 +2,7 @@ package com.example.hpostesting.presentation.testRight
import android.content.Context
import android.net.Uri
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

View File

@@ -34,7 +34,7 @@ class UsbService : Service() {
fun connect(driver: UsbSerialDriver, connection: UsbDeviceConnection) {
mPort = driver.ports[0] // Most devices have just one port (port 0)
mPort.open(connection)
mPort.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
mPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
isUsbConnected = true
Log.d(TAG, "My Usb Connected ${mPort.driver}")

View File

@@ -1,15 +0,0 @@
package com.example.hpostesting.util
import android.content.res.AssetManager
import com.example.hpostesting.data.api.PropertyProvider
import java.io.InputStream
import java.util.Properties
class PropertyProviderImpl (private val assetManager: AssetManager) : PropertyProvider {
override fun getProperty(key: String): String {
val inputStream: InputStream = assetManager.open("app.properties")
val properties = Properties()
properties.load(inputStream)
return properties.getProperty(key)
}
}

View File

@@ -1,5 +0,0 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#000000" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/black" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -1,5 +0,0 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hpostesting.presentation.BloodCollectingMethodActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:theme="@style/Theme.HPOS.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.HPOS.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<TextView
android:id="@+id/tv_title"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/select_blood_collecting_method"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/app_bar_layout" />
<RadioGroup
android:id="@+id/bloodTypeRadioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title">
<RadioButton
android:id="@+id/venousBloodRadioButton"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/venous_blood" />
<RadioButton
android:id="@+id/fingerPrickBloodRadioButton"
style="@style/title1_1"
android:checked="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/finger_prick_blood" />
</RadioGroup>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/go"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bloodTypeRadioGroup" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_parent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:titleTextColor="#FFFFFF"
android:elevation="4dp"
app:menu="@menu/my_menu"
android:theme="@style/ToolbarTheme"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<FrameLayout
android:id="@+id/fg_hc_buffer_check"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/my_toolbar"
app:layout_constraintBottom_toBottomOf="parent"
tools:context=".presentation.buffercheck.HemocubeBufferCheckActivity">
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_parent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- <androidx.appcompat.widget.Toolbar-->
<!-- android:id="@+id/my_toolbar"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="?attr/actionBarSize"-->
<!-- android:background="?attr/colorPrimary"-->
<!-- app:titleTextColor="#FFFFFF"-->
<!-- android:elevation="4dp"-->
<!-- app:menu="@menu/my_menu"-->
<!-- android:theme="@style/ToolbarTheme"-->
<!-- app:popupTheme="@style/ThemeOverlay.AppCompat.Light"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent"/>-->
<FrameLayout
android:id="@+id/fg_diagnostics"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:context=".presentation.diagnostics.DiagnosticsActivity">
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_parent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:visibility="gone"
android:id="@+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:titleTextColor="#FFFFFF"
android:elevation="4dp"
app:menu="@menu/my_menu"
android:theme="@style/ToolbarTheme"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/fghemocube"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/my_toolbar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<!-- NavHostFragment for navigation -->
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_parent"
android:layout_width="match_parent"
@@ -19,17 +21,21 @@
android:theme="@style/ToolbarTheme"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toTopOf="parent"/>
<FrameLayout
android:id="@+id/fghemocube"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/my_toolbar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/my_toolbar"
app:layout_constraintBottom_toBottomOf="parent"
tools:context=".presentation.hemocube.HemocubeActivity">
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.KitScanActivity">
tools:context="com.example.hpostesting.presentation.KitScanActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"

View File

@@ -18,6 +18,4 @@
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/dashboard_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:padding="16dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_blood_group"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<AutoCompleteTextView
android:id="@+id/et_blood_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/select_blood_group"
android:inputType="none"
android:labelFor="@id/til_blood_group"
app:simpleItems="@array/blood_group" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>

View File

@@ -1,102 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hpostesting.presentation.diagnostics.DiagnosticsFragment">
<!-- <TextView-->
<!-- android:id="@+id/tv_title"-->
<!-- style="@style/title1"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="24dp"-->
<!-- android:text="@string/diagnostics"-->
<!-- android:layout_marginTop="16dp"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent" />-->
<TextView
android:id="@+id/tv_subtitle2"
style="@style/title2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/diagnostics"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_subtitle3"
style="@style/title2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />
<TextView
android:id="@+id/tv_subtitle4"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="380dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:gravity="center"
android:text="Start"
android:textColor="@color/red"
android:textSize="22sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" />
<Button
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:gravity="center"
android:text="Start"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />
<!-- <Button-->
<!-- android:id="@+id/btn_read"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/read"-->
<!-- android:layout_margin="16dp"-->
<!-- android:clickable="false"-->
<!-- app:layout_constraintTop_toBottomOf="@id/btn_set_reference"-->
<!-- app:layout_constraintStart_toStartOf="parent" />-->
<!-- </androidx.constraintlayout.widget.ConstraintLayout>-->
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:elevation="12dp"
android:indeterminate="true"
android:indeterminateDrawable="@drawable/progressbar_drawable"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,242 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
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"
tools:context="com.example.hpostesting.presentation.hemocube.DigitalCardFragment">
<androidx.cardview.widget.CardView
android:id="@+id/userCard"
android:layout_width="match_parent"
android:layout_height="350dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="#C0C0C0"
app:cardCornerRadius="25dp"
app:cardElevation="0dp"
app:layout_constraintTop_toTopOf="parent">
<FrameLayout
android:id="@+id/fragment_container_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@android:color/background_light"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="22dp">
<ImageView
android:id="@+id/userImage"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/karnataka" />
<ImageView
android:id="@+id/userName"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="16dp"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toTopOf="@+id/userImage"
android:src="@drawable/sickle_cell_gov_logo"/>
<ImageView
android:id="@+id/userImage3"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/userName"
app:layout_constraintTop_toTopOf="@+id/userName"
android:src="@drawable/indianoil"/>
<androidx.cardview.widget.CardView
android:id="@+id/userdetails"
android:layout_width="150dp"
android:layout_height="120dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="#FFFFFF"
app:cardCornerRadius="5dp"
app:layout_constraintTop_toBottomOf="@id/userImage"
app:cardElevation="0dp"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/name"
style="@style/title1_1"
android:layout_width="80dp"
android:layout_height="20dp"
android:layout_marginStart="16dp"
android:layout_marginTop="10dp"
android:gravity="center"
android:textColor="@color/black"
android:textSize="10sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/userImage"
android:text="name: Mariya" />
<TextView
android:id="@+id/dob"
style="@style/title1_1"
android:layout_width="80dp"
android:layout_height="20dp"
android:layout_marginStart="16dp"
android:gravity="center"
android:layout_marginTop="30dp"
android:textColor="@color/black"
android:textSize="10sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/name"
app:layout_constraintTop_toBottomOf="@id/name"
android:text="DOB: 1998" />
<TextView
android:id="@+id/gender"
style="@style/title1_1"
android:layout_width="80dp"
android:layout_height="20dp"
android:layout_marginStart="16dp"
android:gravity="center"
android:layout_marginTop="50dp"
android:textColor="@color/black"
android:textSize="10sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/dob"
app:layout_constraintTop_toBottomOf="@id/dob"
android:text="gender: female" />
<TextView
android:id="@+id/State"
style="@style/title1_1"
android:layout_width="130dp"
android:layout_height="20dp"
android:gravity="center"
android:layout_marginTop="70dp"
android:textColor="@color/black"
android:textSize="10sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/gender"
app:layout_constraintTop_toBottomOf="@id/gender"
android:text="State: Kerala" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/userdetails2"
android:layout_width="150dp"
android:layout_marginStart="10dp"
android:layout_height="120dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="#FFFFFF"
app:cardCornerRadius="5dp"
app:layout_constraintTop_toBottomOf="@id/userImage3"
app:layout_constraintStart_toEndOf="@+id/userdetails"
app:cardElevation="0dp">
<TextView
android:id="@+id/abhaid"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginStart="16dp"
android:layout_marginTop="10dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="10sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/userImage3"
android:text="ABHA-ID: XXXX-8734" />
<TextView
android:id="@+id/blood"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginStart="16dp"
android:layout_marginTop="30dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="10sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/userImage3"
android:text="Blood Group: O +ve" />
<TextView
android:id="@+id/sicklecell"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginStart="6dp"
android:layout_marginTop="50dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="10sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/userImage3"
android:text="Sickle-Cell: Normal (HbA)" />
<TextView
android:id="@+id/issueDate"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginStart="16dp"
android:layout_marginTop="70dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="10sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/userImage3"
android:text="Issue Date: Oct 2,2023" />
</androidx.cardview.widget.CardView>
<Button
android:id="@+id/digitalcard"
android:backgroundTint="#00008B"
app:cardBackgroundColor="#00008B"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="20dp"
android:text="@string/digital_card"
android:textColor="@color/white"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/userdetails" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:elevation="12dp"
android:indeterminate="true"
android:indeterminateDrawable="@drawable/progressbar_drawable"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -4,33 +4,19 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hpostesting.presentation.dashboard.GalleryFragment">
tools:context=".presentation.dashboard.GalleryFragment">
<Button
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
<TextView
android:id="@+id/text_gallery"
style="@style/title1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/check_buffer"
android:textColor="@color/white"
android:layout_margin="24dp"
android:textAlignment="center"
android:textSize="20sp"
android:text="@string/to_be_launched_in_next_version_of_the_app"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_diagnostics"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/diagnostics"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_submit" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,187 +0,0 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.hpostesting.presentation.buffercheck.HemoCubeBufferCheckFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_parent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_title"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/Instructions"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_subtitle2"
style="@style/title2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/step4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<!-- <TextView-->
<!-- android:id="@+id/tv_subtitle3"-->
<!-- style="@style/title2"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="24dp"-->
<!-- android:layout_marginTop="16dp"-->
<!-- android:text="@string/step5"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />-->
<TextView
android:id="@+id/tv_name"
style="@style/title2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_submit" />
<TextView
android:id="@+id/tv_subtitle4"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:gravity="center"
android:textColor="@color/red"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />
<!-- <Button-->
<!-- android:visibility="gone"-->
<!-- android:id="@+id/btn_samplestart"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="16dp"-->
<!-- android:layout_marginTop="24dp"-->
<!-- android:clickable="false"-->
<!-- android:text="@string/Start_Sample"-->
<!-- android:textColor="@color/white"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/til_blood_group" />-->
<!-- <Button-->
<!-- android:id="@+id/btn_placebuffer"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="16dp"-->
<!-- android:layout_marginTop="24dp"-->
<!-- android:clickable="false"-->
<!-- android:text="@string/place_buffer"-->
<!-- android:textColor="@color/white"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/btn_submit" />-->
<Button
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/submit"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />
<!-- <com.google.android.material.textfield.TextInputLayout-->
<!-- android:id="@+id/til_blood_group"-->
<!-- style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="24dp"-->
<!-- android:layout_marginTop="16dp"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/tv_subtitle4">-->
<!-- <AutoCompleteTextView-->
<!-- android:id="@+id/et_blood_group"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:hint="@string/select_blood_group"-->
<!-- android:inputType="none"-->
<!-- android:labelFor="@id/til_blood_group"-->
<!-- app:simpleItems="@array/blood_group" />-->
<!-- </com.google.android.material.textfield.TextInputLayout>-->
<!-- <Button-->
<!-- android:id="@+id/btn_kit"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_margin="10dp"-->
<!-- android:text="@string/new_kit"-->
<!-- android:textColor="@color/white"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent" />-->
<!-- <Button-->
<!-- android:id="@+id/btn_buffer"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/new_buffer"-->
<!-- android:textColor="@color/white"-->
<!-- android:layout_margin="10dp"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintEnd_toStartOf="@id/btn_kit"/>-->
<!-- <Button-->
<!-- android:id="@+id/btn_read"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/read"-->
<!-- android:layout_margin="16dp"-->
<!-- android:clickable="false"-->
<!-- app:layout_constraintTop_toBottomOf="@id/btn_set_reference"-->
<!-- app:layout_constraintStart_toStartOf="parent" />-->
<!-- </androidx.constraintlayout.widget.ConstraintLayout>-->
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:elevation="12dp"
android:indeterminate="true"
android:indeterminateDrawable="@drawable/progressbar_drawable"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -27,36 +27,22 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:text="@string/step4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<!-- <TextView-->
<!-- android:id="@+id/tv_subtitle3"-->
<!-- style="@style/title2"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="24dp"-->
<!-- android:layout_marginTop="16dp"-->
<!-- android:text="@string/step5"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />-->
<TextView
android:id="@+id/tv_name"
android:id="@+id/tv_subtitle3"
style="@style/title2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:gravity="center"
android:padding="12dp"
android:layout_marginTop="26dp"
android:textFontWeight="700"
android:text="Name: SMI\n ID: 1672282828"
android:layout_marginTop="16dp"
android:text="@string/step5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints" />
app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />
<TextView
android:id="@+id/tv_subtitle4"
@@ -64,120 +50,15 @@
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="72dp"
android:layout_marginTop="16dp"
android:gravity="center"
android:textColor="@color/red"
android:textSize="18sp"
android:textSize="22sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_abha_id" />
<!-- <Button-->
<!-- android:visibility="gone"-->
<!-- android:id="@+id/btn_samplestart"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="16dp"-->
<!-- android:layout_marginTop="24dp"-->
<!-- android:clickable="false"-->
<!-- android:text="@string/Start_Sample"-->
<!-- android:textColor="@color/white"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/til_blood_group" />-->
<!-- <Button-->
<!-- android:id="@+id/btn_placebuffer"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="16dp"-->
<!-- android:layout_marginTop="24dp"-->
<!-- android:clickable="false"-->
<!-- android:text="@string/place_buffer"-->
<!-- android:textColor="@color/white"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/btn_submit" />-->
<TextView
android:id="@+id/tv_title2"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="48dp"
android:text="@string/enter_kit_serial_number_manually"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/et_abha_id"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toStartOf="@id/btn_go"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title2">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/name_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLength="17"
android:inputType="text"
android:hint="@string/serial_number" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/go"
app:cornerRadius="16dp"
app:layout_constraintBottom_toBottomOf="@id/et_abha_id"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@id/et_abha_id"
app:layout_constraintTop_toTopOf="@id/et_abha_id" />
<Button
android:visibility="gone"
android:id="@+id/btn_samplestart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/Start_Sample"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_placebuffer" />
app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" />
<Button
android:id="@+id/btn_placebuffer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/place_buffer"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_submit" />
<Button
android:visibility="gone"
android:id="@+id/btn_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -188,51 +69,65 @@
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4" />
app:layout_constraintTop_toBottomOf="@id/til_blood_group" />
<TextView
android:id="@+id/error_message"
style="@style/title1_1"
android:visibility="gone"
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_blood_group"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="72dp"
android:gravity="center"
android:textColor="@color/red"
android:textSize="12sp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_submit" />
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4">
<TextView
android:id="@+id/tv_device_messages"
style="@style/title1_1"
android:visibility="gone"
android:layout_width="0dp"
android:layout_height="180dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="72dp"
android:gravity="center"
android:textColor="@color/black"
android:textSize="11sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/error_message" />
<AutoCompleteTextView
android:id="@+id/et_blood_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/select_blood_group"
android:inputType="none"
android:labelFor="@id/til_blood_group"
app:simpleItems="@array/blood_group" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:visibility="gone"
android:id="@+id/btn_digitalCard"
android:id="@+id/btn_kit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="DigitalCard View"
android:layout_margin="10dp"
android:text="@string/new_kit"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/error_message" />
app:layout_constraintStart_toStartOf="parent" />
<!-- <Button-->
<!-- android:id="@+id/btn_buffer"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/new_buffer"-->
<!-- android:textColor="@color/white"-->
<!-- android:layout_margin="10dp"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintEnd_toStartOf="@id/btn_kit"/>-->
<!-- <Button-->
<!-- android:id="@+id/btn_read"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/read"-->
<!-- android:layout_margin="16dp"-->
<!-- android:clickable="false"-->
<!-- app:layout_constraintTop_toBottomOf="@id/btn_set_reference"-->
<!-- app:layout_constraintStart_toStartOf="parent" />-->
<!-- </androidx.constraintlayout.widget.ConstraintLayout>-->
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
@@ -247,6 +142,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -22,7 +22,7 @@
android:id="@+id/internetNotAvailableCL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
android:visibility="gone"
android:padding="24dp">
<TextView
@@ -57,27 +57,6 @@
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_blood_group"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_name">
<AutoCompleteTextView
android:id="@+id/et_blood_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/select_blood_group"
android:inputType="none"
android:labelFor="@id/til_blood_group"
app:simpleItems="@array/blood_group" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_submit"
android:layout_width="match_parent"
@@ -87,18 +66,7 @@
app:cornerRadius="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_blood_group" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_order_offline"
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_submit"
tools:listitem="@layout/offline_user_list_view" />
app:layout_constraintTop_toBottomOf="@+id/til_name" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -106,7 +74,7 @@
android:id="@+id/internetAvailableCL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:visibility="visible"
android:padding="24dp">
<TextView
@@ -226,27 +194,6 @@
app:layout_constraintTop_toBottomOf="@+id/radioGroup"
tools:listitem="@layout/user_item_view"/>
<TextView
android:id="@+id/label"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/new_kit"
app:layout_constraintBottom_toTopOf="@+id/btnNewKit"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnNewKit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:backgroundTint="@color/primary"
android:contentDescription="@string/new_kit"
android:src="@drawable/ic_add"
app:elevation="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -4,6 +4,19 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hpostesting.presentation.dashboard.SlideshowFragment">
tools:context=".presentation.dashboard.SlideshowFragment">
<TextView
android:id="@+id/text_slideshow"
style="@style/title1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:textAlignment="center"
android:textSize="20sp"
android:text="@string/to_be_launched_in_next_version_of_the_app"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,23 +0,0 @@
<!-- language_spinner_preference.xml -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Select Language -->
<TextView
android:id="@+id/textSelectLanguage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Select Language"
android:textStyle="bold"
android:textSize="18sp"/>
<!-- Language Spinner -->
<Spinner
android:id="@+id/languageSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"/>
</LinearLayout>

Some files were not shown because too many files have changed in this diff Show More