Compare commits

..

6 Commits

Author SHA1 Message Date
mohamedkaif356
e9f7513c85 Check negative absorbance 2023-07-20 18:14:12 +05:30
mohamedkaif356
229f79fe24 API call fixed 2023-07-19 16:49:33 +05:30
mohamedkaif356
2bd9f79795 Molbio Data upload error fix 2023-07-18 17:58:27 +05:30
mohamedkaif356
e97d533998 Molbio Data upload 2023-07-18 17:15:01 +05:30
jithu
b461fa0710 api 2023-07-17 17:40:45 +05:30
mohamedkaif356
2e0b0be7f4 Blood group selection 2023-07-17 14:06:32 +05:30
71 changed files with 865 additions and 4174 deletions

8
.gitignore vendored
View File

@@ -1,7 +1,13 @@
*.iml *.iml
.gradle .gradle
/local.properties /local.properties
/.idea /.idea/misc.xml
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store .DS_Store
/build /build
/captures /captures

2
.idea/gradle.xml generated
View File

@@ -7,7 +7,7 @@
<option name="testRunner" value="GRADLE" /> <option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" /> <option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" /> <option name="gradleJvm" value="Embedded JDK" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />

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

@@ -0,0 +1,42 @@
<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 /build
/google-services* /google-services.json
/idea /idea

View File

@@ -6,20 +6,19 @@ plugins {
id 'com.google.gms.google-services' id 'com.google.gms.google-services'
id 'androidx.navigation.safeargs.kotlin' id 'androidx.navigation.safeargs.kotlin'
id 'kotlin-kapt' id 'kotlin-kapt'
id 'com.google.firebase.crashlytics'
} }
//apply plugin: 'kotlin-android' //apply plugin: 'kotlin-android'
android { android {
compileSdk 34 compileSdk 33
namespace 'in.sminnovations.hpostesting' namespace 'in.sminnovations.hpostesting'
defaultConfig { defaultConfig {
applicationId "in.sminnovations.hpostesting" applicationId "in.sminnovations.hpostesting.prod"
minSdk 21 minSdk 21
targetSdk 34 targetSdk 33
versionCode 24 versionCode 2
versionName "2.1.24" versionName "2.0.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -40,40 +39,34 @@ android {
dataBinding { dataBinding {
enabled = true enabled = true
} }
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
buildFeatures { buildFeatures {
viewBinding true viewBinding true
buildConfig = true
}
lint {
abortOnError false
checkReleaseBuilds false
} }
} }
dependencies { dependencies {
implementation 'androidx.core:core-ktx:1.12.0' implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0' implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'
//firebase //firebase
implementation platform('com.google.firebase:firebase-bom:32.1.0') 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' implementation 'com.google.firebase:firebase-firestore-ktx'
implementation 'com.google.firebase:firebase-auth-ktx' implementation 'com.google.firebase:firebase-auth-ktx'
implementation 'com.google.firebase:firebase-storage-ktx' implementation 'com.google.firebase:firebase-storage-ktx'
implementation 'com.firebaseui:firebase-ui-firestore:8.0.2' implementation 'com.firebaseui:firebase-ui-firestore:8.0.2'
implementation 'com.google.android.gms:play-services-auth:20.7.0' implementation 'com.google.android.gms:play-services-auth:20.5.0'
implementation 'com.google.android.gms:play-services-location:21.0.1' 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.gms:play-services-ads-identifier:18.0.1'
implementation 'com.google.android.things:androidthings:1.0'
implementation 'com.google.firebase:firebase-appdistribution:16.0.0-beta10'
implementation("com.google.firebase:firebase-appdistribution-api-ktx:16.0.0-beta10")
// Testing // Testing
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
@@ -81,11 +74,11 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
implementation 'com.opencsv:opencsv:4.6' implementation 'com.opencsv:opencsv:4.6'
implementation 'com.github.mik3y:usb-serial-for-android:3.5.1' implementation 'com.github.mik3y:usb-serial-for-android:3.4.6'
implementation "androidx.fragment:fragment-ktx:1.6.1" implementation "androidx.fragment:fragment-ktx:1.6.0"
// CSV read, write // CSV read, write
implementation 'com.opencsv:opencsv:4.6' implementation 'com.opencsv:opencsv:4.6'
@@ -94,20 +87,20 @@ dependencies {
implementation 'com.journeyapps:zxing-android-embedded:4.3.0' implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
// Google ML Kit usign play services // Google ML Kit usign play services
implementation 'com.google.android.gms:play-services-code-scanner:16.1.0' implementation 'com.google.android.gms:play-services-code-scanner:16.0.0'
//Room //Room
implementation "androidx.room:room-ktx:2.6.0-rc01" implementation "androidx.room:room-ktx:2.6.0-alpha01"
implementation "androidx.room:room-runtime:2.6.0-rc01" implementation "androidx.room:room-runtime:2.6.0-alpha01"
kapt ("androidx.room:room-compiler:2.6.0-rc01") kapt ("androidx.room:room-compiler:2.6.0-alpha01")
//image //image
implementation 'com.github.bumptech.glide:glide:4.13.2' implementation 'com.github.bumptech.glide:glide:4.13.2'
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2' annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
// Navigation Component // Navigation Component
implementation "androidx.navigation:navigation-fragment-ktx:2.7.3" implementation "androidx.navigation:navigation-fragment-ktx:2.7.0-beta01"
implementation "androidx.navigation:navigation-ui-ktx:2.7.3" implementation "androidx.navigation:navigation-ui-ktx:2.7.0-beta01"
//Dagger - Hilt //Dagger - Hilt
implementation "com.google.dagger:hilt-android:2.46" implementation "com.google.dagger:hilt-android:2.46"

View File

@@ -14,10 +14,6 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-feature android:name="android.hardware.usb.host" />
<uses-permission android:name="android.permission.USB_PERMISSION" />
<application <application
android:name="com.example.hpostesting.HPOSTestingApplication" android:name="com.example.hpostesting.HPOSTestingApplication"
android:allowBackup="true" android:allowBackup="true"
@@ -29,32 +25,16 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.HPOSTesting" android:theme="@style/Theme.HPOSTesting"
tools:targetApi="31"> tools:targetApi="31">
<activity
android:name="com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity"
android:exported="false" />
<activity
android:name="com.example.hpostesting.presentation.hemocube.HemocubeActivity"
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.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 <activity
android:name="com.example.hpostesting.presentation.KitScanActivity" android:name="com.example.hpostesting.presentation.KitScanActivity"
android:exported="false"
android:noHistory="true" android:noHistory="true"
android:theme="@style/Theme.HPOS.NoActionBar" /> android:exported="false"
android:theme="@style/Theme.HPOS.NoActionBar"/>
<activity <activity
android:name="com.example.hpostesting.presentation.dashboard.DashboardActivity" android:name="com.example.hpostesting.presentation.dashboard.DashboardActivity"
android:exported="false" android:exported="false"
android:label="@string/title_activity_dashboard" android:label="@string/title_activity_dashboard"
android:screenOrientation="portrait"
android:theme="@style/Theme.HPOS.NoActionBar" /> android:theme="@style/Theme.HPOS.NoActionBar" />
<service <service
@@ -76,10 +56,11 @@
<activity <activity
android:name="com.example.hpostesting.presentation.testRight.TestRightActivity" android:name="com.example.hpostesting.presentation.testRight.TestRightActivity"
android:exported="false" android:exported="false"
android:noHistory="true"
android:parentActivityName="com.example.hpostesting.presentation.MainActivity" android:parentActivityName="com.example.hpostesting.presentation.MainActivity"
android:theme="@style/Theme.HPOS.NoActionBar" android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan"> android:noHistory="true"
android:windowSoftInputMode="adjustPan"
android:theme="@style/Theme.HPOS.NoActionBar">
<!-- <intent-filter> --> <!-- <intent-filter> -->
<!-- <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> --> <!-- <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> -->
@@ -93,6 +74,7 @@
<activity <activity
android:name="com.example.hpostesting.presentation.MainActivity" android:name="com.example.hpostesting.presentation.MainActivity"
android:exported="true" android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<intent-filter> <intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
@@ -107,6 +89,7 @@
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:stateNotNeeded="true" android:stateNotNeeded="true"
tools:replace="android:screenOrientation" /> tools:replace="android:screenOrientation" />
</application> </application>
</manifest> </manifest>

View File

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

View File

@@ -1,7 +1,6 @@
package com.example.hpostesting.data package com.example.hpostesting.data
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.test.TestRightDeviceConstants import com.example.hpostesting.data.model.test.TestRightDeviceConstants
import com.example.hpostesting.data.model.test.TestType import com.example.hpostesting.data.model.test.TestType
@@ -9,8 +8,12 @@ import com.example.hpostesting.data.model.test.TestType
object DataHolder { object DataHolder {
var selectedTestType: TestType = TestType.SICKLECERT var selectedTestType: TestType = TestType.SICKLECERT
val usbConnected = MutableLiveData(true) val usbConnected = MutableLiveData(true)
var mobileUniqueId: String? = null var mobileUniqueId: String? = null
var isStoragePermissionGranted = false
var isAppFolderCreated = false var isAppFolderCreated = false
var appFolderPath = "" var appFolderPath = ""
var isReferenceTaken = false var isReferenceTaken = false
@@ -18,13 +21,20 @@ object DataHolder {
var deviceConstant: TestRightDeviceConstants? = null var deviceConstant: TestRightDeviceConstants? = null
var deviceSerialNumber: String = "ABCD" var deviceSerialNumber: String = "ABCD"
val deviceType = MutableLiveData<String>()
/* Contains wavelength -> pixel no.*/
val wavelengthToPixelArray = ArrayList<Double>() val wavelengthToPixelArray = ArrayList<Double>()
/* (For reference/baseline) Contains pixel no. -> Intensity of light falling on that pixel */
val intensityReferenceArray = ArrayList<Double>() val intensityReferenceArray = ArrayList<Double>()
var selectedTest: UserData? = null var selectedTest: UserData? = null
var hemoCubeTestData: HemoCubeTestData? = null
var kitSerial: String = "" var kitSerial: String = ""
var location: UserData.Location? = null var location: UserData.Location? = null
var testExp: Boolean = true var testExp: Boolean = true
var hemocubeResult: Double? = null
} }

View File

@@ -1,46 +0,0 @@
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

@@ -0,0 +1,8 @@
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

@@ -0,0 +1,31 @@
package com.example.hpostesting.data.api
import com.example.hpostesting.data.model.patient.MolbioLogin
import com.example.hpostesting.data.model.patient.UploadResponse
import com.google.gson.JsonObject
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.Header
import retrofit2.http.Headers
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Part
interface MolbioApi {
@Headers("Content-Type: application/json")
@POST("devices/login")
suspend fun login(@Body jsonObject: JsonObject): MolbioLogin
@Multipart
@PUT("results/upload")
fun uploadPdf(@Header("Authorization") auth:String, @Part file: MultipartBody.Part, @Part("DeviceId") name: RequestBody): Call<JsonObject>
@Multipart
@PUT("results/upload")
suspend fun uploadNewPdf(@Header("Authorization") auth:String,@Part("") count:RequestBody,@Part("") userId:RequestBody,@Part file_csv: MultipartBody.Part,@Part file_log:MultipartBody.Part,@Part("DeviceId") name:RequestBody): UploadResponse
}

View File

@@ -2,7 +2,6 @@ package com.example.hpostesting.data.constant
object Constants { object Constants {
const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION" 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 ABHA_APP_PACKAGE = "in.ndhm.phr" const val ABHA_APP_PACKAGE = "in.ndhm.phr"
@@ -23,12 +22,7 @@ object Constants {
const val MAX_WAVELENGTH_RANGE_TO_RECORD = 750 const val MAX_WAVELENGTH_RANGE_TO_RECORD = 750
const val DEVICE_PRODUCT_ID = 24597 const val DEVICE_PRODUCT_ID = 24597
const val DEVICE_TYPE_HOMOCUBE = "HOMOCUBE"
const val DEVICE_TYPE_TEST_RIGHT = "TEST_RIGHT"
const val DEVICE_VENDOR_ID = 1027 const val DEVICE_VENDOR_ID = 1027
const val HOMO_CUBE_ID = 29987
const val VENDOR_ID = 6790
const val ERROR_NORMAL = 400 const val ERROR_NORMAL = 400
const val ERROR_CRITICAL = 401 const val ERROR_CRITICAL = 401
@@ -41,37 +35,11 @@ object Constants {
"VIZ-1000-0004", "VIZ-1000-0004",
"VIZ-1000-0005", "VIZ-1000-0005",
"VIZ-1000-0006", "VIZ-1000-0006",
"HC-V1-001",
"HC-V1-002",
"HC-V1-003",
"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",
) )
const val password = "SMI@12345" const val password = "SMI@12345"
const val KIT_NUMBER = "KitNumber" const val BASE_URL = "https://datacollection.micropcr.com/v1/"
const val KIT_COUNT = "KitCount"
const val BUFFER_VALUE_1 = "BufferValue1" const val TOKEN = "molbioToken"
const val BUFFER_VALUE_2 = "BufferValue2"
const val BUFFER_VALUE_3 = "BufferValue3"
const val BUFFER_VALUE_4 = "BufferValue4"
const val DEVICE_ID = "DEVICE_ID"
} }

View File

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

View File

@@ -2,7 +2,6 @@ package com.example.hpostesting.data.dao
import androidx.room.TypeConverter import androidx.room.TypeConverter
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.google.common.reflect.TypeToken
import com.google.gson.Gson import com.google.gson.Gson
class Converters { class Converters {
@@ -16,6 +15,7 @@ class Converters {
null null
} }
} }
@TypeConverter @TypeConverter
fun toString(location: UserData.Location?): String? { fun toString(location: UserData.Location?): String? {
return if (location != null) { return if (location != null) {
@@ -24,15 +24,4 @@ class Converters {
null null
} }
} }
@TypeConverter
fun fromList(list: List<Double>): String {
return Gson().toJson(list)
}
@TypeConverter
fun toList(json: String): List<Double> {
val type = object : TypeToken<List<Double>>() {}.type
return Gson().fromJson(json, type)
}
} }

View File

@@ -1,24 +0,0 @@
package com.example.hpostesting.data.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData
@Dao
interface DeviceDao {
@Query("SELECT * from device_table")
fun getAll(): LiveData<List<HemoCubeTestData>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(deviceData: DeviceData)
@Query("SELECT * FROM device_table WHERE deviceId = :id")
suspend fun getUserByID(id: String): HemoCubeTestData
@Query("DELETE FROM device_table WHERE deviceId = :id")
suspend fun deleteById(id: String)
}

View File

@@ -1,26 +0,0 @@
package com.example.hpostesting.data.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
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")
fun getAll(): LiveData<List<HemoCubeTestData>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(hemoCubeTestData: HemoCubeTestData)
@Query("SELECT * FROM hemo_cube_test_table WHERE _id = :id")
suspend fun getUserByID(id: String): HemoCubeTestData
@Query("DELETE FROM hemo_cube_test_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)
}

View File

@@ -1,19 +1,12 @@
package com.example.hpostesting.data.dao package com.example.hpostesting.data.dao
import android.content.Context
import androidx.room.Database import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.room.TypeConverters import androidx.room.TypeConverters
import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
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 = 6, exportSchema = false) @Database(entities = [UserData::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class) @TypeConverters(Converters::class)
abstract class MyDatabase : RoomDatabase() { abstract class MyDatabase : RoomDatabase() {
abstract fun userDao(): UserDao abstract fun userDao(): UserDao
abstract fun hemoCubeDao(): HemoCubeDao
} }

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,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

@@ -1,19 +0,0 @@
package com.example.hpostesting.data.model.patient
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.google.firebase.firestore.PropertyName
@Entity(tableName = "device_table")
data class DeviceData(
@PrimaryKey
var _id: String = "",
@get:PropertyName("deviceId") @set:PropertyName("deviceId")
var deviceId: String = "",
@get:PropertyName("deviceType") @set:PropertyName("deviceType")
var deviceType: String = "",
@get:PropertyName("coefficients") @set:PropertyName("coefficients")
var coefficients: List<Double> = emptyList(),
@get:PropertyName("calibratedAt") @set:PropertyName("calibratedAt")
var calibratedAt: String = ""
)

View File

@@ -1,45 +0,0 @@
package com.example.hpostesting.data.model.patient
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "hemo_cube_test_table")
data class HemoCubeTestData(
@PrimaryKey
var _id: String = "",
var name: String = "",
var birthYear: String = "",
var state: String = "",
var abhaId: String = "",
var bloodGroup: 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 deviceRatio: Double? = null,
var calculatedRatio: Double? = null,
var coefficients: String? = "",
var classificationResult: String = ""
)

View File

@@ -0,0 +1,5 @@
package com.example.hpostesting.data.model.patient
data class MolbioLogin(
val token: String
)

View File

@@ -45,6 +45,12 @@ data class PatientDetails(
OTHER OTHER
} }
// enum class BloodGroup {
// O_POSITIVE, O_NEGATIVE,
// A_POSITIVE, A_NEGATIVE,
// B_POSITIVE, B_NEGATIVE,
// AB_POSITIVE, AB_NEGATIVE,
// }
data class Address( data class Address(
var house: String?, var house: String?,

View File

@@ -0,0 +1,5 @@
package com.example.hpostesting.data.model.patient
data class UploadResponse(
val success: Boolean
)

View File

@@ -9,11 +9,8 @@ data class UserData(
@PrimaryKey @PrimaryKey
var _id: String = "", var _id: String = "",
var name: String = "", var name: String = "",
var incubationTime: String = "",
var birthYear: String = "", var birthYear: String = "",
var abhaId: String = "",
var userImageURL: String = "", var userImageURL: String = "",
var gender: String ="",
var location: Location? = null, var location: Location? = null,
var createdBy: String? = "", var createdBy: String? = "",
var reportUploadTime: String? = "", var reportUploadTime: String? = "",
@@ -21,13 +18,13 @@ data class UserData(
var testStatus: Boolean? = false, var testStatus: Boolean? = false,
var mobileId: String = "", var mobileId: String = "",
var deviceId: String = "", var deviceId: String = "",
var state: String = "",
var deviceSerialNumber: String = "", var deviceSerialNumber: String = "",
var kitSerial: String = "", var kitSerial: String = "",
var csvPath: String = "", var csvPath: String = "",
var reportPath: String = "", var reportPath: String = "",
var result: TestRightResultType? = null, var result: TestRightResultType? = null,
var resultRatio: Double? = null var resultRatio: Double? = null,
var uploadFlag: Boolean? = false
) { ) {
enum class Gender { enum class Gender {
MALE, MALE,
@@ -40,13 +37,3 @@ data class UserData(
var longitude: Double? = null var longitude: Double? = null
) )
} }
fun UserData.toHemoCubeTestData() = HemoCubeTestData(
_id = _id,
name = name,
birthYear = birthYear,
userImageURL = userImageURL,
testStatus = testStatus,
location = location,
gender = gender
)

View File

@@ -1,77 +1,78 @@
package com.example.hpostesting.data.repository package com.example.hpostesting.data.repository
import android.net.Uri import android.net.Uri
import com.example.hpostesting.data.api.MolbioApi
import com.example.hpostesting.data.model.PendingUploads import com.example.hpostesting.data.model.PendingUploads
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.patient.MolbioLogin
import com.example.hpostesting.data.model.patient.BufferCheckData import com.example.hpostesting.data.model.patient.UploadResponse
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.UserData
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.firestore import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import com.google.firebase.storage.ktx.storage import com.google.firebase.storage.ktx.storage
import com.google.gson.JsonObject
import kotlinx.coroutines.tasks.await import kotlinx.coroutines.tasks.await
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File import java.io.File
import java.net.ConnectException
import java.net.SocketTimeoutException
import javax.inject.Inject
import javax.inject.Singleton
class DatabaseRepository : Repository {
class NetworkException(message: String, cause: Throwable) : Exception(message, cause)
@Singleton
class DatabaseRepository @Inject constructor(
private val molbioApi: MolbioApi
) : Repository {
private val db: FirebaseFirestore = Firebase.firestore private val db: FirebaseFirestore = Firebase.firestore
private val storage = Firebase.storage private val storage = Firebase.storage
suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String> { private suspend fun <T : Any> safeApiCall(apiCall: suspend () -> T): com.example.hpostesting.data.Result<T> {
return try { return try {
val userdata = db.collection("patientData").whereEqualTo("_id", data!!._id).get().await() val response = apiCall.invoke()
com.example.hpostesting.data.Result.Success(response)
} catch (e: SocketTimeoutException) {
com.example.hpostesting.data.Result.Error(NetworkException("Network timeout", e))
} catch (e: ConnectException) {
com.example.hpostesting.data.Result.Error(
NetworkException(
"Network connection failed",
e
)
)
} catch (e: Exception) {
com.example.hpostesting.data.Result.Error(e)
}
}
suspend fun login(jsonObject: JsonObject): com.example.hpostesting.data.Result<MolbioLogin> {
return safeApiCall { molbioApi.login(jsonObject) }
}
suspend fun uploadPdf(token:String,count:RequestBody,userId:RequestBody,file_csv:MultipartBody.Part,log_csv:MultipartBody.Part,deviceId:RequestBody): com.example.hpostesting.data.Result<UploadResponse> {
return safeApiCall { molbioApi.uploadNewPdf(token,count,userId,file_csv,log_csv,deviceId) }
}
suspend fun addTestToDatabase(data: UserData): Response<String> {
return try {
val userdata = db.collection("patientData").whereEqualTo("_id", data._id).get().await()
if (userdata.documents.isNotEmpty()) { if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach { userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true) db.collection("patientData").document(it.id).update("testStatus", true)
} }
} }
db.collection("testData").add(data!!).await() db.collection("testData").add(data).await()
Response.Success(data!!._id) Response.Success(data._id)
} catch (e: Exception) { } catch (e: Exception) {
Response.Error(e) Response.Error(e)
} }
} }
suspend fun addTestToDatabase(data: UserData?): Response<String> {
return try {
val userdata = db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true)
}
}
db.collection("testData").add(data!!).await()
Response.Success(data!!._id)
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Response.Error(e)
}
}
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)
}
}
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)
}
}
suspend fun uploadFileToStorage(patientID: String, filePath: String): Response<Boolean> { suspend fun uploadFileToStorage(patientID: String, filePath: String): Response<Boolean> {
try { try {
@@ -79,8 +80,9 @@ class DatabaseRepository : Repository {
val riversRef = storage.reference.child("$patientID/${file.lastPathSegment}") val riversRef = storage.reference.child("$patientID/${file.lastPathSegment}")
riversRef.putFile(file).await() riversRef.putFile(file).await()
return Response.Success(true) return Response.Success(true)
} catch (e: Exception) { } catch (e: Exception) {
Firebase.crashlytics.recordException(e) e.printStackTrace()
return Response.Error(e) return Response.Error(e)
} }
} }
@@ -92,7 +94,7 @@ class DatabaseRepository : Repository {
Response.Success(true) Response.Success(true)
} catch (e: Exception) { } catch (e: Exception) {
Firebase.crashlytics.recordException(e) e.printStackTrace()
Response.Error(e) Response.Error(e)
} }
} }
@@ -111,7 +113,7 @@ class DatabaseRepository : Repository {
pendingList pendingList
} catch (e: Exception) { } catch (e: Exception) {
Firebase.crashlytics.recordException(e) e.printStackTrace()
pendingList pendingList
} }
} }
@@ -122,20 +124,9 @@ class DatabaseRepository : Repository {
Response.Success(true) Response.Success(true)
} catch (e: Exception) { } catch (e: Exception) {
Firebase.crashlytics.recordException(e) e.printStackTrace()
Response.Error(e) Response.Error(e)
} }
} }
suspend fun getDeviceData(): List<DeviceData> {
return db.collection("devices").get().await().toObjects(DeviceData::class.java)
}
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

@@ -0,0 +1,55 @@
package com.example.hpostesting.domain
import android.app.job.JobParameters
import android.app.job.JobService
import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import androidx.lifecycle.ViewModelProvider
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.testRight.TestRightViewModel
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class MyJobScheduler : JobService(){
@Inject
lateinit var sharedPreference: SharedPreferences
private lateinit var viewModel: TestRightViewModel
override fun onCreate() {
super.onCreate()
viewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(application)
.create(TestRightViewModel::class.java)
}
override fun onStartJob(p0: JobParameters?): Boolean {
Log.d("jober","job started")
sharedPreference = this.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
viewModel.networkStatusLiveData.observeForever {
if (it) {
fetchInternalDataAndUpload()
}
}
return false
}
private fun fetchInternalDataAndUpload() {
val token = sharedPreference.getString(Constants.TOKEN,"")
viewModel.allUserData.observeForever {userList ->
userList.forEach {user ->
if (user.uploadFlag == false) {
viewModel.bulkUploadResultToDatabase(user, token)
}
}
}
}
override fun onStopJob(p0: JobParameters?): Boolean {
Log.d("jober_stop","Job stopped")
return false
}
}

View File

@@ -2,12 +2,14 @@ package com.example.hpostesting.domain.di
import android.app.Application import android.app.Application
import android.content.Context import android.content.Context
import android.content.SharedPreferences
import androidx.lifecycle.ViewModelProvider
import androidx.room.Room import androidx.room.Room
import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.api.MolbioApi
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.MyDatabase import com.example.hpostesting.data.dao.MyDatabase
import com.example.hpostesting.data.dao.UserDao import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.datasource.LocalFileDataSource 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.LocalFileRepository
import com.example.hpostesting.domain.SaveRawData import com.example.hpostesting.domain.SaveRawData
import com.example.hpostesting.domain.SaveRawDataTest import com.example.hpostesting.domain.SaveRawDataTest
@@ -16,6 +18,8 @@ import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import javax.inject.Singleton import javax.inject.Singleton
@Module @Module
@@ -27,9 +31,7 @@ object AppModule {
fun provideMyDatabase(@ApplicationContext context: Context): MyDatabase { fun provideMyDatabase(@ApplicationContext context: Context): MyDatabase {
return Room.databaseBuilder( return Room.databaseBuilder(
context, MyDatabase::class.java, "my_database" context, MyDatabase::class.java, "my_database"
) ).build()
.fallbackToDestructiveMigration()
.build()
} }
@Provides @Provides
@@ -38,12 +40,6 @@ object AppModule {
return myDatabase.userDao() return myDatabase.userDao()
} }
@Provides
@Singleton
fun provideMyHemo(myDatabase: MyDatabase): HemoCubeDao {
return myDatabase.hemoCubeDao()
}
@Provides @Provides
@Singleton @Singleton
fun provideContext(application: Application): Context { fun provideContext(application: Application): Context {
@@ -66,7 +62,28 @@ object AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideDatabaseRepository(): DatabaseRepository { fun provideRetrofit(): Retrofit =
return DatabaseRepository() Retrofit
.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
@Provides
@Singleton
fun provideMolbioApi(retrofit: Retrofit): MolbioApi =
retrofit.create(MolbioApi::class.java)
@Provides
@Singleton
fun provideSharedPreferences(@ApplicationContext context: Context): SharedPreferences {
return context.getSharedPreferences("my_preferences", Context.MODE_PRIVATE)
}
@Provides
@Singleton
fun provideViewModelFactory(application: Application): ViewModelProvider.Factory {
return ViewModelProvider.AndroidViewModelFactory.getInstance(application)
} }
} }

View File

@@ -1,20 +1,14 @@
package com.example.hpostesting.presentation package com.example.hpostesting.presentation
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpostesting.presentation.hemocube.HemocubeActivity
import com.example.hpostesting.presentation.testRight.TestRightActivity import com.example.hpostesting.presentation.testRight.TestRightActivity
import com.google.android.material.snackbar.Snackbar
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.journeyapps.barcodescanner.ScanContract import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanIntentResult import com.journeyapps.barcodescanner.ScanIntentResult
import com.journeyapps.barcodescanner.ScanOptions import com.journeyapps.barcodescanner.ScanOptions
@@ -26,8 +20,6 @@ class KitScanActivity : AppCompatActivity() {
private val TAG = "KitScanActivity" private val TAG = "KitScanActivity"
private lateinit var binding: ActivityKitScanBinding private lateinit var binding: ActivityKitScanBinding
private lateinit var sharedPreference: SharedPreferences
private val barcodeLauncher = registerForActivityResult( private val barcodeLauncher = registerForActivityResult(
ScanContract() ScanContract()
) { result: ScanIntentResult -> ) { result: ScanIntentResult ->
@@ -47,56 +39,13 @@ class KitScanActivity : AppCompatActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityKitScanBinding.inflate(layoutInflater) binding = ActivityKitScanBinding.inflate(layoutInflater)
sharedPreference = this.getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
setContentView(binding.root) setContentView(binding.root)
if (DataHolder.sampleReadCounter <= Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE && DataHolder.isReferenceTaken) { if (DataHolder.sampleReadCounter <= Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE && DataHolder.isReferenceTaken){
DataHolder.selectedTest!!.kitSerial = DataHolder.kitSerial DataHolder.selectedTest!!.kitSerial = DataHolder.kitSerial
moveToNext() moveToNext()
} }
// if (checkHemoCubeKitData()) {
// DataHolder.selectedTest!!.kitSerial =
// sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
// moveToNext()
// } else {
// with(sharedPreference.edit()) {
// putString(Constants.KIT_NUMBER, "")
// putInt(Constants.KIT_COUNT, 0)
// putString(Constants.BUFFER_VALUE_1, "")
// putString(Constants.BUFFER_VALUE_2, "")
// apply()
// }
// }
try {
if (checkHemoCubeKitData()) {
DataHolder.selectedTest!!.kitSerial =
sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
moveToNext()
} else {
// Handle the case when checkHemoCubeKitData() returns false
with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "")
putInt(Constants.KIT_COUNT, 0)
putString(Constants.BUFFER_VALUE_1, "")
putString(Constants.BUFFER_VALUE_2, "")
apply()
}
}
} catch (e: NullPointerException) {
// Handle the NullPointerException here
e.printStackTrace() // You can log the exception for debugging
FirebaseCrashlytics.getInstance().recordException(e)
val errorMessage = "An error occurred: ${e.message}"
val rootView = findViewById<View>(android.R.id.content)
Snackbar.make(rootView, errorMessage, Snackbar.LENGTH_LONG).show()
// Optionally, show a user-friendly error message to the user
// Toast.makeText(applicationContext, "An error occurred", Toast.LENGTH_SHORT).show()
}
binding.nameEditText.setText("SMI/SC/") binding.nameEditText.setText("SMI/SC/")
setSupportActionBar(binding.toolbar) setSupportActionBar(binding.toolbar)
@@ -108,40 +57,9 @@ class KitScanActivity : AppCompatActivity() {
binding.btnGo.setOnClickListener { binding.btnGo.setOnClickListener {
val serialNumber = binding.nameEditText.text.toString().trim() val serialNumber = binding.nameEditText.text.toString().trim()
if (serialNumber.isNotEmpty() && isSerialValid(serialNumber)) { if (serialNumber.isNotEmpty() && checkDataNotNull() && 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,
"Kit number is updated, Please Select user before starting test",
Toast.LENGTH_SHORT
).show()
val i = Intent(applicationContext, DashboardActivity::class.java)
startActivity(i)
finish()
}
} else {
Toast.makeText(this, "Invalid KIT Number", Toast.LENGTH_LONG).show()
return@setOnClickListener
}
if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid(
serialNumber
)
) {
DataHolder.kitSerial = binding.nameEditText.text.toString() DataHolder.kitSerial = binding.nameEditText.text.toString()
DataHolder.selectedTest?.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() moveToNext()
} else { } else {
Toast.makeText(this, "Invalid KIT Number", Toast.LENGTH_LONG).show() Toast.makeText(this, "Invalid KIT Number", Toast.LENGTH_LONG).show()
@@ -149,15 +67,8 @@ class KitScanActivity : AppCompatActivity() {
} }
} }
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
}
private fun isSerialValid(s: String): Boolean { private fun isSerialValid(s: String): Boolean {
if (s.length != 17) { if (s.length != 17){
binding.nameEditText.error = getString(R.string.invalid_kit) binding.nameEditText.error = getString(R.string.invalid_kit)
return false return false
} }
@@ -165,20 +76,8 @@ class KitScanActivity : AppCompatActivity() {
} }
private fun moveToNext() { private fun moveToNext() {
val i = Intent(applicationContext, TestRightActivity::class.java)
DataHolder.deviceType.observe(this) { deviceType -> startActivity(i)
when (deviceType) {
Constants.DEVICE_TYPE_HOMOCUBE -> {
val i = Intent(applicationContext, HemocubeActivity::class.java)
startActivity(i)
}
Constants.DEVICE_TYPE_TEST_RIGHT -> {
val i = Intent(applicationContext, TestRightActivity::class.java)
startActivity(i)
}
}
}
} }
private fun startScanningNow() { private fun startScanningNow() {
@@ -200,7 +99,9 @@ class KitScanActivity : AppCompatActivity() {
private fun checkDataNotNull(): Boolean { private fun checkDataNotNull(): Boolean {
return if (DataHolder.selectedTest?._id == null) { return if (DataHolder.selectedTest?._id == null) {
Toast.makeText( Toast.makeText(
applicationContext, "Please Select patient before starting test", Toast.LENGTH_SHORT applicationContext,
"Please Select patient before starting test",
Toast.LENGTH_SHORT
).show() ).show()
val i = Intent(applicationContext, DashboardActivity::class.java) val i = Intent(applicationContext, DashboardActivity::class.java)

View File

@@ -1,16 +1,16 @@
package com.example.hpostesting.presentation package com.example.hpostesting.presentation
import android.Manifest import android.Manifest
import android.content.* import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.hardware.usb.UsbManager import android.hardware.usb.UsbManager
import android.location.Location import android.location.Location
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.Menu import android.view.Menu
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
@@ -20,10 +20,11 @@ import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.test.TestType import com.example.hpostesting.data.model.test.TestType
import com.example.hpostesting.presentation.dashboard.DashboardActivity import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.* import com.google.android.gms.location.LocationCallback
import com.google.android.material.snackbar.Snackbar import com.google.android.gms.location.LocationRequest
import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.hoho.android.usbserial.driver.UsbSerialProber import com.hoho.android.usbserial.driver.UsbSerialProber
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityMainBinding import `in`.sminnovations.hpostesting.databinding.ActivityMainBinding
@@ -31,18 +32,22 @@ import `in`.sminnovations.hpostesting.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
private var myMenu: Menu? = null private var myMenu: Menu? = null
private val TAG = "MainActivity" private val TAG = "MainActivity"
private lateinit var fusedLocationClient: FusedLocationProviderClient private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var locationCallback: LocationCallback private lateinit var locationCallback: LocationCallback
private val usbReceiver = object : BroadcastReceiver() { private var mUsbReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent) { override fun onReceive(context: Context?, intent: Intent) {
when (intent.action) { val action = intent.action
UsbManager.ACTION_USB_DEVICE_DETACHED -> DataHolder.usbConnected.value = false if (UsbManager.ACTION_USB_DEVICE_DETACHED == action) {
UsbManager.ACTION_USB_DEVICE_ATTACHED -> DataHolder.usbConnected.value = true DataHolder.usbConnected.value = false
} else if (UsbManager.ACTION_USB_DEVICE_ATTACHED == action) {
DataHolder.usbConnected.value = true
} }
checkAndUpdateUsbConnection()
} }
} }
@@ -59,94 +64,38 @@ class MainActivity : AppCompatActivity() {
locationCallback = object : LocationCallback() { locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) { override fun onLocationResult(locationResult: LocationResult) {
locationResult.lastLocation?.let { location -> locationResult.lastLocation?.let { location ->
DataHolder.location = DataHolder.selectedTest!!.location = UserData.Location(location.latitude, location.longitude)
UserData.Location(location.latitude, location.longitude)
DataHolder.selectedTest?.location =
UserData.Location(location.latitude, location.longitude)
Log.i("Location", DataHolder.location.toString()) Log.i("Location", DataHolder.location.toString())
} }
} }
} }
val usbFilter = IntentFilter().apply { val filter = IntentFilter().apply {
addAction(UsbManager.ACTION_USB_DEVICE_DETACHED) addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED) addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
} }
registerReceiver(usbReceiver, usbFilter) registerReceiver(mUsbReceiver, filter)
DataHolder.deviceType.observe(this) { deviceType ->
with(binding) {
if (deviceType == Constants.DEVICE_TYPE_HOMOCUBE) {
cvItem1.visibility = View.VISIBLE
cvItem3.visibility = View.VISIBLE
cvItem2.visibility = View.GONE
cvItem4.visibility = View.GONE
}
DataHolder.usbConnected.value = true
}
}
if (DataHolder.selectedTest == null) {
startActivity(Intent(this, DashboardActivity::class.java))
finish()
}
} }
private fun checkAndUpdateUsbConnection() { private fun checkAndUpdateUsbConnection() {
val availableDrivers = UsbSerialProber.getDefaultProber() val availableDrivers = UsbSerialProber.getDefaultProber()
.findAllDrivers(getSystemService(Context.USB_SERVICE) as UsbManager) .findAllDrivers(getSystemService(Context.USB_SERVICE) as UsbManager)
if (availableDrivers.isNotEmpty() && availableDrivers[0].device.productId == Constants.DEVICE_PRODUCT_ID && availableDrivers[0].device.vendorId == Constants.DEVICE_VENDOR_ID) {
val deviceType = when { Log.d(
availableDrivers.isNotEmpty() -> { TAG,
val device = availableDrivers[0].device "Device matched -> product = ${availableDrivers[0].device.productId}, vendor = ${availableDrivers[0].device.vendorId}"
when { )
device.productId == Constants.HOMO_CUBE_ID && device.vendorId == Constants.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,
"Device matched -> product = ${device.productId}, vendor = ${device.vendorId}"
)
binding.cvItem1.visibility = View.VISIBLE
binding.cvItem3.visibility = View.VISIBLE
binding.cvItem2.visibility = View.VISIBLE
binding.cvItem4.visibility = View.VISIBLE
DataHolder.deviceType.postValue(Constants.DEVICE_TYPE_TEST_RIGHT)
Constants.DEVICE_TYPE_TEST_RIGHT
}
else -> {
Log.d(
TAG,
"Device NOT matched -> product = ${device.productId}, vendor = ${device.vendorId}"
)
val message =
if (device.productId == Constants.DEVICE_PRODUCT_ID) "Device Not Compatible" else "Device Not Connected"
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
DataHolder.usbConnected.value = false
null
}
}
}
else -> {
Log.d(TAG, "Device NOT Connected")
Toast.makeText(this, "Device Not Connected", Toast.LENGTH_SHORT).show()
DataHolder.usbConnected.value = false
null
}
}
deviceType?.let {
DataHolder.usbConnected.value = true DataHolder.usbConnected.value = true
DataHolder.deviceType.postValue(it) } else if (availableDrivers.isNotEmpty()) {
Log.d(
TAG,
"Device NOT matched -> product = ${availableDrivers[0].device.productId}, vendor = ${availableDrivers[0].device.vendorId}"
)
Toast.makeText(this, "Device Not Compatible", Toast.LENGTH_SHORT).show()
DataHolder.usbConnected.value = false
} else {
Log.d(TAG, "Device NOT Connected")
DataHolder.usbConnected.value = false
} }
} }
@@ -155,14 +104,12 @@ class MainActivity : AppCompatActivity() {
DataHolder.selectedTestType = TestType.SICKLECERT DataHolder.selectedTestType = TestType.SICKLECERT
val i = Intent(applicationContext, KitScanActivity::class.java) val i = Intent(applicationContext, KitScanActivity::class.java)
startActivity(i) startActivity(i)
finish()
} }
binding.cvItem2.setOnClickListener { binding.cvItem2.setOnClickListener {
DataHolder.selectedTestType = TestType.SICKLEFIND DataHolder.selectedTestType = TestType.SICKLEFIND
val i = Intent(applicationContext, KitScanActivity::class.java) val i = Intent(applicationContext, KitScanActivity::class.java)
startActivity(i) startActivity(i)
finish()
} }
DataHolder.usbConnected.observe(this) { DataHolder.usbConnected.observe(this) {
@@ -232,46 +179,16 @@ class MainActivity : AppCompatActivity() {
return return
} }
// fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
// location?.let {
// DataHolder.selectedTest!!.location =
// UserData.Location(location.latitude, location.longitude)
// DataHolder.location =
// UserData.Location(location.latitude, location.longitude)
// } ?: run {
// requestLocationUpdates()
// }
// }.addOnFailureListener { exception: Exception ->
// exception.printStackTrace()
// }
fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? -> fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
location?.let { location?.let {
if (DataHolder.selectedTest != null) {
DataHolder.selectedTest!!.location = DataHolder.selectedTest!!.location =
UserData.Location(location.latitude, location.longitude) UserData.Location(location.latitude, location.longitude)
} else { } ?: run {
startActivity(Intent(this, DashboardActivity::class.java)) requestLocationUpdates()
finish()
} }
DataHolder.location = }.addOnFailureListener { exception: Exception ->
UserData.Location(location.latitude, location.longitude) exception.printStackTrace()
} ?: run {
requestLocationUpdates()
} }
}.addOnFailureListener { exception: Exception ->
// Handle the exception here
exception.printStackTrace()
FirebaseCrashlytics.getInstance().recordException(exception)
// Display an error message to the user using a Snackbar
val errorMessage = "An error occurred: ${exception.message}"
val rootView = findViewById<View>(android.R.id.content)
Snackbar.make(rootView, errorMessage, Snackbar.LENGTH_LONG).show()
}
} }
private fun requestLocationUpdates() { private fun requestLocationUpdates() {

View File

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

View File

@@ -1,10 +1,6 @@
package com.example.hpostesting.presentation.adapter package com.example.hpostesting.presentation.adapter
import android.annotation.SuppressLint 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.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -18,26 +14,9 @@ import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions import com.firebase.ui.firestore.FirestoreRecyclerOptions
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.UserItemViewBinding 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.presentation.hemocube.HemoCubeViewModel
import com.google.firebase.firestore.FirebaseFirestore
class UserListAdapter( class UserListAdapter(options: FirestoreRecyclerOptions<UserData>, private val view: View) :
FirestoreRecyclerAdapter<UserData, UserListAdapter.OrderItemViewHolder>(options) {
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) {
class OrderItemViewHolder(val binding: UserItemViewBinding) : class OrderItemViewHolder(val binding: UserItemViewBinding) :
RecyclerView.ViewHolder(binding.root) RecyclerView.ViewHolder(binding.root)
@@ -51,23 +30,8 @@ class UserListAdapter(
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: OrderItemViewHolder, position: Int, model: UserData) { override fun onBindViewHolder(holder: OrderItemViewHolder, position: Int, model: UserData) {
holder.binding.apply { holder.binding.apply {
userName.text = "Name: ${model.name}" userName.text = model.name
userId.text = "User ID:${model._id}" userId.text = 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) Glide.with(view).load(model.userImageURL).into(userImage)
if (model.testStatus!!) { if (model.testStatus!!) {
teststatus.text = "Test concluded" teststatus.text = "Test concluded"
@@ -75,129 +39,7 @@ class UserListAdapter(
} else { } else {
teststatus.text = "Test is Pending" teststatus.text = "Test is 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("Add Blood Group")
val etBloodGroup = dialogView.findViewById<AutoCompleteTextView>(R.id.et_blood_group)
builder.setPositiveButton("OK") { dialog, which ->
val bloodGroup = etBloodGroup.text.toString()
if (bloodGroup.equals("Select Blood Group") || bloodGroup.isNullOrBlank()) {
etBloodGroup.error = "Please enter your blood group"
Toast.makeText(
context,
"Please enter your blood group",
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 {
Toast.makeText(
context,
"Blood group updated successfully",
Toast.LENGTH_SHORT
).show()
btnBlood.visibility = View.GONE
}
.addOnFailureListener { e ->
Toast.makeText(
context,
"Failed to update blood group: ${e.message}",
Toast.LENGTH_SHORT
).show()
}
} catch (e: IndexOutOfBoundsException) {
// Handle the case where no documents are found for the specified ID
Toast.makeText(
context,
"No user data found for the specified ID",
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("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()
// }
// }
// }
// }
}
userCard.setOnClickListener { userCard.setOnClickListener {
if (batLevel < 40) {
Toast.makeText(
view.context,
"Battery level is low than 40%, please charge the device to continue testing",
Toast.LENGTH_SHORT
).show()
return@setOnClickListener
}
if (model.testStatus != null) { if (model.testStatus != null) {
if (model.testStatus!!) { if (model.testStatus!!) {
Toast.makeText( Toast.makeText(
@@ -206,47 +48,11 @@ class UserListAdapter(
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} else { } else {
if (model.incubationTime != "") { DataHolder.selectedTest = model
if (isBetween15And30Minutes(model.incubationTime) < 15) { view.findNavController().navigate(R.id.action_nav_home_to_mainActivity)
Toast.makeText(
view.context,
"Incubation has not completed 15 minutes",
Toast.LENGTH_SHORT
).show()
} else if (isBetween15And30Minutes(model.incubationTime) > 30) {
Toast.makeText(
view.context,
"Incubation crossed 30 minutes, need to repeat the incubation",
Toast.LENGTH_SHORT
).show()
} else {
DataHolder.selectedTest = model
view.findNavController()
.navigate(R.id.action_nav_home_to_mainActivity)
}
} else {
Toast.makeText(
view.context,
"Incubation not started for this user",
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,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.dashboard.DashboardActivity
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, "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(), "No internet connection avaiable", Toast.LENGTH_SHORT
).show()
}
isOnline = isNetworkAvailable
}
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
showToast("Kit result uploaded successfully")
}
if (result == "Local") {
showToast("Kit result uploading failed, note it down manually")
}
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("test is going on")
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("error while performing classification")
Firebase.crashlytics.recordException(e)
return "ERROR"
}
return "NULL"
}
private fun showToast(message: String) {
Toast.makeText(requireContext(), message, 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,164 +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.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 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, "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()) {
Toast.makeText(this, "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

@@ -2,7 +2,6 @@ package com.example.hpostesting.presentation.dashboard
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout
import androidx.navigation.findNavController import androidx.navigation.findNavController
@@ -11,12 +10,6 @@ import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import com.google.android.material.navigation.NavigationView import com.google.android.material.navigation.NavigationView
import com.google.firebase.appdistribution.FirebaseAppDistribution
import com.google.firebase.appdistribution.FirebaseAppDistributionException
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.crashlytics.ktx.crashlytics
//import com.google.firebase.appdistribution.FirebaseAppDistribution
//import com.google.firebase.appdistribution.FirebaseAppDistributionException
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
@@ -26,12 +19,12 @@ class DashboardActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityDashboardBinding private lateinit var binding: ActivityDashboardBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityDashboardBinding.inflate(layoutInflater) binding = ActivityDashboardBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
setSupportActionBar(binding.appBarDashboard.toolbar) setSupportActionBar(binding.appBarDashboard.toolbar)
val drawerLayout: DrawerLayout = binding.drawerLayout val drawerLayout: DrawerLayout = binding.drawerLayout
@@ -59,44 +52,4 @@ class DashboardActivity : AppCompatActivity() {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() 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()
}
}
} }

View File

@@ -1,13 +1,11 @@
package com.example.hpostesting.presentation.dashboard package com.example.hpostesting.presentation.dashboard
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.example.hpostesting.presentation.buffercheck.HemocubeBufferCheckActivity import androidx.lifecycle.ViewModelProvider
import com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity
import `in`.sminnovations.hpostesting.databinding.FragmentGalleryBinding import `in`.sminnovations.hpostesting.databinding.FragmentGalleryBinding
class GalleryFragment : Fragment() { class GalleryFragment : Fragment() {
@@ -23,8 +21,6 @@ class GalleryFragment : Fragment() {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
// val galleryViewModel =
// ViewModelProvider(this).get(GalleryViewModel::class.java)
_binding = FragmentGalleryBinding.inflate(inflater, container, false) _binding = FragmentGalleryBinding.inflate(inflater, container, false)
val root: View = binding.root val root: View = binding.root
@@ -33,15 +29,6 @@ class GalleryFragment : Fragment() {
// galleryViewModel.text.observe(viewLifecycleOwner) { // galleryViewModel.text.observe(viewLifecycleOwner) {
//// textView.text = it //// textView.text = it
// } // }
binding.btnSubmit.setOnClickListener {
startActivity(Intent(requireContext(), HemocubeBufferCheckActivity::class.java))
}
binding.btnDiagnostics.setOnClickListener {
startActivity(Intent(requireContext(), DiagnosticsActivity::class.java))
}
return root return root
} }

View File

@@ -2,12 +2,10 @@ package com.example.hpostesting.presentation.dashboard
import android.app.AlertDialog import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.content.Context.BATTERY_SERVICE
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.BatteryManager
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -16,49 +14,33 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.model.patient.HemoCubeTestData
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.presentation.KitScanActivity
import com.example.hpostesting.presentation.adapter.UserListAdapter import com.example.hpostesting.presentation.adapter.UserListAdapter
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
import com.example.hpostesting.presentation.testRight.TestRightViewModel import com.example.hpostesting.presentation.testRight.TestRightViewModel
import com.firebase.ui.firestore.FirestoreRecyclerOptions 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.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import com.google.firebase.perf.ktx.performance import com.google.gson.JsonObject
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale import java.util.Locale
@AndroidEntryPoint @AndroidEntryPoint
class HomeFragment : Fragment() { class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
private val viewModel: TestRightViewModel by activityViewModels() private val viewModel: TestRightViewModel by activityViewModels()
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var rvAdapter: UserListAdapter private lateinit var rvAdapter: UserListAdapter
private var batLevel: Int = 0 // Initialize with a default value, or obtain the actual battery level
private lateinit var sharedPreference: SharedPreferences private lateinit var sharedPreference: SharedPreferences
private var loginCount = 1
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? { ): View {
_binding = FragmentHomeBinding.inflate(inflater, container, false) _binding = FragmentHomeBinding.inflate(inflater, container, false)
// Check if _binding is null
if (_binding == null) {
// Handle the case where binding could not be initialized
// You may want to log an error or return a default view in this case
return super.onCreateView(inflater, container, savedInstanceState)
}
sharedPreference = sharedPreference =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE) requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
DataHolder.selectedTest = null DataHolder.selectedTest = null
@@ -71,52 +53,76 @@ class HomeFragment : Fragment() {
viewModel.allUserData.observe(viewLifecycleOwner) { userData -> viewModel.allUserData.observe(viewLifecycleOwner) { userData ->
deleteIncompleteRegistrations(userData) deleteIncompleteRegistrations(userData)
} }
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData ->
deleteHemoCubeIncompleteRegistrations(userData)
}
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isConnected -> viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isConnected ->
if (isConnected) { if (isConnected) {
binding.internetAvailableCL.visibility = View.VISIBLE binding.internetAvailableCL.visibility = View.VISIBLE
binding.internetNotAvailableCL.visibility = View.GONE binding.internetNotAvailableCL.visibility = View.GONE
login()
loadUserData() loadUserData()
setSearch() setSearch()
checkForLocalDBData() // checkForLocalDBData()
} else { } else {
binding.internetAvailableCL.visibility = View.GONE binding.internetAvailableCL.visibility = View.GONE
binding.internetNotAvailableCL.visibility = View.VISIBLE binding.internetNotAvailableCL.visibility = View.VISIBLE
setUserId() setUserId()
} }
} }
hemoCubeViewModel.fireBaseBulkUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
Toast.makeText(
requireContext(),
"Test Results Uploaded Successfully",
Toast.LENGTH_SHORT
).show()
}
if (result == "Error") {
Toast.makeText(requireContext(), "Test Results Upload Failed", Toast.LENGTH_SHORT)
.show()
}
}
binding.btnLogout.setOnClickListener { binding.btnLogout.setOnClickListener {
logoutUser(requireContext()) logoutUser(requireContext())
} }
binding.uploadData.setOnClickListener { binding.uploadData.setOnClickListener {
showUploadDialog(requireContext()) showUploadDialog()
} }
binding.btnNewKit.setOnClickListener { //
with(sharedPreference.edit()) { // val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
putString(Constants.KIT_NUMBER, "") //
putInt(Constants.KIT_COUNT, 0) // val jobInfo = JobInfo.Builder(1, ComponentName(this, MyJobScheduler::class.java))
apply() // .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
// .setPersisted(true)
// .setPeriodic(30 * 60 * 1000)
// .build()
// jobScheduler.schedule(jobInfo)
}
override fun onStart() {
super.onStart()
val jsonObject = JsonObject()
jsonObject.addProperty("Username", "hposdevice")
jsonObject.addProperty("Password", "sickle")
viewModel.loginResponse.observe(viewLifecycleOwner) { response ->
when (response) {
is Result.Success -> {
val editor = sharedPreference.edit()
editor.putString(Constants.TOKEN, response.data.token)
editor.apply()
Log.d("login_api", "called")
// showUploadDialog()
}
is Result.Error -> {
if (loginCount < 3) {
viewModel.login(jsonObject)
loginCount++
}
Log.d("API Error", response.exception.message.toString())
}
is Result.Loading -> {
Toast.makeText(requireContext(), "Loading", Toast.LENGTH_SHORT).show()
}
else -> {}
} }
startActivity(Intent(requireContext(), KitScanActivity::class.java))
requireActivity().finish()
} }
} }
private fun login() {
val jsonObject = JsonObject()
jsonObject.addProperty("Username", "hposdevice")
jsonObject.addProperty("Password", "sickle")
viewModel.login(jsonObject)
}
private fun setUserId() { private fun setUserId() {
binding.btnSubmit.setOnClickListener { binding.btnSubmit.setOnClickListener {
val userId = binding.userId.text.toString() val userId = binding.userId.text.toString()
@@ -133,38 +139,13 @@ class HomeFragment : Fragment() {
} }
private fun loadUserData() { private fun loadUserData() {
try { val query = Firebase.firestore.collection("patientData")
val dateFormat = SimpleDateFormat("yyyy-MM-dd") val recyclerViewOptions =
val currentDate = Date() FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java)
val formattedDate = dateFormat.format(currentDate) .build()
val query = Firebase.firestore.collection("patientData") rvAdapter = UserListAdapter(recyclerViewOptions, binding.root)
.whereGreaterThanOrEqualTo("createdAt", formattedDate) binding.rvOrder.adapter = rvAdapter
.orderBy("createdAt", Query.Direction.DESCENDING) rvAdapter.startListening()
// val query = Firebase.firestore.collection("patientData").whereEqualTo("testStatus", false)
query.get().addOnSuccessListener {
if (it.documents.isEmpty()) {
binding.pendingTest.visibility = View.VISIBLE
} else {
binding.pendingTest.visibility = View.GONE
}
}
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())
}!!
binding.rvOrder.adapter = rvAdapter
rvAdapter.startListening()
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
}
} }
private fun saveUserId(userId: String) { private fun saveUserId(userId: String) {
@@ -178,11 +159,15 @@ class HomeFragment : Fragment() {
val builder = AlertDialog.Builder(context) val builder = AlertDialog.Builder(context)
builder.setTitle("Log Out") builder.setTitle("Log Out")
builder.setMessage("Do you want to LogOut the Application?") builder.setMessage("Do you want to LogOut the Application?")
// Positive button
builder.setPositiveButton("Yes") { dialog, _ -> builder.setPositiveButton("Yes") { dialog, _ ->
saveUserId("") saveUserId("")
findNavController().navigate(R.id.action_nav_home_to_loginFragment) findNavController().navigate(R.id.action_nav_home_to_loginFragment)
dialog.dismiss() dialog.dismiss()
} }
// Negative button
builder.setNegativeButton("No") { dialog, _ -> builder.setNegativeButton("No") { dialog, _ ->
dialog.dismiss() dialog.dismiss()
} }
@@ -191,39 +176,25 @@ class HomeFragment : Fragment() {
dialog.show() dialog.show()
} }
private fun getData(search: String?, field: String) {
val userSearchTrace = Firebase.performance.newTrace("user_search_trace")
userSearchTrace.start()
search?.replaceFirstChar { private fun getData(search: String?, field: String) {
val capitalizedSearch = search?.replaceFirstChar {
if (search.lowercase() if (search.lowercase()
.startsWith(it.lowercase()) .startsWith(it.lowercase())
) it.titlecase(Locale.getDefault()) else it.toString() ) it.titlecase(Locale.getDefault()) else it.toString()
} }
val currentDate = Date()
val dateFormat = SimpleDateFormat("yyyyMMdd") val query = Firebase.firestore.collection("patientData").orderBy(field).startAt(search)
val partition = dateFormat.format(currentDate) .endAt(search + "\uf8ff")
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 recyclerViewOptions = val recyclerViewOptions =
FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java) FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java)
.build() .build()
val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager
batLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
rvAdapter = view?.let { rvAdapter = UserListAdapter(recyclerViewOptions, binding.root)
UserListAdapter(requireContext(), hemoCubeViewModel, recyclerViewOptions, it, batLevel, requireActivity())
}!!
binding.rvOrder.adapter = rvAdapter binding.rvOrder.adapter = rvAdapter
rvAdapter.startListening() rvAdapter.startListening()
userSearchTrace.stop()
} }
private fun setSearch() { private fun setSearch() {
@@ -237,10 +208,8 @@ class HomeFragment : Fragment() {
binding.aadharIdRadioButton.isChecked -> "aadharId" binding.aadharIdRadioButton.isChecked -> "aadharId"
else -> null else -> null
} }
field?.let { getData(query, it) } field?.let { getData(query, it) }
false false
} else { } else {
loadUserData() loadUserData()
false false
@@ -270,15 +239,10 @@ class HomeFragment : Fragment() {
val uploadDataVisibility = if (userDataList.isEmpty()) View.GONE else View.VISIBLE val uploadDataVisibility = if (userDataList.isEmpty()) View.GONE else View.VISIBLE
binding.uploadData.visibility = uploadDataVisibility binding.uploadData.visibility = uploadDataVisibility
} }
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
val uploadDataVisibility = if (userDataList.any { !it.localFlag }) View.VISIBLE else View.GONE
binding.uploadData.visibility = uploadDataVisibility
}
} }
private fun showUploadDialog(context: Context) { private fun showUploadDialog() {
val builder = AlertDialog.Builder(context) val builder = AlertDialog.Builder(requireContext())
builder.setTitle(R.string.upload_db_registration_title) builder.setTitle(R.string.upload_db_registration_title)
builder.setMessage(R.string.upload_db_registration_message) builder.setMessage(R.string.upload_db_registration_message)
@@ -295,13 +259,13 @@ class HomeFragment : Fragment() {
} }
private fun uploadLocalDBData(dialog: DialogInterface) { private fun uploadLocalDBData(dialog: DialogInterface) {
val token = sharedPreference.getString(Constants.TOKEN, "")
viewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> viewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
if (userDataList.isEmpty()) { if (userDataList.isEmpty()) {
dialog.dismiss() dialog.dismiss()
} else { } else {
userDataList.forEach { userData -> userDataList.forEach { userData ->
viewModel.bulkUploadResultToDatabase(userData) viewModel.bulkUploadResultToDatabase(userData, token!!)
viewModel.deleteById(userData._id)
} }
dialog.dismiss() dialog.dismiss()
Toast.makeText( Toast.makeText(
@@ -309,34 +273,16 @@ class HomeFragment : Fragment() {
).show() ).show()
} }
} }
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
userDataList.forEach { userData ->
if (!userData.localFlag) {
userData.localFlag = true
hemoCubeViewModel.bulkAddResultTestToDb(userData)
}
}
dialog.dismiss()
}
} }
private fun deleteIncompleteRegistrations(userDataList: List<UserData>) { private fun deleteIncompleteRegistrations(userDataList: List<UserData>) {
userDataList.forEach { userData -> userDataList.forEach { userData ->
if (userData.csvPath.isEmpty()) { if (userData._id.isEmpty()) {
viewModel.deleteById(userData._id) viewModel.deleteById(userData._id)
} }
} }
} }
private fun deleteHemoCubeIncompleteRegistrations(userDataList: List<HemoCubeTestData>) {
userDataList.forEach { userData ->
if (userData.testTime?.isEmpty() == true) {
hemoCubeViewModel.deleteById(userData._id)
}
}
}
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
_binding = null _binding = null

View File

@@ -9,7 +9,6 @@ import androidx.lifecycle.ViewModelProvider
import com.example.hpostesting.presentation.dashboard.ui.slideshow.SlideshowViewModel import com.example.hpostesting.presentation.dashboard.ui.slideshow.SlideshowViewModel
import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding
class SlideshowFragment : Fragment() { class SlideshowFragment : Fragment() {
private var _binding: FragmentSlideshowBinding? = null private var _binding: FragmentSlideshowBinding? = null
@@ -21,7 +20,7 @@ class SlideshowFragment : Fragment() {
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle?, savedInstanceState: Bundle?
): View { ): View {
val slideshowViewModel = val slideshowViewModel =
ViewModelProvider(this).get(SlideshowViewModel::class.java) ViewModelProvider(this).get(SlideshowViewModel::class.java)
@@ -29,12 +28,6 @@ class SlideshowFragment : Fragment() {
_binding = FragmentSlideshowBinding.inflate(inflater, container, false) _binding = FragmentSlideshowBinding.inflate(inflater, container, false)
val root: View = binding.root val root: View = binding.root
val pInfo = requireActivity().packageManager.getPackageInfo(
requireActivity().packageName, 0
)
val version = pInfo.versionName
binding.textSlideshow.text = version
// val textView: TextView = binding.textSlideshow // val textView: TextView = binding.textSlideshow
// slideshowViewModel.text.observe(viewLifecycleOwner) { // slideshowViewModel.text.observe(viewLifecycleOwner) {
// textView.text = it // textView.text = it

View File

@@ -1,176 +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.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 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,61 +0,0 @@
package com.example.hpostesting.presentation.hemocube
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
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.Date
class DigitalCardFragment : Fragment() {
private lateinit var binding: FragmentDigitalCardBinding
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences
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()
}
private fun initViews() {
activity?.runOnUiThread {
binding.progressBar.visibility = View.VISIBLE
}
val originalDateStr = testDetails?.testTime
val originalDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val originalDate: Date? = originalDateFormat.parse(originalDateStr)
val desiredDateFormat = SimpleDateFormat("MMM dd, yyyy")
val formattedDate: String = originalDate?.let { desiredDateFormat.format(it) } ?: "N/A"
activity?.runOnUiThread {
binding.progressBar.visibility = View.GONE
}
binding.name.text = "Name: ${testDetails?.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: ${testDetails?.classificationResult}"
binding.issueDate.text = "Issue Date: $formattedDate"
}
}

View File

@@ -1,554 +0,0 @@
package com.example.hpostesting.presentation.hemocube
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.Color
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.DataHolder
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
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.dashboard.DashboardActivity
import com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity
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 com.google.firebase.perf.ktx.performance
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import kotlin.math.log10
class HemoCubeFragment : Fragment() {
private lateinit var binding: FragmentHemoCubeReferenceBinding
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences
val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
private var isOnline = false
private var currentDeviceData: DeviceData? = null
private var resultData: String = ""
private var isUsingExistingBuffer = false
private var isTestOngoing = false
private var startListening = MutableLiveData<Boolean>(false)
private val testingTrace = Firebase.performance.newTrace("testing_trace")
private var led1BufferForDevice = 0.0
private var led2BufferForDevice = 0.0
private var led3BufferForDevice = 0.0
private var led4BufferForDevice = 0.0
private var led1SampleForDevice = 0.0
private var led2SampleForDevice = 0.0
private var led3SampleForDevice = 0.0
private var led4SampleForDevice = 0.0
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()
listenToHemoCube()
getDeviceInfo()
observeViewModel()
}
private fun initViews() {
binding.btnSubmit.setOnClickListener {
activity?.runOnUiThread {
binding.progressBar.visibility = View.VISIBLE
}
hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "")
)
}
binding.tvTitle2.visibility = View.GONE
binding.etAbhaId.visibility = View.GONE
binding.nameEditText.visibility = View.GONE
binding.tvTitle.visibility = View.GONE
binding.btnGo.visibility = View.GONE
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
binding.btnPlacebuffer.visibility = View.GONE
binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}"
binding.tvSubtitle4.text = "Config"
binding.btnSamplestart.setOnClickListener {
activity?.runOnUiThread {
binding.tvSubtitle4.visibility = View.VISIBLE
binding.tvSubtitle4.text = "Sample Started"
}
startSampleProcess()
it.visibility = View.GONE
}
binding.btnPlacebuffer.setOnClickListener {
if (isBufferValueAvailable()) {
showBufferAlertDialog()
} else {
activity?.runOnUiThread {
binding.tvSubtitle4.visibility = View.VISIBLE
}
checkAndStartProcess()
}
it.visibility = View.GONE
}
}
private fun observeViewModel() {
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") {
showToast("Test Results Uploaded Successfully")
val digitalCardFragment = DigitalCardFragment()
val transaction = parentFragmentManager.beginTransaction()
transaction.replace(R.id.fragment_container, digitalCardFragment)
transaction.addToBackStack(null)
transaction.commit()
// val i = Intent(
// requireContext().applicationContext, DashboardActivity::class.java
// )
// startActivity(i)
// (activity as HemocubeActivity).finish()
}
if (result == "Local") {
showToast("Internet not available, test details stored locally")
startActivity(Intent(requireActivity(), DashboardActivity::class.java))
}
if (result == "Error") {
showToast("Error uploading data, test details stored locally")
startActivity(Intent(requireActivity(), DashboardActivity::class.java))
}
binding.progressBar.visibility = View.GONE
}
hemoCubeViewModel.getDeviceData(sharedPreferences.getString(Constants.USER_ID, ""))
hemoCubeViewModel.deviceData.observe(viewLifecycleOwner) {
currentDeviceData = it
}
hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
apply {
DataHolder.hemoCubeTestData?.let {
currentDeviceData?.coefficients?.let { coefficients ->
val coefficient1 = coefficients[0]
val coefficient2 = coefficients[1]
val result = coefficient1 * coefficient2
}
}
isOnline = isNetworkAvailable
}
}
hemoCubeViewModel.messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it
}
}
private fun checkAndStartProcess() {
startBufferProcess()
}
private fun isBufferValueAvailable(): Boolean {
return try {
if (sharedPreferences.getString(
Constants.BUFFER_VALUE_1, ""
) != "" && sharedPreferences.getString(Constants.BUFFER_VALUE_2, "") != ""
&& sharedPreferences.getString(Constants.BUFFER_VALUE_3, "") != ""
&& sharedPreferences.getString(Constants.BUFFER_VALUE_4, "") != ""
) {
sharedPreferences.getString(Constants.BUFFER_VALUE_1, "")
?.toDouble()!! > 0.0 && sharedPreferences.getString(
Constants.BUFFER_VALUE_2,
""
)
?.toDouble()!! > 0.0 && sharedPreferences.getString(
Constants.BUFFER_VALUE_3,
""
)
?.toDouble()!! > 0.0 && sharedPreferences.getString(
Constants.BUFFER_VALUE_4,
""
)
?.toDouble()!! > 0.0
} else {
false
}
} catch (e: Exception) {
showToast("error while getting existing buffer")
false
}
}
private fun showBufferAlertDialog() {
val title = "WARNING"
val message = "Do you want to continue with existing buffer?"
val negativeText = getString(R.string.no)
val positiveText = "Yes"
UIUtils.createAlertDialog(requireContext(),
title,
message,
negativeText,
positiveText,
object : MyDialogListener {
override fun onClickNegativeButton() {
startBufferProcess()
}
override fun onClickPositiveButton() {
activity?.runOnUiThread {
binding.btnPlacebuffer.visibility = View.GONE
binding.btnSamplestart.visibility = View.VISIBLE
binding.tvSubtitle4.text = "Place Sample"
}
isUsingExistingBuffer = true
}
})
}
private fun listenToHemoCube() {
if (DataHolder.hemoCubeTestData == null) {
DataHolder.hemoCubeTestData = DataHolder.selectedTest?.toHemoCubeTestData()
}
hemoCubeViewModel.progressBar.postValue(true)
val fullReadOutput = StringBuilder()
startListening.postValue(true)
try {
(activity as HemocubeActivity).mService.listenToHemoCube(object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
fullReadOutput.append(stringData)
handleUsbData(stringData, fullReadOutput)
}
}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
} catch (e: Exception) {
showToast("test is going on")
Firebase.crashlytics.recordException(e)
}
}
private fun getDeviceInfo() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.getDeviceId,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
data?.let {
val stringData = String(it)
hemoCubeViewModel.messages.postValue(stringData)
binding.tvSubtitle4.text = stringData
}
}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun handleUsbData(stringData: String, fullReadOutput: StringBuilder) {
if (stringData.contains("#")) {
isTestOngoing = true
}
resultData += stringData
when {
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.btnPlacebuffer.visibility = View.VISIBLE
}
hemoCubeViewModel.messages.postValue("Start")
}
stringData.contains("#BS") -> {
hemoCubeViewModel.messages.postValue("Buffer Started")
}
stringData.contains("#BC") -> {
activity?.runOnUiThread {
binding.tvSubtitle4.text = "Buffer Completed"
binding.btnSamplestart.visibility = View.VISIBLE
}
}
stringData.contains("#SS") -> {
activity?.runOnUiThread {
binding.tvSubtitle4.text = "Sample Started"
binding.btnSamplestart.visibility = View.GONE
}
}
stringData.contains("#SC") -> {
binding.tvSubtitle4.text = "Sample Completed"
fetchResult()
testingTrace.stop()
}
resultData.contains("REND") -> {
val resultLines = resultData.split("\\s+(?=LB|LS)".toRegex())
var bufferIntensity = resultLines[1].split(' ')[1].trim()
led1BufferForDevice = if (isUsingExistingBuffer) {
sharedPreferences.getString(Constants.BUFFER_VALUE_1, "")?.toDoubleOrNull()!!
} else {
bufferIntensity.toDoubleOrNull()!!
}
bufferIntensity = resultLines[2].split(' ')[1].trim()
led2BufferForDevice = if (isUsingExistingBuffer) {
sharedPreferences.getString(Constants.BUFFER_VALUE_2, "")?.toDoubleOrNull()!!
} else {
bufferIntensity.toDoubleOrNull()!!
}
bufferIntensity = resultLines[3].split(' ')[1].trim()
led3BufferForDevice = if (isUsingExistingBuffer) {
sharedPreferences.getString(Constants.BUFFER_VALUE_3, "")?.toDoubleOrNull()!!
} else {
bufferIntensity.toDoubleOrNull()!!
}
bufferIntensity = resultLines[4].split(' ')[1].trim()
led4BufferForDevice = if (isUsingExistingBuffer) {
sharedPreferences.getString(Constants.BUFFER_VALUE_4, "")?.toDoubleOrNull()!!
} else {
bufferIntensity.toDoubleOrNull()!!
}
var sampleIntensity = resultLines[5].split(' ')[1].trim()
led1SampleForDevice = resultLines[5].split(' ')[1].trim().toDoubleOrNull()!!
sampleIntensity = resultLines[6].split(' ')[1].trim()
led2SampleForDevice = resultLines[6].split(' ')[1].trim().toDoubleOrNull()!!
sampleIntensity = resultLines[7].split(' ')[1].trim()
led3SampleForDevice = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
sampleIntensity = resultLines[8].split(' ')[1].split('\r')[0].trim()
led4SampleForDevice = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
processResult()
}
}
}
private fun showError() {
activity?.runOnUiThread {
UIUtils.createAlertDialog(requireContext(),
"Device Error",
"Something is wrong with the device, please disconnect and reconnect the device and test the user again",
getString(R.string.noo),
"Yes",
object : MyDialogListener {
override fun onClickNegativeButton() {}
override fun onClickPositiveButton() {
startActivity(Intent(requireActivity(), DashboardActivity::class.java))
}
})
}
}
fun handleBackButtonPress() {
if (isTestOngoing) {
// If the test is ongoing, don't allow the back button action
// You can optionally show a message to the user indicating why the back button is disabled
// For example, show a Toast or Snackbar.
showToast("Test is ongoing. Cannot go back.")
} else {
// If the test is not ongoing, you can trigger the back action of the hosting activity
activity?.onBackPressed()
}
}
private fun processResult() {
try {
val deviceLog = resultData
val pInfo = requireActivity().packageManager.getPackageInfo(
requireActivity().packageName, 0
)
val version = pInfo.versionName
val led1Average = log10(led1BufferForDevice?.div(led1SampleForDevice!!) ?: 0.0)
val led2Average = log10(led2BufferForDevice?.div(led2SampleForDevice!!) ?: 0.0)
val led3Average = log10(led3BufferForDevice?.div(led3SampleForDevice!!) ?: 0.0)
val led4Average = log10(led4BufferForDevice?.div(led4SampleForDevice!!) ?: 0.0)
val deviceRatio = led1Average / led3Average
if (led1Average < 0 || led2Average < 0) {
activity?.runOnUiThread {
binding.errorMessage.text = "Warning: Negative Abs. Retake Blank Reading"
binding.errorMessage.visibility = View.VISIBLE
}
}
DataHolder.hemoCubeTestData?.apply {
deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString()
led1Buffer = led1BufferForDevice
led2Buffer = led2BufferForDevice
led3Buffer = led3BufferForDevice
led4Buffer = led4BufferForDevice
appVersion = version
this.led1Sample = led1SampleForDevice
this.led2Sample = led2SampleForDevice
this.led3Sample = led3SampleForDevice
this.led4Sample = led4SampleForDevice
this.led1Average = led1Average
this.led2Average = led2Average
this.led3Average = led3Average
this.led4Average = led4Average
this.deviceRatio = deviceRatio
this.calculatedRatio = calculateRatio(deviceRatio)
this.coefficients = currentDeviceData?.coefficients?.get(0)
.toString() + ", " + currentDeviceData?.coefficients?.get(1).toString()
this.classificationResult = findResult(calculatedRatio)
hemoCubeViewModel.messages.postValue(this.classificationResult)
this.resultData = deviceLog
if (!isUsingExistingBuffer) {
with(sharedPreferences.edit()) {
putString(Constants.BUFFER_VALUE_1, led1BufferForDevice.toString())
putString(Constants.BUFFER_VALUE_2, led2BufferForDevice.toString())
putString(Constants.BUFFER_VALUE_3, led3BufferForDevice.toString())
putString(Constants.BUFFER_VALUE_4, led4BufferForDevice.toString())
apply()
}
}
activity?.runOnUiThread {
binding.btnSubmit.visibility = View.VISIBLE
}
binding.btnSubmit.isEnabled = true
binding.btnSubmit.isClickable = true
binding.clParent.setBackgroundColor(Color.parseColor("#edfffd"))
}
} 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.05)
return "Inconclusive. Very low Absorbance - Repeat test with Higher Blood Volume"
if (calculatedRatio in 0.05..0.155)
return "Normal"
if (calculatedRatio in 0.155..0.175)
return "Negative Borderline. Repeat Test"
if (calculatedRatio in 0.175..0.22)
return "Sickle Cell Trait"
if (calculatedRatio in 0.22..0.25)
return "Positive for Sickle Cell. HPLC for Confirmation"
if (calculatedRatio in 0.25..0.35)
return "Sickle Cell Disease"
if (calculatedRatio > 0.35)
return "Inconclusive. Repeat with test with lower volume of blood"
} else {
return "NULL"
}
} catch (e: Exception) {
showToast("error while performing classification")
Firebase.crashlytics.recordException(e)
return "ERROR"
}
return "NULL"
}
private fun showToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
private fun startBufferProcess() {
hemoCubeViewModel.progressBar.postValue(true)
activity?.runOnUiThread {
binding.btnPlacebuffer.visibility = View.GONE
}
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startBuffer,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun startSampleProcess() {
testingTrace.start()
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.startSample,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun fetchResult() {
hemoCubeViewModel.progressBar.postValue(true)
(activity as HemocubeActivity).mService.sendAndListenToHemoCube(HemoCubeCommands.getSample,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {}
override fun onUsbError(e: Exception?) {
hemoCubeViewModel.progressBar.postValue(false)
}
})
}
private fun calculateRatio(ratio: Double): Double {
val coefficient1 = currentDeviceData?.coefficients?.get(0) ?: 0.0
val coefficient2 = currentDeviceData?.coefficients?.get(1) ?: 0.0
return coefficient1 * ratio + coefficient2
}
private fun checkDeviceIdMismatch(deviceId: String, loginId: String): Boolean {
if (!deviceId.isNullOrEmpty() && !loginId.isNullOrEmpty() && deviceId.last() != loginId.last())
return true
return false
}
}

View File

@@ -1,195 +0,0 @@
package com.example.hpostesting.presentation.hemocube
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.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.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 HemoCubeViewModel @Inject constructor(
private val hemoCubeDao: HemoCubeDao,
private val repository: DatabaseRepository,
context: Context,
) : ViewModel() {
var isServiceConnected = false
val progressBar = MutableLiveData(false)
val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
val messages = MutableLiveData<String>()
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 fireBaseUpload = MutableLiveData<String>()
val fireBaseBulkUpload = MutableLiveData<String>()
fun uploadHemoCubeResultToDatabase(isOnline: Boolean, testStatus: Boolean, kitSerial: String?) =
viewModelScope.launch {
if (kitSerial != null) {
testDetails?.kitSerial = kitSerial
}
testDetails?.testStatus = testStatus
try {
if (isOnline) {
parseData()
addResultTestToDb()
} else {
parseData()
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
hemoCubeDao.insertAll(testDetails!!)
fireBaseUpload.postValue("Local")
}
} catch (e: Exception) {
Log.e("Testdb", "Upload failed: ${e.message}")
}
}
fun uploadHemoCubeResultToDatabaseforbuffercheckN(bufferCheckData: BufferCheckData) =
viewModelScope.launch {
addResultTestToDbforbuffercheck(bufferCheckData)
}
fun getDeviceData(deviceId: String?) = viewModelScope.launch {
deviceData.postValue(deviceId?.let { repository.getDeviceDataById(it) })
}
private fun parseData() {
testDetails?.deviceRatio = DataHolder.hemocubeResult
testDetails?.resultData = DataHolder.hemoCubeTestData?.resultData.toString()
testDetails?.location = DataHolder.location
testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
testDetails?.appVersion = DataHolder.hemoCubeTestData?.appVersion
testDetails?.deviceId = DataHolder.hemoCubeTestData?.deviceId
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?.deviceRatio = DataHolder.hemoCubeTestData?.deviceRatio
testDetails?.calculatedRatio = DataHolder.hemoCubeTestData?.calculatedRatio
testDetails?.coefficients = DataHolder.hemoCubeTestData?.coefficients
testDetails?.classificationResult = DataHolder.hemoCubeTestData?.classificationResult!!
}
private fun addResultTestToDb() {
viewModelScope.launch {
try {
testDetails!!.reportUploadTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
when (val response = repository.addTestToDatabase(testDetails)) {
is Response.Success -> {
val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0)
with(sharedPreference.edit()) {
putInt(Constants.KIT_COUNT, kitCount.plus(1))
apply()
}
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
testDetails.localFlag = true
hemoCubeDao.insertAll(testDetails)
}
is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error")
hemoCubeDao.insertAll(testDetails)
}
}
} 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")
fireBaseUpload.postValue("Error")
}
}
} catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Error")
}
}
}
fun bulkAddResultTestToDb(userData: HemoCubeTestData) {
viewModelScope.launch {
userData.reportUploadTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(userData)) {
is Response.Success -> {
fireBaseBulkUpload.postValue("Success")
updateLocalFlag(userData._id)
}
else -> {
fireBaseBulkUpload.postValue("Error")
}
}
}
}
private fun updateLocalFlag(userId: String) = viewModelScope.launch {
hemoCubeDao.updateFieldById(id = userId, true)
}
fun deleteById(userId: String) = viewModelScope.launch {
hemoCubeDao.deleteById(id = userId)
}
}

View File

@@ -1,188 +0,0 @@
package com.example.hpostesting.presentation.hemocube
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.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 HemocubeActivity : 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 {
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 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, "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()
}
}
}
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)
}
open fun reconnectDevice() {
mService.disconnect()
unbindService(connection)
viewModel.isServiceConnected = false
connectUsb(true)
}
private fun moveToNext() {
if (supportFragmentManager.isDestroyed) return
supportFragmentManager.beginTransaction().replace(binding.fghemocube.id, HemoCubeFragment())
.commit()
}
override fun onBackPressed() {
val fragment = supportFragmentManager.findFragmentById(R.id.fghemocube)
if (fragment is HemoCubeFragment) {
fragment.handleBackButtonPress()
} else {
super.onBackPressed()
}
}
fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
if (!isFinishing) onBackPressed()
}
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

@@ -103,6 +103,17 @@ class TestRightActivity : AppCompatActivity() {
} }
} }
// private fun testing() {
// supportFragmentManager.beginTransaction()
// .replace(binding.flMain.id, TestRightExpSample()).commit()
// }
// Todo: Comment this
// private fun connectUsb(permissionGranted: Boolean) {
// setupService()
// }
// Todo: Uncomment this
private fun connectUsb(permissionGranted: Boolean) { private fun connectUsb(permissionGranted: Boolean) {
Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted") Log.d(TAG, "connectUsb() called, permission variable = $permissionGranted")
val manager = getSystemService(Context.USB_SERVICE) as UsbManager val manager = getSystemService(Context.USB_SERVICE) as UsbManager
@@ -113,6 +124,12 @@ class TestRightActivity : AppCompatActivity() {
} else { } else {
mDriver = availableDrivers[0] mDriver = availableDrivers[0]
if (mDriver.device.productId != Constants.DEVICE_PRODUCT_ID || mDriver.device.vendorId != Constants.DEVICE_VENDOR_ID){
Toast.makeText(this, "Device Connected is not supported", Toast.LENGTH_SHORT).show()
onBackPressed()
return
}
viewModel.testDetails?.deviceId = mDriver.device.serialNumber.toString() viewModel.testDetails?.deviceId = mDriver.device.serialNumber.toString()
DataHolder.deviceSerialNumber = mDriver.device.serialNumber.toString() DataHolder.deviceSerialNumber = mDriver.device.serialNumber.toString()
mConnection = manager.openDevice(mDriver.device) mConnection = manager.openDevice(mDriver.device)
@@ -125,7 +142,12 @@ class TestRightActivity : AppCompatActivity() {
} }
} }
/*
* Request user permission. The response will be received in the BroadcastReceiver
*/
private fun requestUserPermission(manager: UsbManager, device: UsbDevice) { private fun requestUserPermission(manager: UsbManager, device: UsbDevice) {
// Log.d(TAG, "requestUserPermissions() called -> vendor id = ${device.vendorId} & product id = ${device.productId}")
val mPendingIntent: PendingIntent val mPendingIntent: PendingIntent
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
mPendingIntent = PendingIntent.getBroadcast( mPendingIntent = PendingIntent.getBroadcast(
@@ -174,6 +196,11 @@ class TestRightActivity : AppCompatActivity() {
fun onErrorReported(msg: String) { fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
// Snackbar.make(binding.clParent, msg, Snackbar.LENGTH_LONG)
// .setAction("CLOSE") { Toast.makeText(this, "Will soon", Toast.LENGTH_SHORT).show() }
// .setActionTextColor(resources.getColor(R.color.white))
// .show()
if (!isFinishing) if (!isFinishing)
onBackPressed() onBackPressed()
} }
@@ -183,6 +210,16 @@ class TestRightActivity : AppCompatActivity() {
myMenu = menu myMenu = menu
return true return true
} }
// override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
// R.id.action_usb -> {
//// Toast.makeText(this, "USB Connected", Toast.LENGTH_SHORT).show()
//// myMenu?.get(0)?.icon = ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
// true
// }
// else -> {super.onOptionsItemSelected(item)}
// }
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
if (viewModel.isServiceConnected) { if (viewModel.isServiceConnected) {
@@ -191,4 +228,10 @@ class TestRightActivity : AppCompatActivity() {
viewModel.isServiceConnected = false viewModel.isServiceConnected = false
} }
} }
// fun View.setAllEnabled(enabled: Boolean) {
// isEnabled = enabled
// if (this is ViewGroup) children.forEach { child -> child.setAllEnabled(enabled) }
// }
} }

View File

@@ -24,12 +24,17 @@ import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpReferenceB
@AndroidEntryPoint @AndroidEntryPoint
class TestRightExpReference : Fragment() { class TestRightExpReference : Fragment() {
private lateinit var binding: FragmentTestRightExpReferenceBinding private lateinit var binding: FragmentTestRightExpReferenceBinding
private val viewModel: TestRightViewModel by activityViewModels() private val viewModel: TestRightViewModel by activityViewModels()
private val TAG = "TestRightExpReference" private val TAG = "TestRightExpReference"
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View { ): View {
// Inflate the layout for this fragment
binding = FragmentTestRightExpReferenceBinding.inflate(inflater, container, false) binding = FragmentTestRightExpReferenceBinding.inflate(inflater, container, false)
return binding.root return binding.root
} }
@@ -37,17 +42,25 @@ class TestRightExpReference : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setupListeners() setupListeners()
// if (DataHolder.isReferenceTaken)
// moveToSamplePage()
//
// DataHolder.sampleReadCounter <= Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE
if (DataHolder.deviceConstant == null) { if (DataHolder.deviceConstant == null) {
viewModel.progressBar.postValue(true) viewModel.progressBar.postValue(true)
Handler(Looper.getMainLooper()).postDelayed( Handler(Looper.getMainLooper()).postDelayed(
{ sendCmdToFetchDeviceConstant() }, Constants.DELAY_BETWEEN_COMMANDS { sendCmdToFetchDeviceConstant() },
Constants.DELAY_BETWEEN_COMMANDS
) )
} }
} }
private fun setupListeners() { private fun setupListeners() {
binding.btnSetReference.setOnClickListener { binding.btnSetReference.setOnClickListener {
UIUtils.createAlertDialog(requireContext(), UIUtils.createAlertDialog(
requireContext(),
getString(R.string.have_you_placed), getString(R.string.have_you_placed),
getString(R.string.please_place), getString(R.string.please_place),
getString(R.string.no), getString(R.string.no),
@@ -56,7 +69,6 @@ class TestRightExpReference : Fragment() {
override fun onClickNegativeButton() { override fun onClickNegativeButton() {
} }
override fun onClickPositiveButton() { override fun onClickPositiveButton() {
startTakingReference() startTakingReference()
} }
@@ -64,15 +76,16 @@ class TestRightExpReference : Fragment() {
} }
viewModel.errorTriggered.observe(viewLifecycleOwner) { viewModel.errorTriggered.observe(viewLifecycleOwner) {
if (it != null) { if (it != null){
UIUtils.onShowErrorToast(requireContext(), it.message) UIUtils.onShowErrorToast(requireContext(), it.message)
if (it.code == Constants.ERROR_CRITICAL) { if (it.code == Constants.ERROR_CRITICAL){
activity?.onBackPressed() activity?.onBackPressed()
} }
} }
} }
viewModel.progressBar.observe(viewLifecycleOwner) { viewModel.progressBar.observe(viewLifecycleOwner) {
// Log.d(TAG, "SURYA OBSERVER Activated outcome = $it")
if (it) { if (it) {
binding.progressBar.visibility = View.VISIBLE binding.progressBar.visibility = View.VISIBLE
binding.clParent.alpha = 0.5f binding.clParent.alpha = 0.5f
@@ -83,6 +96,7 @@ class TestRightExpReference : Fragment() {
binding.btnSetReference.isEnabled = true binding.btnSetReference.isEnabled = true
} }
} }
} }
/** /**
@@ -93,17 +107,19 @@ class TestRightExpReference : Fragment() {
* 4. command print * 4. command print
*/ */
private fun startTakingReference() { private fun startTakingReference() {
// requireActivity().runOnUiThread {
sendCmdToSetLed() sendCmdToSetLed()
// }
} }
// private fun sendCmdToFetchDeviceConstant(recursive: Boolean) {
private fun sendCmdToFetchDeviceConstant() { private fun sendCmdToFetchDeviceConstant() {
Log.d(TAG, "sendCmdToFetchDeviceConstant() called") Log.d(TAG, "sendCmdToFetchDeviceConstant() called")
viewModel.progressBar.postValue(true) viewModel.progressBar.postValue(true)
val fullReadOutput = StringBuilder() val fullReadOutput = StringBuilder()
(activity as TestRightActivity).mService.eventDrivenWrite( (activity as TestRightActivity).mService.eventDrivenWrite(TestRightCommands.read,
TestRightCommands.read,
object : UsbServiceListener { object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
data?.let { data?.let {
@@ -113,7 +129,8 @@ class TestRightExpReference : Fragment() {
if (stringData.contains("OK", true)) { if (stringData.contains("OK", true)) {
Log.d( Log.d(
TAG, "onUsbRead() called in sendCmdToFetchDeviceConstant() found OK" TAG,
"onUsbRead() called in sendCmdToFetchDeviceConstant() found OK"
) )
viewModel.mapDeviceConstants(fullReadOutput.toString()) viewModel.mapDeviceConstants(fullReadOutput.toString())
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
@@ -121,11 +138,7 @@ class TestRightExpReference : Fragment() {
Log.d(TAG, "results = FINE") Log.d(TAG, "results = FINE")
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
viewModel.errorTriggered.postValue( viewModel.errorTriggered.postValue(ErrorMessage("Please Try Again!!", Constants.ERROR_CRITICAL))
ErrorMessage(
"Please Try Again!!", Constants.ERROR_CRITICAL
)
)
} }
} }
@@ -133,11 +146,7 @@ class TestRightExpReference : Fragment() {
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
Log.e(TAG, "onUsbIoError() called in sendCmdToFetchDeviceConstant() -> $e") Log.e(TAG, "onUsbIoError() called in sendCmdToFetchDeviceConstant() -> $e")
viewModel.errorTriggered.postValue( viewModel.errorTriggered.postValue(ErrorMessage("Please Try Again this step", Constants.ERROR_NORMAL))
ErrorMessage(
"Please Try Again this step", Constants.ERROR_NORMAL
)
)
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
} }
@@ -162,7 +171,8 @@ class TestRightExpReference : Fragment() {
Runnable { Runnable {
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
sendCmdToAutoset() sendCmdToAutoset()
}, Constants.DELAY_BETWEEN_COMMANDS },
Constants.DELAY_BETWEEN_COMMANDS
) )
} }
} }
@@ -193,7 +203,8 @@ class TestRightExpReference : Fragment() {
Runnable { Runnable {
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
sendCmdToRun() sendCmdToRun()
}, Constants.DELAY_BETWEEN_COMMANDS },
Constants.DELAY_BETWEEN_COMMANDS
) )
} }
@@ -226,10 +237,12 @@ class TestRightExpReference : Fragment() {
Runnable { Runnable {
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
sendCmdToFetchLightIntensities() sendCmdToFetchLightIntensities()
}, Constants.DELAY_BETWEEN_COMMANDS },
Constants.DELAY_BETWEEN_COMMANDS
) )
} }
} }
// }
} }
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
@@ -251,15 +264,18 @@ class TestRightExpReference : Fragment() {
data?.let { data?.let {
val stringData = String(it) val stringData = String(it)
fullReadOutput.append(stringData) fullReadOutput.append(stringData)
if (stringData.trim().isNotEmpty() && fullReadOutput.substring(
Math.max( // Log.d(TAG, stringData)
fullReadOutput.length - 15, 0 // if (stringData.contains("OK", true)) {
) // if (fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK", true)) {
).contains("OK [0]", true) if (stringData.trim().isNotEmpty() && fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK [0]", true)) {
) {
Log.d(TAG, "onUsbRead() called in sendCmdToFetchLightIntensities()") Log.d(TAG, "onUsbRead() called in sendCmdToFetchLightIntensities()")
// Log.d(TAG, fullReadOutput.toString())
viewModel.mapIntensityValues(fullReadOutput.toString(), true) viewModel.mapIntensityValues(fullReadOutput.toString(), true)
// viewModel.saveLogTest(requireContext().applicationContext, true, fullReadOutput.toString())
DataHolder.isReferenceTaken = true DataHolder.isReferenceTaken = true
Handler(Looper.getMainLooper()).postDelayed( Handler(Looper.getMainLooper()).postDelayed(
@@ -274,11 +290,7 @@ class TestRightExpReference : Fragment() {
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
Log.e(TAG, "onUsbIoError() called in sendCmdToFetchLightIntensities() -> $e") Log.e(TAG, "onUsbIoError() called in sendCmdToFetchLightIntensities() -> $e")
viewModel.errorTriggered.postValue( viewModel.errorTriggered.postValue(ErrorMessage("Please Try Again this step", Constants.ERROR_NORMAL))
ErrorMessage(
"Please Try Again this step", Constants.ERROR_NORMAL
)
)
viewModel.progressBar.postValue(false) viewModel.progressBar.postValue(false)
} }

View File

@@ -8,6 +8,7 @@ import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
@@ -35,7 +36,16 @@ class TestRightExpSample : Fragment() {
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
// Inflate the layout for this fragment
binding = FragmentTestRightExpSampleBinding.inflate(inflater, container, false) binding = FragmentTestRightExpSampleBinding.inflate(inflater, container, false)
// if (DataHolder.sampleReadCounter > Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE) {
// binding.btnUpdateReference.enable()
// binding.clInstructions.setAllEnabled(false)
// } else {
// binding.btnUpdateReference.disable()
// binding.clInstructions.setAllEnabled(false)
// }
return binding.root return binding.root
} }
@@ -66,6 +76,10 @@ class TestRightExpSample : Fragment() {
} }
binding.btnSubmit.setOnClickListener { binding.btnSubmit.setOnClickListener {
// val details = validateAndReturnTestData()
// if (details != null) {
// viewModel.patientDetails = details
UIUtils.createAlertDialog( UIUtils.createAlertDialog(
requireContext(), requireContext(),
"WARNING", "WARNING",
@@ -98,13 +112,24 @@ class TestRightExpSample : Fragment() {
val i = Intent(requireContext(), MainActivity::class.java) val i = Intent(requireContext(), MainActivity::class.java)
startActivity(i) startActivity(i)
} }
// binding.etNameBlock.setOnClickListener { binding.etName.isErrorEnabled = false }
// binding.etAgeBlock.setOnClickListener { binding.etAge.isErrorEnabled = false }
// binding.etGenderBlock.setOnClickListener { binding.ddGender.isErrorEnabled = false }
} }
// private fun validateAndReturnTestData(): TestDetails? {
//
// return PatientData(name.toString(), age.toString().toInt(), gender.toString(), TestRightResultType.UNDEFINED)
// }
/** /**
* Executing the commands sequentially each after successfully executing one. * Executing the commands sequentially each after successfully executing one.
* 1. command run * 1. command run
* 2. command print * 2. command print
*/ */
private fun startAcquiring() { private fun startAcquiring() {
// binding.progressBar.visibility = View.VISIBLE
sendCmdToRun() sendCmdToRun()
} }
@@ -120,6 +145,9 @@ class TestRightExpSample : Fragment() {
val stringData = String(it) val stringData = String(it)
fullReadOutput.append(stringData) fullReadOutput.append(stringData)
Log.d(TAG, stringData) Log.d(TAG, stringData)
// if (stringData.contains("OK", true)) {
// if (stringData.contains("OK", true) || fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK", true)) {
// if (fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK", true)) {
if (fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK [0]", true)) { if (fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK [0]", true)) {
Log.d(TAG, "onUsbRead() called in sendCmdToRun()") Log.d(TAG, "onUsbRead() called in sendCmdToRun()")
Handler(Looper.getMainLooper()).postDelayed( Handler(Looper.getMainLooper()).postDelayed(
@@ -156,10 +184,17 @@ class TestRightExpSample : Fragment() {
val stringData = String(it) val stringData = String(it)
fullReadOutput.append(stringData) fullReadOutput.append(stringData)
Log.d(TAG, stringData) Log.d(TAG, stringData)
// if (stringData.contains("OK", true)) {
// if (stringData.contains("OK", true) || stringData.contains("O", true) || stringData.contains("K", true)) {
// if (stringData.contains("OK", true) || fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK", true)) {
// if (fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK", true)) {
if (stringData.trim().isNotEmpty() && fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK [0]", true)) { if (stringData.trim().isNotEmpty() && fullReadOutput.substring(Math.max(fullReadOutput.length - 15, 0)).contains("OK [0]", true)) {
Log.d(TAG, "onUsbRead() called in sendCmdToFetchLightIntensities()") Log.d(TAG, "onUsbRead() called in sendCmdToFetchLightIntensities()")
viewModel.mapIntensityValues(fullReadOutput.toString(), false) viewModel.mapIntensityValues(fullReadOutput.toString(), false)
// viewModel.saveLogTest(requireContext().applicationContext, false, fullReadOutput.toString())
// showResultsAfterAcquiring()
Handler(Looper.getMainLooper()).postDelayed( Handler(Looper.getMainLooper()).postDelayed(
{ {
checkIfToRunAgain() checkIfToRunAgain()
@@ -185,11 +220,15 @@ class TestRightExpSample : Fragment() {
viewModel.mapWavelengthToAbsorbance() viewModel.mapWavelengthToAbsorbance()
// Todo: Save CSV + Test CSV
if (DataHolder.selectedTestType == TestType.SICKLECERT) { if (DataHolder.selectedTestType == TestType.SICKLECERT) {
viewModel.calculateResults() viewModel.calculateResults()
} else { } else {
viewModel.calculateResultsForSickleFind() viewModel.calculateResultsForSickleFind()
} }
// Todo: Save Log
saveDataLocally() saveDataLocally()
if (viewModel.numberOfSampleRun < Constants.NO_OF_TIMES_TO_RUN_SAMPLE) { if (viewModel.numberOfSampleRun < Constants.NO_OF_TIMES_TO_RUN_SAMPLE) {
@@ -206,13 +245,36 @@ class TestRightExpSample : Fragment() {
} }
private fun showResultsAfterAcquiring() { private fun showResultsAfterAcquiring() {
viewModel.progressBar.postValue(false) // viewModel.mapWavelengthToAbsorbance()
parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightResults()) // viewModel.calculateResults()
.commit()
if (viewModel.calculationData.absorbanceOne!! < 0 || viewModel.calculationData.absorbanceTwo!! < 0) {
Toast.makeText(requireContext(), " ", Toast.LENGTH_SHORT).show()
viewModel.progressBar.postValue(false)
} else {
parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightResults())
.commit()
}
} }
private fun saveDataLocally() { private fun saveDataLocally() {
// OLD ------------------------------
// val patientName = viewModel.testDetails?.patientName
// if (patientName.length > 5){
// patientName = patientName.substring(0, 5)
// }
// val id = PreferenceUtility.generateId(requireContext())
// val prefixCsv: String = if (DataHolder.selectedTestType == TestType.SICKLECERT)
// "HPOSSC_${DataHolder.deviceSerialNumber}_${patientName}_"
// else
// "HPOSSF_${DataHolder.deviceSerialNumber}_${patientName}_"
// val fileNameCsv = prefixCsv + id + fileExtensionCsv
// NEW ------------------------------
viewModel.saveCsv(requireContext().applicationContext, viewModel.getCSVFileName()) viewModel.saveCsv(requireContext().applicationContext, viewModel.getCSVFileName())
// viewModel.saveCsvForTesting(requireContext().applicationContext, viewModel.getDetailedCSVFileName())
viewModel.saveLogWithPatient(requireContext().applicationContext, viewModel.getLogFileName()) viewModel.saveLogWithPatient(requireContext().applicationContext, viewModel.getLogFileName())
} }

View File

@@ -38,6 +38,7 @@ class TestRightResults : Fragment() {
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View { ): View {
// Inflate the layout for this fragment
binding = FragmentTestRightResultsBinding.inflate(inflater, container, false) binding = FragmentTestRightResultsBinding.inflate(inflater, container, false)
sharedPreference = sharedPreference =
requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE) requireContext().getSharedPreferences("PREFERENCE_NAME", Context.MODE_PRIVATE)
@@ -50,12 +51,20 @@ class TestRightResults : Fragment() {
updateResults() updateResults()
viewModel.fireBaseUpload.observe(viewLifecycleOwner) { viewModel.fireBaseUpload.observe(viewLifecycleOwner) {
if (it == "Success") { when (it) {
Toast.makeText( "Success" -> {
requireContext(), "Test Results Upload Successfully", Toast.LENGTH_SHORT Toast.makeText(
).show() requireContext(), "Test Results Upload Successfully", Toast.LENGTH_SHORT
).show()
binding.progressBar.visibility = View.GONE
}
"Loading" -> {
binding.progressBar.visibility = View.VISIBLE
}
else -> {
Toast.makeText(requireContext(), "Test upload failed, please try again $it", Toast.LENGTH_SHORT).show()
}
} }
binding.progressBar.visibility = View.GONE
} }
} }
@@ -84,17 +93,15 @@ class TestRightResults : Fragment() {
db.collection("patientData").whereEqualTo("_id", viewModel.testDetails?._id) db.collection("patientData").whereEqualTo("_id", viewModel.testDetails?._id)
.get().await() .get().await()
if (userdata.documents.isNotEmpty()) { if (userdata.documents.isNotEmpty()) {
db.collection("patientData").document(userdata.documents[0].id) userdata.documents.forEach {
.update("bloodGroup", bloodGroup) db.collection("patientData").document(it.id).update("bloodGroup", bloodGroup)
withContext(Dispatchers.Main) {
val i = Intent(
requireContext().applicationContext,
DashboardActivity::class.java
)
startActivity(i)
} }
} }
} }
withContext(Dispatchers.Main) {
val i = Intent(requireContext().applicationContext, DashboardActivity::class.java)
startActivity(i)
}
} }
} }
@@ -114,6 +121,36 @@ class TestRightResults : Fragment() {
if (DataHolder.selectedTestType == TestType.SICKLECERT) { if (DataHolder.selectedTestType == TestType.SICKLECERT) {
// when (viewModel.testDetails?.result) {
// TestRightResultType.NORMAL -> {
// binding.resultNormal.visibility = View.VISIBLE
// }
//
// TestRightResultType.SICKLECELLDISEASE -> {
// binding.resultDisease.visibility = View.VISIBLE
// }
//
// TestRightResultType.SICKLECELLTRAIT -> {
// binding.resultTrait.visibility = View.VISIBLE
// }
//
// TestRightResultType.POSITIVEBORDERLINE -> {
// binding.resultPositiveBorderline.visibility = View.VISIBLE
// binding.tvRecommended.visibility = View.VISIBLE
// }
//
// TestRightResultType.NEGATIVEBORDERLINE -> {
// binding.resultNegativeBorderline.visibility = View.VISIBLE
// binding.tvRecommended.visibility = View.VISIBLE
// }
// else -> {
//// binding.resultUndefined.visibility = View.VISIBLE
// Toast.makeText(
// requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG
// ).show()
// moveToSamplePage()
// }
// }
binding.resultNormal.visibility = View.VISIBLE binding.resultNormal.visibility = View.VISIBLE
} else { } else {
when (viewModel.testDetails?.result) { when (viewModel.testDetails?.result) {
@@ -137,11 +174,16 @@ class TestRightResults : Fragment() {
} }
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable -> viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
val deviceStaticId = sharedPreference.getString(Constants.USER_ID, "") val deviceStaticId = sharedPreference.getString(Constants.USER_ID, "")
val token = sharedPreference.getString(Constants.TOKEN,"")
if (isNetworkAvailable) { if (isNetworkAvailable) {
viewModel.uploadResultToDatabase(requireContext(), true, deviceStaticId!!) if (token != null) {
viewModel.uploadResultToDatabase(requireContext(), true, deviceStaticId!!,token)
}
binding.progressBar.visibility = View.VISIBLE binding.progressBar.visibility = View.VISIBLE
} else { } else {
viewModel.uploadResultToDatabase(requireContext(), false, deviceStaticId!!) if (token != null) {
viewModel.uploadResultToDatabase(requireContext(), false, deviceStaticId!!,token)
}
Toast.makeText( Toast.makeText(
requireContext(), requireContext(),
"Internet not available, Test Data added to Local DB", "Internet not available, Test Data added to Local DB",
@@ -163,4 +205,6 @@ class TestRightResults : Fragment() {
.commit() .commit()
} }
} }
} }

View File

@@ -8,11 +8,13 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.hpostesting.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpostesting.data.NetworkStatusLiveData import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpostesting.data.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.dao.UserDao import com.example.hpostesting.data.dao.UserDao
import com.example.hpostesting.data.model.CalculationVariableForTest import com.example.hpostesting.data.model.CalculationVariableForTest
import com.example.hpostesting.data.model.ErrorMessage import com.example.hpostesting.data.model.ErrorMessage
import com.example.hpostesting.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpostesting.data.model.patient.MolbioLogin
import com.example.hpostesting.data.model.patient.UserData import com.example.hpostesting.data.model.patient.UserData
import com.example.hpostesting.data.model.test.TestRightCalculationData import com.example.hpostesting.data.model.test.TestRightCalculationData
import com.example.hpostesting.data.model.test.TestRightDeviceConstants import com.example.hpostesting.data.model.test.TestRightDeviceConstants
@@ -25,9 +27,13 @@ import com.example.hpostesting.domain.SickleFindResultCaluculationWithMaxImpl
import com.example.hpostesting.domain.TestRightResultCalculation import com.example.hpostesting.domain.TestRightResultCalculation
import com.example.hpostesting.util.MyUtils import com.example.hpostesting.util.MyUtils
import com.google.firebase.storage.FirebaseStorage import com.google.firebase.storage.FirebaseStorage
import com.google.gson.JsonObject
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await import kotlinx.coroutines.tasks.await
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
@@ -52,17 +58,19 @@ class TestRightViewModel @Inject constructor(
val errorTriggered = MutableLiveData<ErrorMessage>() val errorTriggered = MutableLiveData<ErrorMessage>()
var numberOfSampleRun = 0 var numberOfSampleRun = 0
val loginResponse = MutableLiveData<Result<MolbioLogin>>()
val fireBaseUpload = MutableLiveData<String>() val fireBaseUpload = MutableLiveData<String>()
val testDetails = DataHolder.selectedTest val testDetails = DataHolder.selectedTest
private val _networkStatusLiveData = NetworkStatusLiveData(context) private val _networkStatusLiveData = NetworkStatusLiveData(context)
val networkStatusLiveData: LiveData<Boolean> val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData get() = _networkStatusLiveData
val allUserData = userDao.getAll() val allUserData = userDao.getAll()
private lateinit var calculationData: TestRightCalculationData lateinit var calculationData: TestRightCalculationData
/* (For exp sample) Contains pixel no. -> Intensity of light falling on that pixel */
val intensitySampleArray = ArrayList<Double>() val intensitySampleArray = ArrayList<Double>()
val wavelengthToAbsorbance = ArrayList<ArrayList<Double>>() val wavelengthToAbsorbance = ArrayList<ArrayList<Double>>()
@@ -70,6 +78,8 @@ class TestRightViewModel @Inject constructor(
val calculationVariableList = ArrayList<CalculationVariableForTest>() val calculationVariableList = ArrayList<CalculationVariableForTest>()
fun mapDeviceConstants(string: String) { fun mapDeviceConstants(string: String) {
// Log.d(TAG, "mapDeviceConstants() called")
// Log.d(TAG, "mapDeviceConstants() value -> $string")
if (string.isNotEmpty()) { if (string.isNotEmpty()) {
val listOfStrings = string.split(",") val listOfStrings = string.split(",")
if (listOfStrings.size >= 4) { if (listOfStrings.size >= 4) {
@@ -430,7 +440,7 @@ class TestRightViewModel @Inject constructor(
return prefixTxt + fileExtensionTxt return prefixTxt + fileExtensionTxt
} }
private fun addResultTestToDb() { private fun addResultTestToDb(csvFilePath: String, logTxtFilePath: String, token: String) {
testDetails?.testTime = SimpleDateFormat( testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
@@ -440,15 +450,51 @@ class TestRightViewModel @Inject constructor(
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(testDetails)) { when (repository.addTestToDatabase(testDetails)) {
is Response.Success -> { is Response.Success -> {
fireBaseUpload.postValue("Success") uploadToMolbio(csvFilePath, logTxtFilePath, token)
} }
else -> {} else -> {}
} }
} }
} }
fun uploadResultToDatabase(context: Context, isOnline: Boolean,deviceSerialNumber: String) = viewModelScope.launch { private fun uploadToMolbio(csvFilePath: String, logTxtFilePath: String, token: String) = viewModelScope.launch {
val csv_file = File(csvFilePath)
val log_file=File(logTxtFilePath)
val csv_reqBody = RequestBody.create(MediaType.parse("text/csv"), csv_file)
val log_reqBody = RequestBody.create(MediaType.parse("text/txt"), log_file)
val deviceId= testDetails?.deviceSerialNumber?.let {
RequestBody.create(MediaType.parse("text/plain"),
it
)
}
val userId= testDetails?._id?.let { RequestBody.create(MediaType.parse("text/plain"), it) }
val csv_formData = MultipartBody.Part.createFormData("csv_file", csv_file.name, csv_reqBody)
val log_formData = MultipartBody.Part.createFormData("csv_file", log_file.name, log_reqBody)
val count = "1".let {
RequestBody.create(MediaType.parse("text/plain"),
it
)
}
repository.uploadPdf(token, count, userId!!, csv_formData, log_formData, deviceId!!).let { upload ->
when(upload) {
is Result.Success -> {
fireBaseUpload.postValue("Success")
}
is Result.Error -> {
fireBaseUpload.postValue(upload.exception.message)
}
else -> {
}
}
}
}
fun uploadResultToDatabase(context: Context, isOnline: Boolean, deviceSerialNumber: String, token: String) = viewModelScope.launch {
fireBaseUpload.postValue("Loading")
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName() val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName()
val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName() val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName()
testDetails?.csvPath = csvFilePath testDetails?.csvPath = csvFilePath
@@ -473,8 +519,7 @@ class TestRightViewModel @Inject constructor(
val serialNumber = Constants.STATICID.firstOrNull { it == deviceSerialNumber } val serialNumber = Constants.STATICID.firstOrNull { it == deviceSerialNumber }
testDetails?.csvPath = csvUri testDetails?.csvPath = csvUri
testDetails?.reportPath = logUri testDetails?.reportPath = logUri
addResultTestToDb(csvFilePath, logTxtFilePath, token)
addResultTestToDb()
} catch (exception: Exception) { } catch (exception: Exception) {
// Handle the exception appropriately (e.g., log the error, display an error message) // Handle the exception appropriately (e.g., log the error, display an error message)
} }
@@ -482,11 +527,14 @@ class TestRightViewModel @Inject constructor(
testDetails?.testTime = SimpleDateFormat( testDetails?.testTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
userDao.insertAll(testDetails!!) userDao.insertAll(testDetails!!).let {
fireBaseUpload.postValue("Success")
}
} }
} }
fun bulkUploadResultToDatabase(userData: UserData) = viewModelScope.launch { fun bulkUploadResultToDatabase(userData: UserData, token: String?) = viewModelScope.launch {
fireBaseUpload.postValue("Loading")
val storageRef = FirebaseStorage.getInstance().reference val storageRef = FirebaseStorage.getInstance().reference
val storageTestDetailsRef = storageRef.child("${testDetails?._id}/") val storageTestDetailsRef = storageRef.child("${testDetails?._id}/")
try { try {
@@ -503,24 +551,31 @@ class TestRightViewModel @Inject constructor(
val csvUri = csvUploadTask.storage.downloadUrl.await().toString() val csvUri = csvUploadTask.storage.downloadUrl.await().toString()
val logUri = logUploadTask.storage.downloadUrl.await().toString() val logUri = logUploadTask.storage.downloadUrl.await().toString()
val csvFilePath = userData.csvPath
val logTxtFilePath = userData.reportPath
userData.csvPath = csvUri userData.csvPath = csvUri
userData.reportPath = logUri userData.reportPath = logUri
bulkAddResultTestToDb(userData, csvFilePath, logTxtFilePath, token)
bulkAddResultTestToDb(userData)
} catch (exception: Exception) { } catch (exception: Exception) {
// Handle the exception appropriately (e.g., log the error, display an error message) // Handle the exception appropriately (e.g., log the error, display an error message)
} }
} }
private fun bulkAddResultTestToDb(userData: UserData) { private fun bulkAddResultTestToDb(
userData: UserData,
csvFilePath: String,
logTxtFilePath: String,
token: String?
) {
viewModelScope.launch { viewModelScope.launch {
userData.reportUploadTime = SimpleDateFormat( userData.reportUploadTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault() "yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
when (repository.addTestToDatabase(userData)) { when (repository.addTestToDatabase(userData)) {
is Response.Success -> { is Response.Success -> {
fireBaseUpload.postValue("Success") uploadToMolbio(csvFilePath, logTxtFilePath, token!!)
} }
else -> {} else -> {}
@@ -531,4 +586,13 @@ class TestRightViewModel @Inject constructor(
fun deleteById(userId: String) = viewModelScope.launch { fun deleteById(userId: String) = viewModelScope.launch {
userDao.deleteById(id = userId) userDao.deleteById(id = userId)
} }
fun login(jsonObject: JsonObject) = viewModelScope.launch {
loginResponse.postValue(Result.Loading())
repository.login(jsonObject).let {
loginResponse.postValue(it)
}
}
} }

View File

@@ -7,40 +7,46 @@ import android.os.Binder
import android.os.IBinder import android.os.IBinder
import android.util.Log import android.util.Log
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.constant.TestRightCommands import com.example.hpostesting.data.constant.TestRightCommands
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.UsbServiceListener
import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialPort import com.hoho.android.usbserial.driver.UsbSerialPort
import com.hoho.android.usbserial.util.SerialInputOutputManager import com.hoho.android.usbserial.util.SerialInputOutputManager
import java.io.IOException import java.io.IOException
class UsbService : Service() { class UsbService : Service() {
// Binder to be given to clients
private val binder = UsbServiceBinder() private val binder = UsbServiceBinder()
private lateinit var mPort: UsbSerialPort private lateinit var mPort: UsbSerialPort
private var isUsbConnected = false private var isUsbConnected = false
private val TAG = "UsbService" private val TAG = "UsbService"
inner class UsbServiceBinder : Binder() { inner class UsbServiceBinder : Binder() {
// Return this instance of UsbService so clients can call public methods
fun getService(): UsbService = this@UsbService fun getService(): UsbService = this@UsbService
} }
override fun onBind(intent: Intent): IBinder { override fun onBind(intent: Intent): IBinder {
Log.d("surya", "onBind() called")
return binder return binder
} }
var listener: UsbServiceListener? = null var listener: UsbServiceListener? = null
var bus: UsbServiceListener? = null
fun connect(driver: UsbSerialDriver, connection: UsbDeviceConnection) { fun connect(driver: UsbSerialDriver, connection: UsbDeviceConnection) {
// Todo: Uncomment this
mPort = driver.ports[0] // Most devices have just one port (port 0) mPort = driver.ports[0] // Most devices have just one port (port 0)
mPort.open(connection) 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 isUsbConnected = true
Log.d(TAG, "My Usb Connected ${mPort.driver}") Log.d(TAG, "My Usb Connected ${mPort.driver}")
val usbIoManager = SerialInputOutputManager(mPort, val usbIoManager = SerialInputOutputManager(mPort,
object : SerialInputOutputManager.Listener{ object : SerialInputOutputManager.Listener{
override fun onNewData(data: ByteArray?) { override fun onNewData(data: ByteArray?) {
// Log.e(TAG, "onNewData() called inside eventDrivenWrite()")
listener?.onUsbRead(data) listener?.onUsbRead(data)
} }
override fun onRunError(e: Exception?) { override fun onRunError(e: Exception?) {
@@ -51,6 +57,7 @@ class UsbService : Service() {
}) })
usbIoManager.start(); usbIoManager.start();
} }
fun disconnect() { fun disconnect() {
if(isUsbConnected){ if(isUsbConnected){
mPort.close() mPort.close()
@@ -58,6 +65,45 @@ class UsbService : Service() {
Log.d(TAG, "My Usb disconnected:: ${mPort.driver}") Log.d(TAG, "My Usb disconnected:: ${mPort.driver}")
} }
} }
// Todo: comment this
// fun eventDrivenWrite(command: TestRightCommands, listener: UsbServiceListener) {
// this.listener = listener
// try {
// when (command) {
// TestRightCommands.autoset -> {
// this.listener!!.onUsbRead("OK".toByteArray())
// }
// TestRightCommands.led2Set50 -> {
// this.listener!!.onUsbRead("OK".toByteArray())
// }
// TestRightCommands.run -> {
// this.listener!!.onUsbRead("OK [0]".toByteArray())
// }
// TestRightCommands.read -> {
// this.listener!!.onUsbRead(InputData().inputRead.toByteArray())
// }
// TestRightCommands.printAll -> {
// if (DataHolder.testExp) {
// for (each in InputData().printForReference.lines()) {
// this.listener!!.onUsbRead((each + "\n").toByteArray())
// }
// } else {
// for (each in InputData().printForSample.lines()) {
// this.listener!!.onUsbRead((each + "\n").toByteArray())
// }
// }
// }
// else -> {
// this.listener!!.onUsbRead("OK".toByteArray())
// }
// }
// } catch (e: IOException) {
// listener.onUsbError(e)
// }
// }
// Todo: Uncomment this
fun eventDrivenWrite(command: TestRightCommands, listener: UsbServiceListener) { fun eventDrivenWrite(command: TestRightCommands, listener: UsbServiceListener) {
this.listener = listener this.listener = listener
try { try {
@@ -67,21 +113,19 @@ class UsbService : Service() {
} }
} }
fun listenToHemoCube(listener: UsbServiceListener) { // fun write(command: TestRightCommands){
this.listener = listener // mPort.write(command.command.toByteArray(), Constants.WRITE_TIMEOUT_MILLIS)
try { // }
} catch (e: IOException) { // fun read(){
listener.onUsbError(e) // val byteArray = ByteArray(3700)
} // val len = mPort.read(byteArray, Constants.READ_TIMEOUT_MILLIS)
} //
// Log.d(TAG, "length is $len")
// val byteArrayCropped = ByteArray(len)
// System.arraycopy(byteArray, 0, byteArrayCropped, 0, len)
//
// listener?.onUsbRead(byteArrayCropped)
// }
fun sendAndListenToHemoCube(command: HemoCubeCommands, listener: UsbServiceListener) {
try {
this.bus = listener
mPort.write(command.command.toByteArray(), Constants.WRITE_TIMEOUT_MILLIS)
} catch (e: IOException) {
listener.onUsbError(e)
}
}
} }

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

@@ -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,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/fghemocube"
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.hemocube.HemocubeActivity">
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

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,243 +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.hemocube.DigitalCardFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fragment_container">
<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">
<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"
tools:src="@drawable/karnataka" />
<ImageView
android:id="@+id/userName"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="46dp"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toTopOf="@+id/userImage"
tools:src="@drawable/sickle_cell_gov_logo"/>
<ImageView
android:id="@+id/userImage3"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="36dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/userName"
app:layout_constraintTop_toTopOf="@+id/userName"
tools:src="@drawable/indianoil"/>
<ImageView
android:id="@+id/userImage4"
android:layout_width="80dp"
android:layout_height="100dp"
android:layout_marginTop="30dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/userImage"
tools:src="@drawable/person" />
<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:layout_constraintStart_toEndOf="@+id/userImage4"
app:cardElevation="0dp">
<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="80dp"
android:layout_height="20dp"
android:layout_marginStart="16dp"
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="16dp"
android:layout_marginTop="50dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="8sp"
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>
</layout>

View File

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

@@ -1,225 +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.hemocube.HemoCubeFragment">
<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"
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"
android:gravity="center"
android:padding="12dp"
android:layout_marginTop="26dp"
android:textFontWeight="700"
android:text="Name: SMI\n ID: 1672282828"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints" />
<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="72dp"
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/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" />
<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"
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" />
<TextView
android:id="@+id/error_message"
style="@style/title1_1"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="172dp"
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/btn_submit" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:elevation="12dp"
android:indeterminate="true"
android:indeterminateDrawable="@drawable/progressbar_drawable"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -5,19 +5,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView
android:id="@+id/pendingTest"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:visibility="gone"
android:text="@string/all_registered_user_are_tested_successfully"
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.constraintlayout.widget.ConstraintLayout
android:id="@+id/internetNotAvailableCL" android:id="@+id/internetNotAvailableCL"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -70,6 +57,7 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/internetAvailableCL" android:id="@+id/internetAvailableCL"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -194,27 +182,6 @@
app:layout_constraintTop_toBottomOf="@+id/radioGroup" app:layout_constraintTop_toBottomOf="@+id/radioGroup"
tools:listitem="@layout/user_item_view"/> 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> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,99 +1,75 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <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" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/userCard" android:id="@+id/userCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
app:cardBackgroundColor="@color/primary_light"
app:cardCornerRadius="25dp"
app:cardElevation="0dp"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="24dp" android:padding="12dp">
app:cardBackgroundColor="@color/primary_light"
app:cardCornerRadius="25dp"
app:cardElevation="0dp"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout <ImageView
android:layout_width="match_parent" android:id="@+id/userImage"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/userName"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="12dp"> android:fontFamily="@font/poppins_bold"
android:layout_marginTop="16dp"
android:gravity="center"
android:textColor="@color/black"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/userImage" />
<ImageView <TextView
android:id="@+id/userImage" android:id="@+id/userId"
android:layout_width="100dp" android:layout_width="0dp"
android:layout_height="100dp" android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent" android:fontFamily="@font/poppins_bold"
app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="16dp"
tools:src="@drawable/ic_launcher_foreground" /> android:gravity="center"
android:textColor="@color/black"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/userName" />
<TextView <TextView
android:id="@+id/userName" android:id="@+id/teststatus"
style="@style/title1_1" android:layout_width="0dp"
android:layout_width="0dp" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:fontFamily="@font/poppins_bold"
android:layout_marginStart="16dp" android:layout_marginTop="16dp"
android:gravity="start" android:gravity="center"
android:textColor="@color/black" android:textColor="@color/black"
android:textSize="14sp" android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/userImage" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/userImage" app:layout_constraintTop_toBottomOf="@id/userId" />
tools:text="Name: MohamedKaif" />
<TextView
android:id="@+id/userId"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toBottomOf="@id/userName"
tools:text="UserID: MohamedKaif" />
<TextView </androidx.constraintlayout.widget.ConstraintLayout>
android:id="@+id/teststatus"
android:layout_width="0dp"
android:layout_height="wrap_content"
style="@style/title1_1"
android:layout_marginTop="4dp"
android:layout_marginStart="16dp"
android:gravity="start"
android:textColor="@color/black"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/userImage"
app:layout_constraintTop_toBottomOf="@id/userId"
tools:text="Test Status: Completed"/>
<Button </androidx.cardview.widget.CardView>
android:id="@+id/btn_startIncubation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:text="@string/start_incubation"
android:visibility="gone"
android:textColor="@color/white"
app:layout_constraintStart_toEndOf="@+id/btn_blood"
app:layout_constraintBottom_toBottomOf="@+id/btn_blood" />
<Button
android:id="@+id/btn_blood"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:text="@string/blood_group"
android:textColor="@color/white"
app:layout_constraintEnd_toStartOf="@+id/btn_startIncubation"
app:layout_constraintTop_toBottomOf="@id/teststatus" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -47,5 +47,4 @@
app:popUpTo="@id/mobile_navigation" app:popUpTo="@id/mobile_navigation"
app:popUpToInclusive="true"/> app:popUpToInclusive="true"/>
</fragment> </fragment>
</navigation> </navigation>

View File

@@ -44,8 +44,6 @@
<string name="please_place">Please place the cuvette containing sample for reference before running</string> <string name="please_place">Please place the cuvette containing sample for reference before running</string>
<string name="yes">Yes</string> <string name="yes">Yes</string>
<string name="no">No</string> <string name="no">No</string>
<string name="noo"></string>
<string name="connect">Connect</string> <string name="connect">Connect</string>
<string name="connected">Connected</string> <string name="connected">Connected</string>
@@ -112,11 +110,6 @@
<string name="sickle_cert">Sickle Cert</string> <string name="sickle_cert">Sickle Cert</string>
<string name="sickle_find">Sickle Find</string> <string name="sickle_find">Sickle Find</string>
<string name="submit">Submit</string> <string name="submit">Submit</string>
<string name="diagnostics">Device Diagnostics</string>
<string name="place_buffer">Start</string>
<string name="Start_Sample">Start Sample</string>
<string name="new_kit">New Kit</string>
<string name="new_buffer">New Buffer</string>
<string name="name_error_2">Invalid character, Allowed characters are Letters, Numbers and ( ) _ - , . only</string> <string name="name_error_2">Invalid character, Allowed characters are Letters, Numbers and ( ) _ - , . only</string>
<string name="recommended">\*Result to be confirmed with laboratory test</string> <string name="recommended">\*Result to be confirmed with laboratory test</string>
<string name="recommended_age">\*Result to be confirmed with laboratory test as age of the patient is less than 5 years</string> <string name="recommended_age">\*Result to be confirmed with laboratory test as age of the patient is less than 5 years</string>
@@ -149,7 +142,6 @@
<string name="action_settings">Settings</string> <string name="action_settings">Settings</string>
<string name="menu_home">Home</string> <string name="menu_home">Home</string>
<string name="show_hemocube_result">Show Result</string>
<string name="menu_gallery">Gallery</string> <string name="menu_gallery">Gallery</string>
<string name="menu_settings">Settings</string> <string name="menu_settings">Settings</string>
<string name="profile">Profile</string> <string name="profile">Profile</string>
@@ -158,7 +150,6 @@
<string name="is_patient_married_yes_no">Is Patient Married? (Yes/No)</string> <string name="is_patient_married_yes_no">Is Patient Married? (Yes/No)</string>
<string name="category">Category</string> <string name="category">Category</string>
<string name="blood_group">Blood Group</string> <string name="blood_group">Blood Group</string>
<string name="digital_card">Digital Counselling Card</string>
<string name="patient_medical_records">Patient Medical Records</string> <string name="patient_medical_records">Patient Medical Records</string>
<string name="patient_address_details">Patient Address Details</string> <string name="patient_address_details">Patient Address Details</string>
<string name="district">District</string> <string name="district">District</string>
@@ -193,8 +184,5 @@
<string name="upload_success_message">Upload done successfully</string> <string name="upload_success_message">Upload done successfully</string>
<string name="test_completed">Test Completed</string> <string name="test_completed">Test Completed</string>
<string name="select_blood_group">Select Blood Group</string> <string name="select_blood_group">Select Blood Group</string>
<string name="all_registered_user_are_tested_successfully">All registered user are tested successfully</string>
<string name="start_incubation">Incubate</string>
<string name="check_buffer">Check Buffer</string>
</resources> </resources>

View File

@@ -10,7 +10,6 @@
<!-- <usb-device vendor-id="1027" product-id="24593" /> &lt;!&ndash; 0x6011: FT4232H &ndash;&gt;--> <!-- <usb-device vendor-id="1027" product-id="24593" /> &lt;!&ndash; 0x6011: FT4232H &ndash;&gt;-->
<!-- <usb-device vendor-id="1027" product-id="24596" /> &lt;!&ndash; 0x6014: FT232H &ndash;&gt;--> <!-- <usb-device vendor-id="1027" product-id="24596" /> &lt;!&ndash; 0x6014: FT232H &ndash;&gt;-->
<usb-device vendor-id="1027" product-id="24597" /> <!-- 0x6015: FT230X, FT231X, FT234XD --> <usb-device vendor-id="1027" product-id="24597" /> <!-- 0x6015: FT230X, FT231X, FT234XD -->
<usb-device vendor-id="6790" product-id="29987" /> <!-- 0x6015: FT230X, FT231X, FT234XD -->
<!-- 0x10C4 / 0xEA??: Silabs CP210x --> <!-- 0x10C4 / 0xEA??: Silabs CP210x -->
<!-- <usb-device vendor-id="4292" product-id="60000" /> &lt;!&ndash; 0xea60: CP2102 and other CP210x single port devices &ndash;&gt;--> <!-- <usb-device vendor-id="4292" product-id="60000" /> &lt;!&ndash; 0xea60: CP2102 and other CP210x single port devices &ndash;&gt;-->

View File

@@ -3,9 +3,9 @@ buildscript {
kotlin_version = '1.8.21' kotlin_version = '1.8.21'
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.1.1' classpath 'com.android.tools.build:gradle:8.0.2'
classpath 'com.google.gms:google-services:4.4.0' classpath 'com.google.gms:google-services:4.3.15'
classpath 'com.google.firebase:firebase-appdistribution-gradle:4.0.1' classpath 'com.google.firebase:firebase-appdistribution-gradle:4.0.0'
} }
repositories { repositories {
mavenCentral() mavenCentral()
@@ -19,7 +19,6 @@ plugins {
id 'androidx.navigation.safeargs' version '2.7.0-beta01' apply false id 'androidx.navigation.safeargs' version '2.7.0-beta01' apply false
id 'com.google.dagger.hilt.android' version '2.46' apply false id 'com.google.dagger.hilt.android' version '2.46' apply false
id "com.google.gms.google-services" version "4.3.15" apply false id "com.google.gms.google-services" version "4.3.15" apply false
id 'com.google.firebase.crashlytics' version "2.9.8" apply false
} }
task clean(type: Delete) { task clean(type: Delete) {