Compare commits

...

22 Commits

Author SHA1 Message Date
chandrashekhar reddy
735afbf3c0 new 125 version, changes in HemoCubeFragment, latest version 2024-07-08 14:29:10 +05:30
chandrashekhar reddy
5c8d6581b6 new 125 version 2024-06-27 17:24:31 +05:30
chandrashekhar reddy
1f9784aea6 new 125 version 2024-06-27 17:18:39 +05:30
chandrashekhar reddy
81b799d9c1 new 125 version 2024-06-27 17:11:50 +05:30
chandrashekhar reddy
b89139d571 new 125 version 2024-06-27 17:07:38 +05:30
chandrashekhar reddy
0de4b71866 new 124 version 2024-06-27 16:49:32 +05:30
chandrashekhar reddy
331726682f new 124 version 2024-06-25 13:06:20 +05:30
chandrashekhar reddy
c41a2f5139 new 124 version with cuvette size option, pipeline fixed 2024-06-11 18:35:14 +05:30
chandrashekhar reddy
262f334f40 new 124 version with cuvette size option 2024-06-11 18:13:27 +05:30
chandrashekhar reddy
50fd8c0632 new 124 version with cuvette size option 2024-06-06 12:05:49 +05:30
chandrashekhar reddy
bdb58f9b49 new 124 version with cuvette size option 2024-06-05 16:22:12 +05:30
chandrashekhar reddy
7fe72b0371 new 124 version with cuvette size option 2024-05-22 13:22:30 +05:30
chandrashekhar reddy
d620aa9e0d new 124 version with cuvette size option 2024-05-22 12:54:32 +05:30
chandrashekhar reddy
238debae85 device Diagnostics updated the screen with progress bar 2024-04-30 17:56:51 +05:30
chandrashekhar reddy
4ba2f38583 device Diagnostics for user has been integrated 2024-04-29 18:15:20 +05:30
chandrashekhar reddy
0b6e3749c3 constants value added molbio integration 2024-04-25 12:48:52 +05:30
chandrashekhar reddy
f2e9bf2eed Merge remote-tracking branch 'origin/dev' into dev 2024-04-15 12:20:16 +05:30
chandrashekhar reddy
7fcfd58544 quality version bulid for V1 device 2024-04-15 12:20:04 +05:30
Mariya
628b84bfef changed the time zone for result upload for molbio 2024-04-05 14:23:51 +05:30
chandrashekhar reddy
c825ebbda3 Removed the finish activity in HomeFragment while calling kit activity so onback pressed app will not exit instead come back to home 2024-04-03 17:13:15 +05:30
chandrashekhar reddy
fe8a340021 Added details in AboutFragment about SMI 2024-04-03 17:04:51 +05:30
chandrashekhar reddy
6bbbcea227 For security added sql cipher to room and removed bug in ActivitiesFragment 2024-04-03 13:45:41 +05:30
68 changed files with 2792 additions and 1176 deletions

View File

@@ -16,11 +16,11 @@ android {
// dev -> development, quality -> qc, uat -> User Acceptance Testing, preprod -> preproduction, prod -> production, iocl -> iocl-iisc production // dev -> development, quality -> qc, uat -> User Acceptance Testing, preprod -> preproduction, prod -> production, iocl -> iocl-iisc production
defaultConfig { defaultConfig {
applicationId "in.sminnovations.hpostesting.dev" applicationId "in.sminnovations.hpostesting.iocl"
minSdk 21 minSdk 21
targetSdk 34 targetSdk 34
versionCode 122 versionCode 125
versionName "2.1.122" versionName "2.1.125"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@@ -138,6 +138,7 @@ dependencies {
implementation "androidx.room:room-ktx:2.6.1" implementation "androidx.room:room-ktx:2.6.1"
implementation "androidx.room:room-runtime:2.6.1" implementation "androidx.room:room-runtime:2.6.1"
kapt ("androidx.room:room-compiler:2.6.1") kapt ("androidx.room:room-compiler:2.6.1")
implementation "net.zetetic:android-database-sqlcipher:4.4.0"
//image //image
implementation 'com.github.bumptech.glide:glide:4.13.2' implementation 'com.github.bumptech.glide:glide:4.13.2'
@@ -167,5 +168,8 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.aar']) implementation fileTree(dir: 'libs', include: ['*.aar'])
implementation 'io.nats:jnats:2.11.4' implementation 'io.nats:jnats:2.11.4'
implementation 'org.apache.commons:commons-math3:3.6.1'
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.17'
implementation 'androidx.security:security-crypto:1.1.0-alpha03'
} }

View File

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

View File

@@ -4,15 +4,15 @@
"type": "APK", "type": "APK",
"kind": "Directory" "kind": "Directory"
}, },
"applicationId": "in.sminnovations.hpostesting.quality", "applicationId": "in.sminnovations.hpostesting.iocl",
"variantName": "release", "variantName": "release",
"elements": [ "elements": [
{ {
"type": "SINGLE", "type": "SINGLE",
"filters": [], "filters": [],
"attributes": [], "attributes": [],
"versionCode": 101, "versionCode": 125,
"versionName": "2.1.101", "versionName": "2.1.125",
"outputFile": "app-release.apk" "outputFile": "app-release.apk"
} }
], ],

View File

@@ -2,6 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission
android:name="android.permission.AUTHENTICATE_ACCOUNTS"
android:maxSdkVersion="22" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
@@ -34,13 +37,36 @@
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.dashboard.UpdateValuesActivity"
android:exported="false"
android:screenOrientation="portrait"/>
<service
android:name="com.example.hpostesting.util.MyAuthenticatorService"
android:exported="true"
android:permission="android.permission.BIND_AUTOFILL_SERVICE">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
<activity
android:name="com.example.hpostesting.presentation.dashboard.ui.PasswordResetActivity"
android:exported="false"
android:screenOrientation="portrait" />
<activity <activity
android:name="com.example.hpostesting.presentation.usb_teminal.UsbTerminalActivity" android:name="com.example.hpostesting.presentation.usb_teminal.UsbTerminalActivity"
android:screenOrientation="portrait" android:exported="false"
android:exported="false" /> android:screenOrientation="portrait" />
<activity <activity
android:name="com.example.hpostesting.presentation.deviceinfo.DeviceActivity" android:name="com.example.hpostesting.presentation.deviceinfo.DeviceActivity"
android:exported="false" /> android:exported="false"
android:theme="@style/Theme.HPOS.NoActionBar" />
<activity <activity
android:name="com.example.hpostesting.presentation.hemocube.DigitalCardActivity" android:name="com.example.hpostesting.presentation.hemocube.DigitalCardActivity"
android:exported="false" /> android:exported="false" />
@@ -103,7 +129,6 @@
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/Theme.HPOS.NoActionBar" android:theme="@style/Theme.HPOS.NoActionBar"
tools:ignore="AppLinkUrlError,MissingClass"> tools:ignore="AppLinkUrlError,MissingClass">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
@@ -125,13 +150,14 @@
android:exported="true" android:exported="true"
android:noHistory="true" android:noHistory="true"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<!-- <intent-filter>--> <intent-filter>
<!-- <action android:name="android.intent.action.MAIN" />--> <action android:name="android.intent.action.MAIN" />
<!-- <category android:name="android.intent.category.HOME" />-->
<!-- <category android:name="android.intent.category.DEFAULT" />--> <category android:name="android.intent.category.HOME" />
<!-- <category android:name="android.intent.category.MONKEY"/>--> <category android:name="android.intent.category.DEFAULT" />
<!-- <category android:name="android.intent.category.LAUNCHER_APP" />--> <category android:name="android.intent.category.MONKEY" />
<!-- </intent-filter>--> <category android:name="android.intent.category.LAUNCHER_APP" />
</intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View File

@@ -23,6 +23,7 @@ import com.example.hpostesting.data.model.updates.CheckUpdateResponse
import com.example.hpostesting.data.model.updates.DeviceUpdateRequest import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.ResponseBody import okhttp3.ResponseBody
import retrofit2.Response
import retrofit2.http.Body import retrofit2.http.Body
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Multipart import retrofit2.http.Multipart
@@ -42,10 +43,14 @@ interface MolbioResultApi {
@Body checkUpdateRequest: CheckUpdateRequest, @Body checkUpdateRequest: CheckUpdateRequest,
): CheckUpdateResponse ): CheckUpdateResponse
// @POST("deviceService/device/getUpdate")
// suspend fun deviceUpdate(
// @Body deviceUpdateRequest: DeviceUpdateRequest,
// ): ResponseBody
@POST("deviceService/device/getUpdate") @POST("deviceService/device/getUpdate")
suspend fun deviceUpdate( suspend fun deviceUpdate(
@Body deviceUpdateRequest: DeviceUpdateRequest, @Body deviceUpdateRequest: DeviceUpdateRequest,
): ResponseBody ): Response<ResponseBody>
@GET("deviceService/device/getClientCertificate") @GET("deviceService/device/getClientCertificate")
suspend fun downloadClientCertificate( suspend fun downloadClientCertificate(

View File

@@ -14,9 +14,16 @@
package com.example.hpostesting.data.constant package com.example.hpostesting.data.constant
object Constants { object Constants {
const val CENTER_NAME =""
const val DISTRICT =""
const val FLAGS_ENABLED = false//testing flag disable then pass buffer and sample checks
const val ABS_FLAGS_ENABLED = false
const val IP_ADDRESS="ip_address"
const val QUICK_CAPTURE="quick_capture"
const val KIT_TIME = "kit_time"
const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION" const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION"
const val HEMOCUBE_USB_PERMISSION = "shanmukha.in.sickle_cell_homocube.USB_PERMISSION" const val HEMOCUBE_USB_PERMISSION = "shanmukha.in.sickle_cell_homocube.USB_PERMISSION"
const val passphrase = "smi_#@sql"
const val BASE_URL = "www.google.com" const val BASE_URL = "www.google.com"
const val DOCUMENT_ID_FOR_UPDATE ="2o71vBKLqdgEKYtFG8Lb" const val DOCUMENT_ID_FOR_UPDATE ="2o71vBKLqdgEKYtFG8Lb"
const val ABHA_APP_PACKAGE = "in.ndhm.phr" const val ABHA_APP_PACKAGE = "in.ndhm.phr"
@@ -37,7 +44,8 @@ object Constants {
const val TEST_RIGHT_TOTAL_PIXEL = 3694 const val TEST_RIGHT_TOTAL_PIXEL = 3694
const val MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE = 40 const val MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE = 35
const val MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM = 10
const val RANGE_IN_RESULT_CALCULATIONS = 10 const val RANGE_IN_RESULT_CALCULATIONS = 10
@@ -78,178 +86,16 @@ object Constants {
// jig // jig
const val NAVIGATE_TO_TEST_JIG_DIRECTLY = false const val NAVIGATE_TO_TEST_JIG_DIRECTLY = false
val STATICID = listOf( //update values of abs
"FACTORY", const val ABS2LED1MMLL = "ABS2LED1MMLL"
"ADMIN", const val ABS2LED1MMUL = "ABS2LED1MMUL"
"PQUSER", const val ABS2LED2MMLL = "ABS2LED2MMLL"
"QCUSER", const val ABS2LED2MMUL = "ABS2LED2MMUL"
"VIZ-1000-0004",
"VIZ-1000-0005",
"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-1015",
"HCV-000-3002",
"HCV-000-3003",
"HCV-000-3004",
"HCV-000-3005",
"HCV-000-3006",
"HCV-000-3007",
"HCV-000-3008",
"HCV-000-3009",
"HCV-000-3010",
"HCV-000-3011",
"HCV-000-3012",
"HCV-000-3013",
"HCV-000-3014",
"HCV-000-3015",
"HCV-000-3016",
"HCV-000-3017",
"HCV-000-3018",
"HCV-000-3019",
"HCV-000-3020",
"HCV-000-3021",
"HCV-000-3022",
"HCV-000-3023",
"HCV-000-3024",
"HCV-000-3025",
"HCV-000-3026",
"HCV-000-3027",
"HCV-000-3028",
"HCV-000-3029",
"HCV-000-3030",
"HPP1-0124-0001",
"HPP1-0124-0002",
"HPP1-0124-0003",
"HPP1-0124-0004",
"HPP1-0124-0005",
"HPP1-0124-0006",
"HPP1-0124-0007",
"HPP1-0124-0008",
"HPP1-0124-0009",
"HPP1-0124-0010",
"HPP1-0124-0011",
"HPP1-0124-0012",
"HPP1-0124-0013",
"HPP1-0124-0014",
"HPP1-0124-0015",
"HPP1-0124-0016",
"HPP1-0124-0017",
"HPP1-0124-0018",
"HPP1-0124-0019",
"HPP1-0124-0020",
"HPP1-0124-0021",
"HPP1-0124-0022",
"HPP1-0124-0023",
"HPP1-0124-0024",
"HPP1-0124-0025",
"HPP1-0124-0026",
"HPP1-0124-0027",
"HPP1-0124-0028",
"HPP1-0124-0029",
"HPP1-0124-0030",
"HPP1-0124-0031",
"HPP1-0124-0032",
"HPP1-0124-0033",
"HPP1-0124-0034",
"HPP1-0124-0035",
"HPP1-0124-0036",
"HPP1-0124-0037",
"HPP1-0124-0038",
"HPP1-0124-0039",
"HPP1-0124-0040",
"HPP1-0124-0041",
"HPP1-0124-0042",
"HPP1-0124-0043",
"HPP1-0124-0044",
"HPP1-0124-0045",
"HPP1-0124-0046",
"HPP1-0124-0047",
"HPP1-0124-0048",
"HPP1-0124-0049",
"HPP1-0124-0050",
"HCV-001-0001",
"HCV-001-0002",
"HCV-001-0003",
"HCV-001-0004",
"HCV-001-0005",
"HCV-001-0006",
"HCV-001-0007",
"HCV-001-0008",
"HCV-001-0009",
"HCV-001-0010",
"HCV-001-0011",
"HCV-001-0012",
"HCV-001-0013",
"HCV-001-0014",
"HCV-001-0015",
"HCV-001-0016",
"HCV-001-0017",
"HCV-001-0018",
"HCV-001-0019",
"HCV-001-0020",
"HCV-001-0021",
"HCV-001-0022",
"HCV-001-0023",
"HCV-001-0024",
"HCV-001-0025",
"HCV-001-0026",
"HCV-001-0027",
"HCV-001-0028",
"HCV-001-0029",
"HCV-001-0030",
"HCV-001-0031",
"HCV-001-0032",
"HCV-001-0033",
"HCV-001-0034",
"HCV-001-0003",
"HCV-001-0035",
"HCV-001-0036",
"HCV-001-0037",
"HCV-001-0038",
"HCV-001-0039",
"HCV-001-0040",
"HCV-001-0041",
"HCV-001-0042",
"HCV-001-0043",
"HCV-001-0044",
"HCV-001-0045",
"HCV-001-0046",
"HCV-001-0047",
"HCV-001-0048",
"HCV-001-0049",
"HCV-001-0050",
"HCV-000-6001",
"HCV-000-6002",
"HCV-000-6003",
"HCV-000-6004",
"HCV-000-6005",
"HCV-000-6006",
"HCV-000-6007",
"HCV-000-6008",
"HCV-000-6009",
"HCV-000-6010",
)
const val password = "SMI@12345" const val ABS10LED1MMLL = "ABS10LED1MMLL"
const val ABS10LED1MMUL = "ABS10LED1MMUL"
const val ABS10LED2MMLL = "ABS10LED2MMLL"
const val ABS10LED2MMUL = "ABS10LED2MMUL"
const val KIT_NUMBER = "KitNumber" const val KIT_NUMBER = "KitNumber"
const val KIT_COUNT = "KitCount" const val KIT_COUNT = "KitCount"
@@ -260,7 +106,7 @@ object Constants {
const val BUFFER_VALUE_4 = "BufferValue4" const val BUFFER_VALUE_4 = "BufferValue4"
const val DEVICE_ID = "DEVICE_ID" const val DEVICE_ID = "DEVICE_ID"
const val LABNAME = "LAB_NAME" const val LABNAME = "LAB_NAME"
const val CUVETTE_SIZE = "CUVETTE_SIZE"
const val IS_TOKEN_AVAILABLE = "IS_TOKEN_AVAILABLE" const val IS_TOKEN_AVAILABLE = "IS_TOKEN_AVAILABLE"
const val BUFFER_LED_LOWER_BOUND = 21000 const val BUFFER_LED_LOWER_BOUND = 21000
const val BUFFER_LED_UPPER_BOUND = 23500 const val BUFFER_LED_UPPER_BOUND = 23500
@@ -1238,7 +1084,8 @@ object Constants {
) )
const val INCUBATION_TIME_MIN = 0 const val INCUBATION_TIME_MIN = 0
const val INCUBATION_TIME_MAX = 1400 const val INCUBATION_TIME_MAX = 300
const val MAX_KIT_TIME = 240
const val BATTERY_LEVEL_MIN = Int.MIN_VALUE const val BATTERY_LEVEL_MIN = Int.MIN_VALUE
const val PQ_MODE = true const val PQ_MODE = true
@@ -1735,5 +1582,216 @@ object Constants {
listOf(0.0, 0.0) listOf(0.0, 0.0)
) )
) )
//Hemocube for 10mm
const val positiveBoderLine10mm1 = 1.3
const val positiveBoderLine10mm2 = 1.66
const val negativeBoderLine10mm1 = 2.0
const val negativeBoderLine10mm2 = 2.4
const val normalMin10mm = 0.1
const val normalMax10mm = 0.23
const val negativeBorderlineMin10mm = 0.23
const val negativeBorderlineMax10mm = 0.25
const val sickleCellTraitMin10mm = 0.25
const val sickleCellTraitMax10mm = 0.31
const val positiveForSickleCellMin10mm = 0.31
const val positiveForSickleCellMax10mm = 0.43
const val sickleCellDiseaseMin10mm = 0.43
const val sickleCellDiseaseMax10mm = 0.7
//Hemocube for 2mm
const val positiveBoderLine2mm1 = 0.8
const val positiveBoderLine2mm2 = 1.1
const val negativeBoderLine2mm1 = 1.5
const val negativeBoderLine2mm2 = 1.9
const val normalMin2mm = 0.1
const val normalMax2mm = 0.23
const val negativeBorderlineMin2mm = 0.23
const val negativeBorderlineMax2mm = 0.25
const val sickleCellTraitMin2mm = 0.25
const val sickleCellTraitMax2mm = 0.31
const val positiveForSickleCellMin2mm = 0.31
const val positiveForSickleCellMax2mm = 0.45
const val sickleCellDiseaseMin2mm = 0.45
const val sickleCellDiseaseMax2mm = 0.7
const val min2mmLed1 = 0.34
const val max2mmLed1 = 1.48
const val min2mmLed2 = 0.04
const val max2mmLed2 = 0.33
const val min10mmLed1 = 0.22
const val max10mmLed1 = 1.12
const val min10mmLed2 = 0.05
const val max10mmLed2 = 0.41
// val STATICID = listOf(
// "FACTORY",
// "ADMIN",
// "PQUSER",
// "QCUSER",
// "VIZ-1000-0004",
// "VIZ-1000-0005",
// "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-1015",
// "HCV-000-3002",
// "HCV-000-3003",
// "HCV-000-3004",
// "HCV-000-3005",
// "HCV-000-3006",
// "HCV-000-3007",
// "HCV-000-3008",
// "HCV-000-3009",
// "HCV-000-3010",
// "HCV-000-3011",
// "HCV-000-3012",
// "HCV-000-3013",
// "HCV-000-3014",
// "HCV-000-3015",
// "HCV-000-3016",
// "HCV-000-3017",
// "HCV-000-3018",
// "HCV-000-3019",
// "HCV-000-3020",
// "HCV-000-3021",
// "HCV-000-3022",
// "HCV-000-3023",
// "HCV-000-3024",
// "HCV-000-3025",
// "HCV-000-3026",
// "HCV-000-3027",
// "HCV-000-3028",
// "HCV-000-3029",
// "HCV-000-3030",
// "HPP1-0124-0001",
// "HPP1-0124-0002",
// "HPP1-0124-0003",
// "HPP1-0124-0004",
// "HPP1-0124-0005",
// "HPP1-0124-0006",
// "HPP1-0124-0007",
// "HPP1-0124-0008",
// "HPP1-0124-0009",
// "HPP1-0124-0010",
// "HPP1-0124-0011",
// "HPP1-0124-0012",
// "HPP1-0124-0013",
// "HPP1-0124-0014",
// "HPP1-0124-0015",
// "HPP1-0124-0016",
// "HPP1-0124-0017",
// "HPP1-0124-0018",
// "HPP1-0124-0019",
// "HPP1-0124-0020",
// "HPP1-0124-0021",
// "HPP1-0124-0022",
// "HPP1-0124-0023",
// "HPP1-0124-0024",
// "HPP1-0124-0025",
// "HPP1-0124-0026",
// "HPP1-0124-0027",
// "HPP1-0124-0028",
// "HPP1-0124-0029",
// "HPP1-0124-0030",
// "HPP1-0124-0031",
// "HPP1-0124-0032",
// "HPP1-0124-0033",
// "HPP1-0124-0034",
// "HPP1-0124-0035",
// "HPP1-0124-0036",
// "HPP1-0124-0037",
// "HPP1-0124-0038",
// "HPP1-0124-0039",
// "HPP1-0124-0040",
// "HPP1-0124-0041",
// "HPP1-0124-0042",
// "HPP1-0124-0043",
// "HPP1-0124-0044",
// "HPP1-0124-0045",
// "HPP1-0124-0046",
// "HPP1-0124-0047",
// "HPP1-0124-0048",
// "HPP1-0124-0049",
// "HPP1-0124-0050",
// "HCV-001-0001",
// "HCV-001-0002",
// "HCV-001-0003",
// "HCV-001-0004",
// "HCV-001-0005",
// "HCV-001-0006",
// "HCV-001-0007",
// "HCV-001-0008",
// "HCV-001-0009",
// "HCV-001-0010",
// "HCV-001-0011",
// "HCV-001-0012",
// "HCV-001-0013",
// "HCV-001-0014",
// "HCV-001-0015",
// "HCV-001-0016",
// "HCV-001-0017",
// "HCV-001-0018",
// "HCV-001-0019",
// "HCV-001-0020",
// "HCV-001-0021",
// "HCV-001-0022",
// "HCV-001-0023",
// "HCV-001-0024",
// "HCV-001-0025",
// "HCV-001-0026",
// "HCV-001-0027",
// "HCV-001-0028",
// "HCV-001-0029",
// "HCV-001-0030",
// "HCV-001-0031",
// "HCV-001-0032",
// "HCV-001-0033",
// "HCV-001-0034",
// "HCV-001-0003",
// "HCV-001-0035",
// "HCV-001-0036",
// "HCV-001-0037",
// "HCV-001-0038",
// "HCV-001-0039",
// "HCV-001-0040",
// "HCV-001-0041",
// "HCV-001-0042",
// "HCV-001-0043",
// "HCV-001-0044",
// "HCV-001-0045",
// "HCV-001-0046",
// "HCV-001-0047",
// "HCV-001-0048",
// "HCV-001-0049",
// "HCV-001-0050",
// "HCV-000-6001",
// "HCV-000-6002",
// "HCV-000-6003",
// "HCV-000-6004",
// "HCV-000-6005",
// "HCV-000-6006",
// "HCV-000-6007",
// "HCV-000-6008",
// "HCV-000-6009",
// "HCV-000-6010",
// )
//
} }

View File

@@ -27,6 +27,7 @@ object DataHolder {
var isAppFolderCreated = false var isAppFolderCreated = false
var appFolderPath = "" var appFolderPath = ""
var isReferenceTaken = false var isReferenceTaken = false
var isToken = false
var sampleReadCounter = 0 var sampleReadCounter = 0
var deviceConstant: TestRightDeviceConstants? = null var deviceConstant: TestRightDeviceConstants? = null
@@ -37,7 +38,11 @@ object DataHolder {
var selectedTest: UserData? = null var selectedTest: UserData? = null
var hemoCubeTestData: HemoCubeTestData? = null var hemoCubeTestData: HemoCubeTestData? = null
var kitSerial: String = "" var kitSerial: String = ""
var centerName: String = ""
var district: String = ""
var quickCapture:Boolean = false
var location: UserData.Location? = null var location: UserData.Location? = null
var ipAddress: String =""
var testExp: Boolean = true var testExp: Boolean = true
var hemocubeResult: Double? = null var hemocubeResult: Double? = null
} }

View File

@@ -30,4 +30,5 @@ enum class HemoCubeCommands(val command: String) {
FORTH_GAIN_COMMAND("W\r"), FORTH_GAIN_COMMAND("W\r"),
CHECK_CUVETTE_COMMAND("L\r"), CHECK_CUVETTE_COMMAND("L\r"),
CHECK_TEMP_COMMAND("A\r"), CHECK_TEMP_COMMAND("A\r"),
J_COMMAND("J\r"),
} }

View File

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

View File

@@ -106,5 +106,9 @@ data class HemoCubeTestData(
var filter: String? = "", var filter: String? = "",
var volume: String? = "", var volume: String? = "",
var isCSVCreated: Boolean = false, var isCSVCreated: Boolean = false,
var labName: String? = "" var labName: String? = "",
var cuvetteSize: String? = "",
var district: String? = "",
var centerName: String? = "",
var ipAddress:String?= ""
) )

View File

@@ -89,8 +89,8 @@ class DatabaseRepository @Inject constructor(
return safeApiCall { molbioResultApi.checkUpdate(checkUpdateRequest) } return safeApiCall { molbioResultApi.checkUpdate(checkUpdateRequest) }
} }
override suspend fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest): Result<ResponseBody> { override suspend fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest): retrofit2.Response<ResponseBody> {
return safeApiCall { molbioResultApi.deviceUpdate(deviceUpdateRequest) } return molbioResultApi.deviceUpdate(deviceUpdateRequest)
} }
override suspend fun deviceDiagnostics(deviceDiagnosticsRequest: DeviceDiagnosticsRequest): Result<DeviceDiagnosticsResponse> { override suspend fun deviceDiagnostics(deviceDiagnosticsRequest: DeviceDiagnosticsRequest): Result<DeviceDiagnosticsResponse> {
@@ -120,6 +120,21 @@ class DatabaseRepository @Inject constructor(
Response.Error(e) Response.Error(e)
} }
} }
override suspend fun addQcTestToDatabase(data: HemoCubeTestData?): Response<String> {
return try {
val userdata =
db.collection("patientData").whereEqualTo("_id", data!!._id).get().await()
if (userdata.documents.isNotEmpty()) {
userdata.documents.forEach {
db.collection("patientData").document(it.id).update("testStatus", true)
}
}
db.collection("qcData").add(data).await()
Response.Success(data._id)
} catch (e: Exception) {
Response.Error(e)
}
}
override suspend fun addTestToDatabase(data: UserData?): Response<String> { override suspend fun addTestToDatabase(data: UserData?): Response<String> {
TODO("Not yet implemented") TODO("Not yet implemented")
@@ -145,6 +160,7 @@ class DatabaseRepository @Inject constructor(
} }
} }
override suspend fun addTestJigData(data: JigData?): Response<String> { override suspend fun addTestJigData(data: JigData?): Response<String> {
return try { return try {
db.collection("jigs").add(data!!).await() db.collection("jigs").add(data!!).await()

View File

@@ -38,6 +38,7 @@ import okhttp3.ResponseBody
interface Repository { interface Repository {
suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String> suspend fun addTestToDatabase(data: HemoCubeTestData?): Response<String>
suspend fun addQcTestToDatabase(data: HemoCubeTestData?): Response<String>
suspend fun addTestToDatabasefornew(data: HemoCubeTestData?): Response<String> suspend fun addTestToDatabasefornew(data: HemoCubeTestData?): Response<String>
suspend fun addTestToDatabase(data: UserData?): Response<String> suspend fun addTestToDatabase(data: UserData?): Response<String>
@@ -64,7 +65,7 @@ interface Repository {
suspend fun checkUpdate(checkUpdateRequest: CheckUpdateRequest): Result<CheckUpdateResponse> suspend fun checkUpdate(checkUpdateRequest: CheckUpdateRequest): Result<CheckUpdateResponse>
suspend fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest): Result<ResponseBody> suspend fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest): retrofit2.Response<ResponseBody>
suspend fun deviceDiagnostics(deviceDiagnosticsRequest: DeviceDiagnosticsRequest): Result<DeviceDiagnosticsResponse> suspend fun deviceDiagnostics(deviceDiagnosticsRequest: DeviceDiagnosticsRequest): Result<DeviceDiagnosticsResponse>
suspend fun downloadClientCertificate(): Result<ResponseBody> suspend fun downloadClientCertificate(): Result<ResponseBody>
suspend fun uploadLogs(logFile: MultipartBody.Part): Result<UploadLogsResponse> suspend fun uploadLogs(logFile: MultipartBody.Part): Result<UploadLogsResponse>

View File

@@ -20,6 +20,7 @@ import android.content.res.AssetManager
import androidx.room.Room import androidx.room.Room
import com.example.hpostesting.data.api.MolbioAuthApi import com.example.hpostesting.data.api.MolbioAuthApi
import com.example.hpostesting.data.api.MolbioResultApi import com.example.hpostesting.data.api.MolbioResultApi
import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.util.PropertyProvider import com.example.hpostesting.util.PropertyProvider
import com.example.hpostesting.data.dao.HemoCubeBufferDao import com.example.hpostesting.data.dao.HemoCubeBufferDao
import com.example.hpostesting.data.dao.HemoCubeDao import com.example.hpostesting.data.dao.HemoCubeDao
@@ -43,6 +44,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 net.sqlcipher.database.SQLiteDatabase
import net.sqlcipher.database.SupportFactory
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.gson.GsonConverterFactory
@@ -57,9 +60,12 @@ object AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideMyDatabase(@ApplicationContext context: Context): MyDatabase { fun provideMyDatabase(@ApplicationContext context: Context): MyDatabase {
val passphraseBytes: ByteArray = SQLiteDatabase.getBytes(Constants.passphrase.toCharArray())
val factory = SupportFactory(passphraseBytes)
return Room.databaseBuilder( return Room.databaseBuilder(
context, MyDatabase::class.java, "my_database" context, MyDatabase::class.java, "my_database"
).fallbackToDestructiveMigration().build() ).openHelperFactory(factory).fallbackToDestructiveMigration().build()
} }
@Provides @Provides

View File

@@ -44,6 +44,11 @@ import com.zebra.scannercontrol.IDcsSdkApiDelegate
import com.zebra.scannercontrol.SDKHandler import com.zebra.scannercontrol.SDKHandler
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityKitScanBinding import `in`.sminnovations.hpostesting.databinding.ActivityKitScanBinding
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import kotlin.math.max
class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate { class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
@@ -67,8 +72,24 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
} }
} }
private fun processScannedData(contents: String) { private fun processScannedData(contents: String) {//edited auto selection of cuvette size
binding.nameEditText.setText(contents) if(contents.contains("SMI/SC/")){
with(sharedPreference.edit()) {
putString(Constants.CUVETTE_SIZE, "2mm")
apply()
}
Toast.makeText(this, "Selected cuvette size: 2mm", Toast.LENGTH_SHORT).show()
binding.nameEditText.setText(contents)
}else if(contents.contains("SMI/SC-2-D10/")){
with(sharedPreference.edit()) {
putString(Constants.CUVETTE_SIZE, "10mm")
apply()
}
Toast.makeText(this, "Selected cuvette size: 10mm", Toast.LENGTH_SHORT).show()
binding.nameEditText.setText(contents)
}else{
Toast.makeText(this, R.string.invalid_kit, Toast.LENGTH_LONG).show()
}
} }
override fun attachBaseContext(newBase: Context?) { override fun attachBaseContext(newBase: Context?) {
@@ -112,10 +133,29 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
binding = ActivityKitScanBinding.inflate(layoutInflater) binding = ActivityKitScanBinding.inflate(layoutInflater)
sharedPreference = this.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) sharedPreference = this.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
setContentView(binding.root) setContentView(binding.root)
binding.toolbar.title = "Kit Serial Number"
val maxTest = if(sharedPreference.getString(Constants.CUVETTE_SIZE, "10mm").toString() == "2mm"){
Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE
}else{
Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE10MM
}
val time = timeDifference(sharedPreference.getString(Constants.KIT_TIME, "").toString())
val kitNum = sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
// Toast.makeText(this@KitScanActivity,"Test MAx time"+ time+"-Test count-"+kitNum,Toast.LENGTH_SHORT).show()
if (DataHolder.sampleReadCounter <= Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE && DataHolder.isReferenceTaken) { if (DataHolder.sampleReadCounter <= maxTest && kitNum != "" && time < Constants.MAX_KIT_TIME) {
DataHolder.selectedTest!!.kitSerial = DataHolder.kitSerial
moveToNext() moveToNext()
} else {
Toast.makeText(this@KitScanActivity, "Limit Reached, Use New KIT for testing", Toast.LENGTH_SHORT).show()
DataHolder.sampleReadCounter = 0
DataHolder.kitSerial = ""
with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "")
putString(Constants.BUFFER_VALUE_1, "")
putString(Constants.BUFFER_VALUE_2, "")
apply()
}
} }
// if (checkHemoCubeKitData()) { // if (checkHemoCubeKitData()) {
@@ -132,35 +172,31 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
// } // }
// } // }
try { // try {
if (checkHemoCubeKitData()) { // if (checkHemoCubeKitData()) {
DataHolder.selectedTest!!.kitSerial = // DataHolder.selectedTest!!.kitSerial =
sharedPreference.getString(Constants.KIT_NUMBER, "").toString() // sharedPreference.getString(Constants.KIT_NUMBER, "").toString()
moveToNext() // moveToNext()
} else { // } else {
// Handle the case when checkHemoCubeKitData() returns false // // Handle the case when checkHemoCubeKitData() returns false
with(sharedPreference.edit()) { // with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "") // putString(Constants.KIT_NUMBER, "")
putInt(Constants.KIT_COUNT, 0) // putInt(Constants.KIT_COUNT, 0)
putString(Constants.BUFFER_VALUE_1, "") // putString(Constants.BUFFER_VALUE_1, "")
putString(Constants.BUFFER_VALUE_2, "") // putString(Constants.BUFFER_VALUE_2, "")
apply() // apply()
} // }
} // }
} catch (e: NullPointerException) { // } catch (e: NullPointerException) {
// Handle the NullPointerException here // // Handle the NullPointerException here
e.printStackTrace() // You can log the exception for debugging // e.printStackTrace() // You can log the exception for debugging
FirebaseCrashlytics.getInstance().recordException(e) // FirebaseCrashlytics.getInstance().recordException(e)
val errorMessage = "An error occurred: ${e.message}" // val errorMessage = "An error occurred: ${e.message}"
val rootView = findViewById<View>(android.R.id.content) // val rootView = findViewById<View>(android.R.id.content)
Snackbar.make(rootView, errorMessage, Snackbar.LENGTH_LONG).show() // Snackbar.make(rootView, errorMessage, Snackbar.LENGTH_LONG).show()
// Optionally, show a user-friendly error message to the user // // Optionally, show a user-friendly error message to the user
// Toast.makeText(applicationContext, "An error occurred", Toast.LENGTH_SHORT).show() // // Toast.makeText(applicationContext, "An error occurred", Toast.LENGTH_SHORT).show()
} // }
binding.nameEditText.setText("SMI/SC/")
setSupportActionBar(binding.toolbar) setSupportActionBar(binding.toolbar)
binding.btnScanNow.setOnClickListener { binding.btnScanNow.setOnClickListener {
@@ -171,20 +207,39 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
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() && isSerialValid(serialNumber)) {
if(serialNumber.contains("SMI/SC/")){
with(sharedPreference.edit()) {
putString(Constants.CUVETTE_SIZE, "2mm")
apply()
}
Toast.makeText(this, "Selected cuvette size: 2mm", Toast.LENGTH_SHORT).show()
}else if(serialNumber.contains("SMI/SC-2-D10/")){
with(sharedPreference.edit()) {
putString(Constants.CUVETTE_SIZE, "10mm")
apply()
}
Toast.makeText(this, "Selected cuvette size: 10mm", Toast.LENGTH_SHORT).show()
}
val kitTime = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(Calendar.getInstance().time).toString()
if (DataHolder.selectedTest == null) { if (DataHolder.selectedTest == null) {
with(sharedPreference.edit()) { with(sharedPreference.edit()) {
putString( putString(
Constants.KIT_NUMBER, binding.nameEditText.text.toString() Constants.KIT_NUMBER, binding.nameEditText.text.toString()
) )
putString(Constants.BUFFER_VALUE_1, "")
putString(Constants.BUFFER_VALUE_2, "")
putString(Constants.KIT_TIME, kitTime)
putInt(Constants.KIT_COUNT, 1) putInt(Constants.KIT_COUNT, 1)
apply() apply()
} }
DataHolder.kitSerial = binding.nameEditText.text.toString()
Toast.makeText( Toast.makeText(
applicationContext, applicationContext,
R.string.kit_updated, R.string.kit_updated,
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
val i = Intent(applicationContext, DashboardActivity::class.java) val i = Intent(applicationContext, DashboardActivity::class.java)
startActivity(i) startActivity(i)
finish() finish()
@@ -192,6 +247,9 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
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()) { with(sharedPreference.edit()) {
putString(Constants.BUFFER_VALUE_1, "")
putString(Constants.BUFFER_VALUE_2, "")
putString(Constants.KIT_TIME, kitTime)
putString(Constants.KIT_NUMBER, binding.nameEditText.text.toString()) putString(Constants.KIT_NUMBER, binding.nameEditText.text.toString())
putInt(Constants.KIT_COUNT, 1) putInt(Constants.KIT_COUNT, 1)
apply() apply()
@@ -202,21 +260,21 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
Toast.makeText(this, R.string.invalid_kit_number, Toast.LENGTH_LONG).show() Toast.makeText(this, R.string.invalid_kit_number, Toast.LENGTH_LONG).show()
return@setOnClickListener return@setOnClickListener
} }
if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid( // if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid(
serialNumber // 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()) { // with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, binding.nameEditText.text.toString()) // putString(Constants.KIT_NUMBER, binding.nameEditText.text.toString())
putInt(Constants.KIT_COUNT, 1) // putInt(Constants.KIT_COUNT, 1)
apply() // apply()
} // }
moveToNext() // moveToNext()
} else { // } else {
Toast.makeText(this, R.string.invalid_kit_number, Toast.LENGTH_LONG).show() // Toast.makeText(this, R.string.invalid_kit_number, Toast.LENGTH_LONG).show()
} // }
} }
//Setting up the SDK handler //Setting up the SDK handler
@@ -275,20 +333,30 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
Log.d("BARCODE", result) Log.d("BARCODE", result)
runOnUiThread { runOnUiThread {
val editableResult: Editable = Editable.Factory.getInstance().newEditable(result) val editableResult: Editable = Editable.Factory.getInstance().newEditable(result)
binding.nameEditText.text = editableResult processScannedData(result)
// binding.nameEditText.text = editableResult
} }
} }
private fun checkHemoCubeKitData(): Boolean { // private fun checkHemoCubeKitData(): Boolean {
return sharedPreference.getString(Constants.KIT_NUMBER, "") // return sharedPreference.getString(Constants.KIT_NUMBER, "")
?.isNotBlank() == true && sharedPreference.getInt( // ?.isNotBlank() == true && sharedPreference.getInt(
Constants.KIT_COUNT, 0 // Constants.KIT_COUNT, 0
) > 0 && sharedPreference.getInt(Constants.KIT_COUNT, 0) < Constants.KIT_CAPACITY // ) > 0 && sharedPreference.getInt(Constants.KIT_COUNT, 0) < Constants.KIT_CAPACITY
} // }
private fun isSerialValid(s: String): Boolean { private fun isSerialValid(s: String): Boolean {
if (s.length != 17) { if (s.contains("SMI/SC/")) {
binding.nameEditText.error = getString(R.string.invalid_kit) if(s.length != 17){
binding.nameEditText.error = "Invalid Kit Serial Number, correct example SMI/SC/000/00/000"
return false
}
}else if(s.contains("SMI/SC-2-D10/")){
if(s.length != 27){
binding.nameEditText.error = "Invalid Kit Serial Number, correct example SMI/SC-2-D10/000000/000/000"
return false
}
}else{
return false return false
} }
return true return true
@@ -346,4 +414,18 @@ class KitScanActivity : AppCompatActivity(), IDcsSdkApiDelegate {
true true
} }
} }
private fun timeDifference(createdAt: String): Long {
val currentTime = Calendar.getInstance().time
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
val createdAtDate: Date = if (createdAt.isEmpty()) {
currentTime
} else {
formatter.parse(createdAt) ?: currentTime
}
val diffMillis = currentTime.time - createdAtDate.time
return diffMillis / (60 * 1000) // Convert milliseconds to minutes
}
} }

View File

@@ -75,7 +75,7 @@ class MainActivity : AppCompatActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
binding.myToolbar.title = "Test Type"
setSupportActionBar(binding.myToolbar) setSupportActionBar(binding.myToolbar)
setupListeners() setupListeners()

View File

@@ -16,6 +16,7 @@ package com.example.hpostesting.presentation.adapter
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.res.Resources import android.content.res.Resources
import android.provider.ContactsContract.Data
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -35,7 +36,7 @@ import java.util.Calendar
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
class OfflineUserListAdapter(private val view: View, private val batLevel: Int) : class OfflineUserListAdapter(private val view: View, private val batLevel: Int,private val fromWhere:String) :
RecyclerView.Adapter<OfflineUserListAdapter.OfflineUserListViewHolder>() { RecyclerView.Adapter<OfflineUserListAdapter.OfflineUserListViewHolder>() {
inner class OfflineUserListViewHolder(val binding: OfflineUserListViewBinding) : inner class OfflineUserListViewHolder(val binding: OfflineUserListViewBinding) :
@@ -72,7 +73,7 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int)
override fun onBindViewHolder(holder: OfflineUserListViewHolder, position: Int) { override fun onBindViewHolder(holder: OfflineUserListViewHolder, position: Int) {
val userList = differ.currentList[position] val userList = differ.currentList[position]
holder.binding.apply { holder.binding.apply {
userID.text = "User ID: ${userList._id}" userID.text = "Sample ID: ${userList._id}"
bloodGroup.text = "Blood group: ${userList.bloodGroup}" bloodGroup.text = "Blood group: ${userList.bloodGroup}"
time.text = "Time: ${isBetween15And30Minutes(userList.incubationTime)} \n Started at: ${ time.text = "Time: ${isBetween15And30Minutes(userList.incubationTime)} \n Started at: ${
SimpleDateFormat("HH:mm:ss").format( SimpleDateFormat("HH:mm:ss").format(
@@ -88,33 +89,32 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int)
} else { } else {
teststatus.text = view.context.getString(R.string.test_pending) teststatus.text = view.context.getString(R.string.test_pending)
} }
if(fromWhere == "Home") {
userCard.setOnClickListener { userCard.setOnClickListener {
if (false) { if (false) {
Toast.makeText(
view.context,
view.context.getString(R.string.low_battery_warning),
Toast.LENGTH_SHORT
).show()
return@setOnClickListener
}
if (userList.testStatus != null) {
if (userList.testStatus!!) {
Toast.makeText( Toast.makeText(
view.context, view.context,
view.context.getString(R.string.test_already_conducted), view.context.getString(R.string.low_battery_warning),
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} else { return@setOnClickListener
if (userList.incubationTime != "") { }
if (isBetween15And30Minutes(userList.incubationTime) < Constants.INCUBATION_TIME_MIN) { if (userList.testStatus != null) {
Toast.makeText( if (userList.testStatus!!) {
view.context, Toast.makeText(
view.context.getString(R.string.incubation_not_completed), view.context,
Toast.LENGTH_SHORT view.context.getString(R.string.test_already_conducted),
).show() Toast.LENGTH_SHORT
} else ).show()
if (isBetween15And30Minutes(userList.incubationTime) > Constants.INCUBATION_TIME_MAX) { } else {
if (userList.incubationTime != "") {
if (isBetween15And30Minutes(userList.incubationTime) < Constants.INCUBATION_TIME_MIN) {
Toast.makeText(
view.context,
view.context.getString(R.string.incubation_not_completed),
Toast.LENGTH_SHORT
).show()
} else if (isBetween15And30Minutes(userList.incubationTime) > Constants.INCUBATION_TIME_MAX) {
Toast.makeText( Toast.makeText(
view.context, view.context,
view.context.getString(R.string.incubation_crossed_30_minutes), view.context.getString(R.string.incubation_crossed_30_minutes),
@@ -122,25 +122,25 @@ class OfflineUserListAdapter(private val view: View, private val batLevel: Int)
).show() ).show()
} else { } else {
DataHolder.selectedTest = UserData( DataHolder.selectedTest = UserData(
sampleid = userList.sampleid, sampleid = userList.sampleid,
_id = userList._id, _id = userList._id,
bloodGroup = userList.bloodGroup, bloodGroup = userList.bloodGroup,
incubationTime = userList.incubationTime incubationTime = userList.incubationTime
) )
view.findNavController() view.findNavController()
.navigate(R.id.action_nav_home_to_mainActivity) .navigate(R.id.action_nav_home_to_mainActivity)
} }
} else { } else {
Toast.makeText( Toast.makeText(
view.context, view.context,
view.context.getString(R.string.incubation_not_started), view.context.getString(R.string.incubation_not_started),
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
}
} }
} }
} }
} }
} }
} }

View File

@@ -41,7 +41,6 @@ import java.util.Date
import java.util.Locale import java.util.Locale
class UserListAdapter( class UserListAdapter(
private val context: Context, private val context: Context,
private val hemoCubeViewModel: HemoCubeViewModel, private val hemoCubeViewModel: HemoCubeViewModel,
options: FirestoreRecyclerOptions<UserData>, options: FirestoreRecyclerOptions<UserData>,

View File

@@ -16,6 +16,7 @@ package com.example.hpostesting.presentation.autodac
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -36,13 +37,14 @@ import java.util.Calendar
import java.util.Locale import java.util.Locale
class AutoDacFragment : Fragment() { class AutoDacFragment : Fragment() {
private var readClick = false
private var testStatusCode = 0.0
private lateinit var binding: FragmentAutoDacBinding private lateinit var binding: FragmentAutoDacBinding
private val autoDacViewModel: AutoDacViewModel by activityViewModels() private val autoDacViewModel: AutoDacViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
private var currentDeviceData: DeviceData? = null private var currentDeviceData: DeviceData? = null
private var resultData: String = "" private var resultData: String = ""
private val messages = MutableLiveData<String>() // private val messages = MutableLiveData<String>()
private var startListening = MutableLiveData(false) private var startListening = MutableLiveData(false)
override fun onCreateView( override fun onCreateView(
@@ -64,14 +66,25 @@ class AutoDacFragment : Fragment() {
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
listenToHemoCube() listenToHemoCube()
getDeviceId() getDeviceId()
binding.tvSubtitle4.movementMethod = ScrollingMovementMethod()
binding.btnSubmit.setOnClickListener { binding.btnSubmit.setOnClickListener {
resultData += "Calibrating the device...\n"
autoDacViewModel.messages.postValue(resultData)
testStatusCode = 0.5
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
runAutoDacCommand() runJCommand()
} }
binding.btnReadDac.setOnClickListener { binding.btnReadDac.setOnClickListener {
readClick = true
binding.btnReadDac.visibility = View.GONE binding.btnReadDac.visibility = View.GONE
readCurrentDACValuesCommand() runECommand()
} }
if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") {
binding.btnReadDac.visibility = View.VISIBLE
}else{
binding.btnReadDac.visibility = View.GONE
}
} }
private fun observeViewModel() { private fun observeViewModel() {
@@ -80,7 +93,7 @@ class AutoDacFragment : Fragment() {
currentDeviceData = it currentDeviceData = it
} }
messages.observe(viewLifecycleOwner) { autoDacViewModel.messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it binding.tvSubtitle4.text = it
} }
@@ -114,8 +127,33 @@ class AutoDacFragment : Fragment() {
} }
}) })
} }
private fun runJCommand() {
autoDacViewModel.progressBar.postValue(true)
(activity as AutoDacActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.J_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
private fun runAutoDacCommand() { override fun onUsbError(e: Exception?) {
autoDacViewModel.progressBar.postValue(false)
}
})
}
private fun runDCommand() {
autoDacViewModel.progressBar.postValue(true)
(activity as AutoDacActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.DIAGNOSTICS_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
override fun onUsbError(e: Exception?) {
autoDacViewModel.progressBar.postValue(false)
}
})
}
private fun runCCommand() {
autoDacViewModel.progressBar.postValue(true) autoDacViewModel.progressBar.postValue(true)
(activity as AutoDacActivity).mService.sendAndListenToHemoCube( (activity as AutoDacActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.AUTO_DAC_COMMAND, HemoCubeCommands.AUTO_DAC_COMMAND,
@@ -128,6 +166,33 @@ class AutoDacFragment : Fragment() {
} }
}) })
} }
private fun runGCommand() {
autoDacViewModel.progressBar.postValue(true)
(activity as AutoDacActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.SET_AUTO_DAC_TO_EPROM_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
override fun onUsbError(e: Exception?) {
autoDacViewModel.progressBar.postValue(false)
}
})
}
private fun runECommand() {
autoDacViewModel.progressBar.postValue(true)
(activity as AutoDacActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.LOAD_DAC_VALUES,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
override fun onUsbError(e: Exception?) {
autoDacViewModel.progressBar.postValue(false)
}
})
}
private fun setAutoDacValuesCommand() { private fun setAutoDacValuesCommand() {
autoDacViewModel.progressBar.postValue(true) autoDacViewModel.progressBar.postValue(true)
@@ -168,10 +233,12 @@ class AutoDacFragment : Fragment() {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
data?.let { data?.let {
val stringData = String(it) val stringData = String(it)
autoDacViewModel.messages.postValue(stringData)
fullReadOutput.append(stringData) fullReadOutput.append(stringData)
resultData += stringData resultData += stringData
binding.tvSubtitle4.text = resultData if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") {
autoDacViewModel.messages.postValue(resultData)
}
// binding.tvSubtitle4.text = resultData
if (stringData.contains("SN")) { if (stringData.contains("SN")) {
val slData = stringData.split(" ") val slData = stringData.split(" ")
if (slData.size > 1) { if (slData.size > 1) {
@@ -186,10 +253,56 @@ class AutoDacFragment : Fragment() {
} }
} }
} }
if (resultData.contains("#JC") && testStatusCode < 1.0) {
if (resultData.contains("#CC")) { testStatusCode = 1.1
runDCommand()
}
if (resultData.contains("#DC") && testStatusCode < 1.2) {
testStatusCode = 1.3
if(validateDacValues()){
if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") {
resultData += "Calibrating the device, Please wait...\n"
}else{
resultData = "Calibrating the device, Please wait...\n"
}
autoDacViewModel.messages.postValue(resultData)
runCCommand()
}else{
activity?.runOnUiThread {
if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") {
resultData += "Calibration failed!\nContact us for help at support@sminnovations.in"
}else{
resultData = "Calibration failed!\nContact us for help at support@sminnovations.in"
}
autoDacViewModel.messages.postValue(resultData)
binding.btnReadDac.visibility = View.GONE
}
}
}
if (resultData.contains("#GC") && testStatusCode < 1.6) {
testStatusCode = 1.7
runECommand()
}
if (resultData.contains("#EC") && testStatusCode < 1.8) {
testStatusCode = 1.9
if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") {
resultData += "Calibration Completed\n"
}else{
resultData = "Calibration Completed\n"
}
autoDacViewModel.messages.postValue(resultData)
activity?.runOnUiThread {
Toast.makeText(requireActivity(), "Calibration completed", Toast.LENGTH_LONG).show()
binding.ivCheck.visibility = View.VISIBLE
}
}
if (resultData.contains("#EC") && readClick && testStatusCode < 2.1) {
testStatusCode = 2.2
readCurrentDACValuesCommand()
}
if (resultData.contains("#CC") && testStatusCode < 1.4) {
testStatusCode = 1.5
setAutoDacValuesCommand() setAutoDacValuesCommand()
autoDacViewModel.addAutoDacDataToDb( autoDacViewModel.addAutoDacDataToDb(
DiagnosticsData( DiagnosticsData(
deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "") deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "")
@@ -212,9 +325,7 @@ class AutoDacFragment : Fragment() {
).format(Calendar.getInstance().time) ).format(Calendar.getInstance().time)
) )
) )
activity?.runOnUiThread {
binding.ivCheck.visibility = View.VISIBLE
}
} }
if (resultData.contains("#WC")) { if (resultData.contains("#WC")) {
@@ -230,6 +341,27 @@ class AutoDacFragment : Fragment() {
Firebase.crashlytics.recordException(e) Firebase.crashlytics.recordException(e)
} }
} }
fun extractSubstring(input: String): String {
val regex = "#CS(.*?)#CC".toRegex()
val matchResult = regex.find(input)
return matchResult?.groups?.get(1)?.value?.trim() ?: ""
}
private fun validateDacValues(): Boolean {
val pattern = Regex("(LED:\\d+)__DAC:(\\d+)__ADC:(\\d+)")
val matches = pattern.findAll(resultData)
for (match in matches) {
val ledName = match.groupValues[1]
val xValue = match.groupValues[2].toDouble()
val yValue = match.groupValues[3].toDouble()
if(xValue == 3200.0){
if(yValue < 500.0){
return false
}
}
}
return true
}
fun parseData(inputData: List<String>): List<Pair<String, String>> { fun parseData(inputData: List<String>): List<Pair<String, String>> {
val pattern = Regex("([A-Z]+)\\s(\\d+)") val pattern = Regex("([A-Z]+)\\s(\\d+)")

View File

@@ -47,6 +47,12 @@ class AboutFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
// binding.linkClick.setOnClickListener {
// val url = "https://sminnovations.in/"
// val intent = Intent(Intent.ACTION_VIEW)
// intent.data = Uri.parse(url)
// startActivity(intent)
// }
} }

View File

@@ -58,7 +58,7 @@ class ActivitiesFragment : Fragment() {
val bm = val bm =
requireContext().getSystemService(Context.BATTERY_SERVICE) as BatteryManager requireContext().getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
adapter = OfflineUserListAdapter(binding.root, batLevel) adapter = OfflineUserListAdapter(binding.root, batLevel,"Activities")
adapter.differ.submitList(userData) adapter.differ.submitList(userData)
binding.rvOrderOffline.adapter = adapter binding.rvOrderOffline.adapter = adapter
}else{ }else{

View File

@@ -35,7 +35,9 @@ import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import com.example.hpostesting.util.Result import com.example.hpostesting.util.Result
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.data.constant.LanguageManager import com.example.hpostesting.data.constant.LanguageManager
import com.example.hpostesting.data.model.login.LoginRequest
import com.example.hpostesting.data.model.updates.DeviceUpdateRequest import com.example.hpostesting.data.model.updates.DeviceUpdateRequest
import com.example.hpostesting.presentation.utils.NatsManager import com.example.hpostesting.presentation.utils.NatsManager
import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel import com.example.hpostesting.presentation.hemocube.HemoCubeViewModel
@@ -49,6 +51,7 @@ import `in`.sminnovations.hpostesting.BuildConfig
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
import java.io.File import java.io.File
import java.security.MessageDigest
interface NatsMessageCallback { interface NatsMessageCallback {
fun onMessageReceived(topic: String, message: String) fun onMessageReceived(topic: String, message: String)
@@ -72,7 +75,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
private var downloadId: Long = 0 private var downloadId: Long = 0
// TODO: Remove hemocube viewmodel // TODO: Remove hemocube viewmodel
private val hemocubeViewModel: HemoCubeViewModel by viewModels() private val hemocubeViewModel: HemoCubeViewModel by viewModels()
private lateinit var sharedPreference: SharedPreferences
override fun attachBaseContext(newBase: Context?) { override fun attachBaseContext(newBase: Context?) {
val languageCode = LanguageManager.getSavedLanguage(newBase!!) val languageCode = LanguageManager.getSavedLanguage(newBase!!)
LanguageManager.setLocale(newBase, languageCode) LanguageManager.setLocale(newBase, languageCode)
@@ -97,6 +100,11 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
nats.connect() nats.connect()
} }
val savedKitSerial = sharedPreferences.getString(Constants.KIT_NUMBER, "")
Log.d("DashboardActivity", "Saved Kit Serial: $savedKitSerial")
// Toast.makeText(this, "Saved Kit Serial: $savedKitSerial", Toast.LENGTH_SHORT).show()
val versionName = getAppVersion(this@DashboardActivity) + " [ " + getAppEnvironment(this@DashboardActivity) + " ]" val versionName = getAppVersion(this@DashboardActivity) + " [ " + getAppEnvironment(this@DashboardActivity) + " ]"
binding.appBarDashboard.versionName.text = versionName binding.appBarDashboard.versionName.text = versionName
@@ -106,43 +114,34 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
nats.sub("server.hpos.${deviceId}.ping") nats.sub("server.hpos.${deviceId}.ping")
nats.pub("server.hpos.${deviceId}.ping", "THIS IS A TEST MSG") nats.pub("server.hpos.${deviceId}.ping", "THIS IS A TEST MSG")
hemocubeViewModel.deviceUpdate.observe(this) { result -> hemocubeViewModel.deviceUpdate.observe(this) {
when (result) { Log.d("DashboardLogs",it.toString())
is Result.Success -> {
// Handle success
val apk = result.data
val file = File(getExternalFilesDir("Updates"), "update.apk")
file.setReadable(true, false) // Ensure the file is readable
apk.byteStream().use { input ->
file.outputStream().use { output ->
input.copyTo(output)
}
}
Log.d("Responsebodyformat", "Responsebodyformat: ")
installApk(file)
Log.e("ApI", "APK URL: $apk")
Toast.makeText(
this,
"${result.data}",
Toast.LENGTH_SHORT
).show()
}
is Result.Error -> { var apk = it
result.exception.let { message -> val file = File(getExternalFilesDir("Downloads"), "update.apk")
Toast.makeText(this, "An error occurred On Updating App: $message", Toast.LENGTH_LONG) file.setReadable(true, false)
.show()
}
}
is Result.Loading -> { // Write APK to file
} apk.byteStream().use { input ->
file.outputStream().use { output ->
else -> { input.copyTo(output)
} }
} }
}
}
hemocubeViewModel.deviceUpdateheader.observe(this){
val apkFile = File(getExternalFilesDir("Downloads"), "update.apk")
val expectedChecksum = it.get("Checksum") // Provide your expected checksum here
val algorithm = "SHA-256" // Choose the algorithm you want to use (e.g., MD5, SHA-1, SHA-256)
val isIntegrityVerified = verifyChecksum(apkFile, expectedChecksum!!, algorithm)
if (isIntegrityVerified) {
println("APK integrity verified: The file has not been tampered with.")
installApk(apkFile)
} else {
println("APK integrity check failed: The file may have been tampered with.")
}
}
val drawerLayout: DrawerLayout = binding.drawerLayout val drawerLayout: DrawerLayout = binding.drawerLayout
val navView: NavigationView = binding.navView val navView: NavigationView = binding.navView
@@ -175,7 +174,24 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
} }
fun calculateChecksum(file: File, algorithm: String): String {
val digest = MessageDigest.getInstance(algorithm)
val inputStream = file.inputStream()
val buffer = ByteArray(8192)
var bytesRead = inputStream.read(buffer)
while (bytesRead != -1) {
digest.update(buffer, 0, bytesRead)
bytesRead = inputStream.read(buffer)
}
val checksumBytes = digest.digest()
return checksumBytes.joinToString("") { "%02x".format(it) }
}
// Function to verify checksum
fun verifyChecksum(file: File, expectedChecksum: String, algorithm: String): Boolean {
val actualChecksum = calculateChecksum(file, algorithm)
return actualChecksum.equals(expectedChecksum, ignoreCase = true)
}
private fun installApk(file: File) { private fun installApk(file: File) {
val pInfo = baseContext.packageManager.getPackageInfo(baseContext.packageName, 0) val pInfo = baseContext.packageManager.getPackageInfo(baseContext.packageName, 0)
val uri: Uri = FileProvider.getUriForFile( val uri: Uri = FileProvider.getUriForFile(
@@ -212,41 +228,41 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
val firebaseAppDistribution = FirebaseAppDistribution.getInstance() // val firebaseAppDistribution = FirebaseAppDistribution.getInstance()
firebaseAppDistribution.updateIfNewReleaseAvailable() // firebaseAppDistribution.updateIfNewReleaseAvailable()
.addOnProgressListener { updateProgress -> // .addOnProgressListener { updateProgress ->
//
if (updateProgress.apkBytesDownloaded > 0) { // if (updateProgress.apkBytesDownloaded > 0) {
Toast.makeText( // Toast.makeText(
this, // this,
"${updateProgress.updateStatus}. ${updateProgress.apkBytesDownloaded / 1048576} /${updateProgress.apkFileTotalBytes / 1048576} MB", // "${updateProgress.updateStatus}. ${updateProgress.apkBytesDownloaded / 1048576} /${updateProgress.apkFileTotalBytes / 1048576} MB",
Toast.LENGTH_SHORT // Toast.LENGTH_SHORT
).show() // ).show()
} // }
} // }
.addOnFailureListener { e -> // .addOnFailureListener { e ->
// (Optional) Handle errors. // // (Optional) Handle errors.
if (e is FirebaseAppDistributionException) { // if (e is FirebaseAppDistributionException) {
when (e.errorCode) { // when (e.errorCode) {
FirebaseAppDistributionException.Status.NOT_IMPLEMENTED -> { // FirebaseAppDistributionException.Status.NOT_IMPLEMENTED -> {
// SDK did nothing. This is expected when building for Play. // // SDK did nothing. This is expected when building for Play.
} // }
//
else -> { // else -> {
// Handle other errors. // // Handle other errors.
Toast.makeText( // Toast.makeText(
this, // this,
"AppDistribution error, status: ${e.errorCode}", // "AppDistribution error, status: ${e.errorCode}",
Toast.LENGTH_SHORT // Toast.LENGTH_SHORT
).show() // ).show()
} // }
} // }
FirebaseCrashlytics.getInstance().recordException(e) // FirebaseCrashlytics.getInstance().recordException(e)
} // }
} // }
.addOnSuccessListener { // .addOnSuccessListener {
// Toast.makeText(this, "App Update: Success!", Toast.LENGTH_SHORT).show() //// Toast.makeText(this, "App Update: Success!", Toast.LENGTH_SHORT).show()
} // }
} }
override fun setConnect(connect: Boolean) { override fun setConnect(connect: Boolean) {
@@ -265,7 +281,7 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
private fun createDeviceUpdateRequestData(): DeviceUpdateRequest { private fun createDeviceUpdateRequestData(): DeviceUpdateRequest {
return DeviceUpdateRequest( return DeviceUpdateRequest(
serial_no = sharedPreference.getString(Constants.DEVICE_ID, "") serial_no = sharedPreferences.getString(Constants.DEVICE_ID, "")
) )
} }
private fun getAppVersion(context: Context): String { private fun getAppVersion(context: Context): String {
@@ -284,4 +300,6 @@ class DashboardActivity : AppCompatActivity(), IDataCollector {
"N/A" "N/A"
} }
} }
} }

View File

@@ -28,6 +28,7 @@ import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.presentation.autodac.AutoDacActivity import com.example.hpostesting.presentation.autodac.AutoDacActivity
import com.example.hpostesting.presentation.buffercheck.HemocubeBufferCheckActivity import com.example.hpostesting.presentation.buffercheck.HemocubeBufferCheckActivity
import com.example.hpostesting.presentation.calibration.CalibrationActivity import com.example.hpostesting.presentation.calibration.CalibrationActivity
import com.example.hpostesting.presentation.dashboard.ui.PasswordResetActivity
import com.example.hpostesting.presentation.deviceinfo.DeviceActivity import com.example.hpostesting.presentation.deviceinfo.DeviceActivity
import com.example.hpostesting.presentation.deviceprovision.DeviceProvisionActivity import com.example.hpostesting.presentation.deviceprovision.DeviceProvisionActivity
import com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity import com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity
@@ -86,22 +87,32 @@ class GalleryFragment : Fragment() {
binding.btnUsbTerminal.visibility = View.VISIBLE binding.btnUsbTerminal.visibility = View.VISIBLE
binding.btnSubmit.visibility = View.VISIBLE binding.btnSubmit.visibility = View.VISIBLE
binding.btnDeviceInfo.visibility = View.VISIBLE binding.btnDeviceInfo.visibility = View.VISIBLE
binding.btnResetPassword.visibility = View.VISIBLE
binding.btnUpdateValues.visibility = View.VISIBLE
}else{ }else{
binding.btnResetPassword.visibility = View.GONE
binding.btnDeviceProvision.visibility = View.GONE binding.btnDeviceProvision.visibility = View.GONE
binding.btnAutoDac.visibility = View.GONE binding.btnAutoDac.visibility = View.VISIBLE
binding.btnDeviceProvision.visibility = View.GONE binding.btnDeviceProvision.visibility = View.GONE
binding.btnDiagnostics.visibility = View.GONE binding.btnDiagnostics.visibility = View.VISIBLE
binding.btnFiles.visibility = View.GONE binding.btnFiles.visibility = View.GONE
binding.btnFirefox.visibility = View.GONE binding.btnFirefox.visibility = View.GONE
binding.btnCalibration.visibility = View.GONE binding.btnCalibration.visibility = View.GONE
binding.btnUsbTerminal.visibility = View.GONE binding.btnUsbTerminal.visibility = View.GONE
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
binding.btnDeviceInfo.visibility = View.VISIBLE binding.btnDeviceInfo.visibility = View.VISIBLE
binding.btnUpdateValues.visibility = View.GONE
} }
binding.btnResetPassword.setOnClickListener{
startActivity(Intent(requireContext(), PasswordResetActivity::class.java))
}
binding.btnDeviceProvision.setOnClickListener { binding.btnDeviceProvision.setOnClickListener {
startActivity(Intent(requireContext(), DeviceProvisionActivity::class.java)) startActivity(Intent(requireContext(), DeviceProvisionActivity::class.java))
} }
binding.btnUpdateValues.setOnClickListener {
startActivity(Intent(requireContext(), UpdateValuesActivity::class.java))
}
binding.btnUsbTerminal.setOnClickListener { binding.btnUsbTerminal.setOnClickListener {
startActivity(Intent(requireContext(), UsbTerminalActivity::class.java)) startActivity(Intent(requireContext(), UsbTerminalActivity::class.java))
} }

View File

@@ -37,6 +37,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
@@ -70,17 +71,24 @@ import com.google.firebase.perf.ktx.performance
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 kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import okhttp3.ResponseBody import okhttp3.ResponseBody
import org.json.JSONObject import org.json.JSONObject
import java.io.BufferedOutputStream import java.io.BufferedOutputStream
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.net.HttpURLConnection
import java.net.URL
import java.nio.charset.Charset import java.nio.charset.Charset
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import java.util.Scanner
import java.util.zip.ZipEntry import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream import java.util.zip.ZipInputStream
import kotlin.properties.Delegates import kotlin.properties.Delegates
@@ -126,7 +134,7 @@ class HomeFragment : Fragment() {
getDeviceId() getDeviceId()
checkUnprocessedCSVData() checkUnprocessedCSVData()
checkForUpdate() //checkForUpdate()
viewModel.allUserData.observe(viewLifecycleOwner) { userData -> viewModel.allUserData.observe(viewLifecycleOwner) { userData ->
deleteIncompleteRegistrations(userData) deleteIncompleteRegistrations(userData)
} }
@@ -140,10 +148,14 @@ class HomeFragment : Fragment() {
}else if(it.testStatus == true){ }else if(it.testStatus == true){
userList.removeAll(userData) userList.removeAll(userData)
} }
if (timeDifference(it.incubationTime) >= 50){
userList.removeAll(userData)
}
} }
val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager val bm = requireContext().getSystemService(BATTERY_SERVICE) as BatteryManager
val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) val batLevel: Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
adapter = OfflineUserListAdapter(binding.root, batLevel) adapter = OfflineUserListAdapter(binding.root, batLevel,"Home")
adapter.differ.submitList(userList) adapter.differ.submitList(userList)
binding.rvOrderOffline.adapter = adapter binding.rvOrderOffline.adapter = adapter
} }
@@ -168,17 +180,17 @@ class HomeFragment : Fragment() {
.show() .show()
} }
} }
binding.btnLogout.setOnClickListener { // binding.btnLogout.setOnClickListener {
logoutUser(requireContext()) // logoutUser(requireContext())
} // }
binding.btnLogout1.setOnClickListener { binding.btnLogout1.setOnClickListener {
logoutUser(requireContext()) logoutUser(requireContext())
} }
binding.uploadData.setOnClickListener { // binding.uploadData.setOnClickListener {
// showUploadDialog(requireContext()) //// showUploadDialog(requireContext())
} // }
hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData -> hemoCubeViewModel.allUserData.observe(viewLifecycleOwner) { userData ->
if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") { if (sharedPreference.getString(Constants.USER_ID, "").toString() == "ADMIN") {
val btnSaveLocalVisibility = val btnSaveLocalVisibility =
@@ -203,27 +215,32 @@ class HomeFragment : Fragment() {
} }
binding.btnNewKit.setOnClickListener { // binding.btnNewKit.setOnClickListener {
with(sharedPreference.edit()) { // with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "") // putString(Constants.KIT_NUMBER, "")
putInt(Constants.KIT_COUNT, 0) // putInt(Constants.KIT_COUNT, 0)
apply() // apply()
} // }
startActivity(Intent(requireContext(), KitScanActivity::class.java)) // startActivity(Intent(requireContext(), KitScanActivity::class.java))
requireActivity().finish() // // requireActivity().finish()
} // }
binding.btnNewKitoffline.setOnClickListener { binding.btnNewKitoffline.setOnClickListener {
with(sharedPreference.edit()) { // with(sharedPreference.edit()) {
putString(Constants.KIT_NUMBER, "") // putString(Constants.KIT_NUMBER, "")
putInt(Constants.KIT_COUNT, 0) // putInt(Constants.KIT_COUNT, 0)
apply() // apply()
} // }
startActivity(Intent(requireContext(), KitScanActivity::class.java)) startActivity(Intent(requireContext(), KitScanActivity::class.java))
requireActivity().finish() // requireActivity().finish()
} }
binding.btnQuickCapture.setOnClickListener { binding.btnQuickCapture.setOnClickListener {
with(sharedPreference.edit()) {
putBoolean(Constants.QUICK_CAPTURE, true)
apply()
}
DataHolder.quickCapture = true
DataHolder.hemoCubeTestData = HemoCubeTestData() DataHolder.hemoCubeTestData = HemoCubeTestData()
val i = Intent( val i = Intent(
@@ -239,23 +256,24 @@ class HomeFragment : Fragment() {
checkNetworkStatus() checkNetworkStatus()
} }
@RequiresApi(Build.VERSION_CODES.P) @RequiresApi(Build.VERSION_CODES.P)
private fun checkNetworkStatus() { private fun checkNetworkStatus() {
hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isConnected -> hemoCubeViewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isConnected ->
// Toast.makeText(requireContext(),"connected"+isConnected+wasConnected, Toast.LENGTH_SHORT).show() // Toast.makeText(requireContext(),"connected"+isConnected+wasConnected, Toast.LENGTH_SHORT).show()
if (isConnected != wasConnected) { if (isConnected != wasConnected) {
if (isConnected) { if (isConnected) {
binding.internetAvailableCL.visibility = View.VISIBLE binding.tvTitleNoInternet.text = "Please enter the user id and select blood group to start the test."
binding.internetNotAvailableCL.visibility = View.GONE //binding.internetAvailableCL.visibility = View.VISIBLE
binding.pendingTest.visibility = View.VISIBLE binding.internetIcon.setImageDrawable(AppCompatResources.getDrawable(requireContext(),R.drawable.internet))
loadUserData() binding.internetNotAvailableCL.visibility = View.VISIBLE
setSearch() binding.pendingTest.visibility = View.GONE
checkForLocalDBData() setUserId()
// loadUserData()
// setSearch()
//checkForLocalDBData()
if (Constants.MOLBIO_INTEGRATION) { if (Constants.MOLBIO_INTEGRATION) {
checkForTokenAndUpdate() checkForTokenAndUpdate()
} }
// Now re-subscribe to allUserData // Now re-subscribe to allUserData
/* hemoCubeViewModel.allLocalData.observe(viewLifecycleOwner) { originalUserDataList -> /* hemoCubeViewModel.allLocalData.observe(viewLifecycleOwner) { originalUserDataList ->
@@ -320,11 +338,15 @@ class HomeFragment : Fragment() {
} }
}*/ }*/
hemoCubeViewModel.sendDataToMolbio() if(Constants.MOLBIO_INTEGRATION){
hemoCubeViewModel.sendDataToMolbio()
}
hemoCubeViewModel.sendDataToFirebase() hemoCubeViewModel.sendDataToFirebase()
} else { } else {
binding.internetAvailableCL.visibility = View.GONE binding.tvTitleNoInternet.text = getString(R.string.internet_not_available_please_enter_the_user_id_manually)
// binding.internetAvailableCL.visibility = View.GONE
binding.internetIcon.setImageDrawable(AppCompatResources.getDrawable(requireContext(),R.drawable.off))
binding.pendingTest.visibility = View.GONE binding.pendingTest.visibility = View.GONE
binding.internetNotAvailableCL.visibility = View.VISIBLE binding.internetNotAvailableCL.visibility = View.VISIBLE
setUserId() setUserId()
@@ -332,7 +354,9 @@ class HomeFragment : Fragment() {
wasConnected = isConnected wasConnected = isConnected
}else{ }else{
if(!wasConnected){ if(!wasConnected){
binding.internetAvailableCL.visibility = View.GONE binding.internetIcon.setImageDrawable(AppCompatResources.getDrawable(requireContext(),R.drawable.off))
binding.tvTitleNoInternet.text = getString(R.string.internet_not_available_please_enter_the_user_id_manually)
// binding.internetAvailableCL.visibility = View.GONE
binding.pendingTest.visibility = View.GONE binding.pendingTest.visibility = View.GONE
binding.internetNotAvailableCL.visibility = View.VISIBLE binding.internetNotAvailableCL.visibility = View.VISIBLE
setUserId() setUserId()
@@ -355,7 +379,8 @@ class HomeFragment : Fragment() {
Log.d("istoken", isTokenAvailable.toString()) Log.d("istoken", isTokenAvailable.toString())
if (!isTokenAvailable) { if (!isTokenAvailable) {
Log.d("istoken1", isTokenAvailable.toString()) Log.d("istoken1", isTokenAvailable.toString())
hemoCubeViewModel.login(createLoginRequestData(userID, password)) callLogin(userID, password)
// hemoCubeViewModel.login(createLoginRequestData(userID, password))
//isTokenAvailable = true //isTokenAvailable = true
@@ -363,7 +388,8 @@ class HomeFragment : Fragment() {
Log.d("istoken7", isTokenAvailable.toString()) Log.d("istoken7", isTokenAvailable.toString())
if (isTokenExpired(accessToken)) { if (isTokenExpired(accessToken)) {
Log.d("istoken8", isTokenAvailable.toString()) Log.d("istoken8", isTokenAvailable.toString())
hemoCubeViewModel.login(createLoginRequestData(userID, password)) callLogin(userID, password)
// hemoCubeViewModel.login(createLoginRequestData(userID, password))
//hemoCubeViewModel.startPeriodicCheckUpdate() //hemoCubeViewModel.startPeriodicCheckUpdate()
}else{ }else{
hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData()) hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData())
@@ -373,22 +399,24 @@ class HomeFragment : Fragment() {
} }
} else if (userID == "deviceIDAPI" && password == "devicePasswordAPI" && deviceId.isNotEmpty()) { } else if (userID == "deviceIDAPI" && password == "devicePasswordAPI" && deviceId.isNotEmpty()) {
fetchDeviceCredentials() fetchDeviceCredentials()
} else if (file.exists()) { } else if (file.exists()) {// change back without!
val encryptedString = file.readText() val encryptedString = file.readText()
val encryptionKey = val encryptionKey =
Settings.Secure.getString(context?.contentResolver, Settings.Secure.ANDROID_ID) Settings.Secure.getString(context?.contentResolver, Settings.Secure.ANDROID_ID)
// val decryptedMessage: String = Encryption.decrypt(encryptedString, encryptionKey) val decryptedMessage: String = Encryption.decrypt(encryptedString, encryptionKey)
// val credentials = decryptedMessage.split("\n") val credentials = decryptedMessage.split("\n")
// userID = credentials[0] userID = credentials[0]
// password = credentials[1] password = credentials[1]
// Toast.makeText(context, "DECRYPTED: $credentials", Toast.LENGTH_SHORT).show() Toast.makeText(context, "DECRYPTED: $credentials", Toast.LENGTH_SHORT).show()
if (!isTokenAvailable) { if (!isTokenAvailable) {
hemoCubeViewModel.login(createLoginRequestData(userID, password)) callLogin(userID, password)
//hemoCubeViewModel.login(createLoginRequestData(userID, password))
} }
else if (isTokenAvailable) { else if (isTokenAvailable) {
//hemoCubeViewModel.startPeriodicCheckUpdate() //hemoCubeViewModel.startPeriodicCheckUpdate()
if (isTokenExpired(accessToken)) { if (isTokenExpired(accessToken)) {
hemoCubeViewModel.login(createLoginRequestData(userID, password)) callLogin(userID, password)
//hemoCubeViewModel.login(createLoginRequestData(userID, password))
}else{ }else{
hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData()) hemoCubeViewModel.checkUpdate(createCheckUpdateRequestData())
} }
@@ -646,10 +674,9 @@ class HomeFragment : Fragment() {
val version = pInfo.versionName val version = pInfo.versionName
var labname = sharedPreference.getString(Constants.LABNAME,"") var labname = sharedPreference.getString(Constants.LABNAME,"")
return LoginRequest( return LoginRequest(
password = password, serialNumber = userID, username = userID, version = version, lab = labname location = DataHolder.ipAddress, password = password, serialNumber = userID, username = userID, version = version, lab = labname
) )
}//latitude = DataHolder.location!!.latitude.toString(), longitude = DataHolder.location!!.longitude.toString(), location = DataHolder.location.toString() }
private fun createCheckUpdateRequestData(): CheckUpdateRequest { private fun createCheckUpdateRequestData(): CheckUpdateRequest {
val pInfo = requireActivity().packageManager.getPackageInfo( val pInfo = requireActivity().packageManager.getPackageInfo(
requireActivity().packageName, 0 requireActivity().packageName, 0
@@ -782,7 +809,8 @@ class HomeFragment : Fragment() {
} }
if (!isTokenAvailable) { if (!isTokenAvailable) {
Log.d("istoken0", isTokenAvailable.toString()) Log.d("istoken0", isTokenAvailable.toString())
hemoCubeViewModel.login(createLoginRequestData(username, password)) callLogin(username, password)
//hemoCubeViewModel.login(createLoginRequestData(username, password))
} }
} ?: Log.e("fetchDeviceCredentials", "Failed to parse device data.") } ?: Log.e("fetchDeviceCredentials", "Failed to parse device data.")
@@ -832,7 +860,7 @@ class HomeFragment : Fragment() {
requireActivity() requireActivity()
) )
}!! }!!
binding.rvOrder.adapter = rvAdapter // binding.rvOrder.adapter = rvAdapter
rvAdapter.startListening() rvAdapter.startListening()
} catch (e: Exception) { } catch (e: Exception) {
@@ -901,50 +929,54 @@ class HomeFragment : Fragment() {
requireActivity() requireActivity()
) )
}!! }!!
binding.rvOrder.adapter = rvAdapter // binding.rvOrder.adapter = rvAdapter
rvAdapter.startListening() rvAdapter.startListening()
userSearchTrace.stop() userSearchTrace.stop()
} }
private fun setSearch() { // private fun setSearch() {
binding.searchProduct.setOnQueryTextListener(object : // binding.searchProduct.setOnQueryTextListener(object :
androidx.appcompat.widget.SearchView.OnQueryTextListener { // androidx.appcompat.widget.SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean { // override fun onQueryTextSubmit(query: String?): Boolean {
return if (!query.isNullOrEmpty()) { // return if (!query.isNullOrEmpty()) {
val field = when { // val field = when {
binding.userIdRadioButton.isChecked -> "_id" // binding.userIdRadioButton.isChecked -> "_id"
binding.abhaIdRadioButton.isChecked -> "abhaId" // binding.abhaIdRadioButton.isChecked -> "abhaId"
binding.aadharIdRadioButton.isChecked -> "aadharId" // binding.aadharIdRadioButton.isChecked -> "aadharId"
else -> null // else -> null
} // }
//
field?.let { getData(query, it) } // field?.let {
false // //getData(query, it) }
// }
} else { // false
loadUserData() //
false // } else {
} // // loadUserData()
} // false
// }
override fun onQueryTextChange(query: String?): Boolean { // }
return if (!query.isNullOrEmpty()) { //
val field = when { // override fun onQueryTextChange(query: String?): Boolean {
binding.userIdRadioButton.isChecked -> "_id" // return if (!query.isNullOrEmpty()) {
binding.abhaIdRadioButton.isChecked -> "abhaId" // val field = when {
binding.aadharIdRadioButton.isChecked -> "aadharId" // binding.userIdRadioButton.isChecked -> "_id"
else -> null // binding.abhaIdRadioButton.isChecked -> "abhaId"
} // binding.aadharIdRadioButton.isChecked -> "aadharId"
field?.let { getData(query, it) } // else -> null
false // }
} else { // field?.let {
loadUserData() // //getData(query, it)
false // }
} // false
} // } else {
}) // // loadUserData()
} // false
// }
// }
// })
// }
private fun checkForLocalDBData() { private fun checkForLocalDBData() {
// viewModel.allUserData.observe(viewLifecycleOwner) { userDataList -> // viewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
@@ -958,11 +990,11 @@ class HomeFragment : Fragment() {
// binding.uploadData.visibility = uploadDataVisibility // binding.uploadData.visibility = uploadDataVisibility
// } // }
hemoCubeViewModel.allKitTestData.observe(viewLifecycleOwner) { bufferData -> // hemoCubeViewModel.allKitTestData.observe(viewLifecycleOwner) { bufferData ->
val uploadDataVisibility = // val uploadDataVisibility =
if (bufferData.any { !it.localFlag }) View.VISIBLE else View.GONE // if (bufferData.any { !it.localFlag }) View.VISIBLE else View.GONE
binding.uploadData.visibility = uploadDataVisibility // binding.uploadData.visibility = uploadDataVisibility
} // }
} }
private fun checkUnprocessedCSVData() { private fun checkUnprocessedCSVData() {
@@ -1074,15 +1106,15 @@ class HomeFragment : Fragment() {
// dialog.dismiss() // dialog.dismiss()
// } // }
hemoCubeViewModel.allKitTestData.observe(viewLifecycleOwner) { kitDataList -> // hemoCubeViewModel.allKitTestData.observe(viewLifecycleOwner) { kitDataList ->
kitDataList.forEach { userData -> // kitDataList.forEach { userData ->
if (!userData.localFlag) { // if (!userData.localFlag) {
userData.localFlag = true // userData.localFlag = true
hemoCubeViewModel.bulkAddResultKitTestToDb(userData) // hemoCubeViewModel.bulkAddResultKitTestToDb(userData)
} // }
} // }
dialog.dismiss() // dialog.dismiss()
} // }
} }
private fun downloadLocalDBData(dialog: DialogInterface) { private fun downloadLocalDBData(dialog: DialogInterface) {
@@ -1166,7 +1198,11 @@ class HomeFragment : Fragment() {
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
hemoCubeViewModel.networkStatusLiveData.removeObservers(viewLifecycleOwner) hemoCubeViewModel.networkStatusLiveData.removeObservers(viewLifecycleOwner)
hemoCubeViewModel.allKitTestData.removeObservers(viewLifecycleOwner)
hemoCubeViewModel.allUserData.removeObservers(viewLifecycleOwner)
hemoCubeViewModel.uploadLogs.removeObservers(viewLifecycleOwner)
hemoCubeViewModel.checkUpdate.removeObservers(viewLifecycleOwner)
hemoCubeViewModel.downloadcertificate.removeObservers(viewLifecycleOwner)
} }
private fun downloadCsv() { private fun downloadCsv() {
@@ -1473,6 +1509,66 @@ class HomeFragment : Fragment() {
super.onDestroy() super.onDestroy()
} }
@OptIn(DelicateCoroutinesApi::class)
private fun getPublicIpAddr(callback: (String) -> Unit) {
try {
GlobalScope.launch(Dispatchers.IO) {
val url = URL("https://api.ipify.org")
val conn = url.openConnection() as HttpURLConnection
try {
conn.connect()
if (conn.responseCode == HttpURLConnection.HTTP_OK) {
val scanner = Scanner(conn.inputStream)
scanner.useDelimiter("\\A")
if (scanner.hasNext()) {
val ipAddress = scanner.next()
Log.d("ipaddress",DataHolder.ipAddress)
callback(ipAddress)
}else{
callback("fail")
}
}
} finally {
conn.disconnect()
}
}
}catch (e: Exception){
Log.e("home",e.toString())
callback("fail")
}
}
private fun callLogin(userID: String, password: String) {
if(DataHolder.ipAddress == "0.0"){
getPublicIpAddr { ipAddress ->
if(ipAddress != "fail"){
DataHolder.ipAddress = ipAddress
with(sharedPreference.edit()) {
putString(Constants.IP_ADDRESS, ipAddress)
apply()
}
}
hemoCubeViewModel.login(createLoginRequestData(userID, password))
}
}else{
hemoCubeViewModel.login(createLoginRequestData(userID, password))
}
}
private fun timeDifference(createdAt: String): Long {
val currentTime = Calendar.getInstance().time
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
val createdAtDate: Date = if (createdAt.isEmpty()) {
currentTime
} else {
formatter.parse(createdAt) ?: currentTime
}
val diffMillis = currentTime.time - createdAtDate.time
return diffMillis / (60 * 1000) // Convert milliseconds to minutes
}
} }

View File

@@ -20,6 +20,8 @@ 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 android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
@@ -38,6 +40,8 @@ import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding
private var isLanguageChanged = false private var isLanguageChanged = false
class SlideshowFragment : Fragment(){ class SlideshowFragment : Fragment(){
private var selectedItem = "10mm"
private val values = arrayOf("10mm", "2mm")
private lateinit var binding: FragmentSlideshowBinding private lateinit var binding: FragmentSlideshowBinding
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
override fun onCreateView( override fun onCreateView(
@@ -54,6 +58,7 @@ class SlideshowFragment : Fragment(){
binding.nameEditText.setText(sharedPreferences.getString(Constants.LABNAME,"")) binding.nameEditText.setText(sharedPreferences.getString(Constants.LABNAME,""))
selectedItem = sharedPreferences.getString(Constants.CUVETTE_SIZE,"10mm").toString()
binding.btnGo.setOnClickListener { binding.btnGo.setOnClickListener {
var labname = binding.nameEditText.text.toString() var labname = binding.nameEditText.text.toString()
@@ -72,6 +77,35 @@ class SlideshowFragment : Fragment(){
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} }
val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, values)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
val pos: Int
if(selectedItem == "10mm"){
pos = 0
}else{
pos = 1
}
binding.spinnerCuvette.adapter = adapter
binding.spinnerCuvette.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
// Handle item selection here
selectedItem = values[position]
}
override fun onNothingSelected(parent: AdapterView<*>?) {
// Do nothing here
}
}
binding.spinnerCuvette.setSelection(pos)
binding.btnAddSize.setOnClickListener {
with(sharedPreferences.edit()) {
putString(Constants.CUVETTE_SIZE, selectedItem)
apply()
}
Toast.makeText(requireContext(), "Selected cuvette size: $selectedItem", Toast.LENGTH_SHORT).show()
}
childFragmentManager.beginTransaction().replace(binding.container.id,PrefsFragment()).commit() childFragmentManager.beginTransaction().replace(binding.container.id,PrefsFragment()).commit()
} }
} }

View File

@@ -0,0 +1,50 @@
/*
* // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
* // Notice: All information contained herein is, and remains
* // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
* // if any. The intellectual and technical concepts contained
* // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
* // and its suppliers and may be covered by Indian and Foreign Patents,
* // patents in process, and are protected by trade secret or copyright law.
* // Dissemination of this information or reproduction of this material
* // is strictly forbidden unless prior written permission is obtained
* // from ShanMukha Innovations Pvt. Ltd.
*/
package com.example.hpostesting.presentation.dashboard
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.example.hpostesting.data.constant.Constants
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
import `in`.sminnovations.hpostesting.databinding.ActivityUpdateValuesBinding
class UpdateValuesActivity : AppCompatActivity() {
private lateinit var binding: ActivityUpdateValuesBinding
lateinit var sharedPreferences: SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityUpdateValuesBinding.inflate(layoutInflater)
sharedPreferences = this.getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
setContentView(binding.root)
binding.btnSubmit.setOnClickListener {
saveStringToPreferences(Constants.ABS2LED1MMLL, binding.et2mmled1Ll.text.toString())
saveStringToPreferences(Constants.ABS2LED1MMUL, binding.et2mmled1Ul.text.toString())
saveStringToPreferences(Constants.ABS2LED2MMLL, binding.et2mmled2Ll.text.toString())
saveStringToPreferences(Constants.ABS2LED2MMUL, binding.et2mmled2Ul.text.toString())
saveStringToPreferences(Constants.ABS10LED1MMLL, binding.et10mmled1Ll.text.toString())
saveStringToPreferences(Constants.ABS10LED1MMUL, binding.et10mmled1Ul.text.toString())
saveStringToPreferences(Constants.ABS10LED2MMLL, binding.et10mmled2Ll.text.toString())
saveStringToPreferences(Constants.ABS10LED2MMUL, binding.et10mmled2Ul.text.toString())
}
}
private fun saveStringToPreferences(key: String, value: String) {
sharedPreferences.edit().putString(key, value).apply()
}
}

View File

@@ -13,15 +13,17 @@
package com.example.hpostesting.presentation.dashboard.ui package com.example.hpostesting.presentation.dashboard.ui
import com.example.hpostesting.util.SecureStorage
import android.accounts.Account
import android.accounts.AccountManager
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Context.WIFI_SERVICE
import android.content.SharedPreferences import android.content.SharedPreferences
import android.location.Location import android.location.Location
import android.location.LocationListener import android.location.LocationListener
import android.location.LocationManager import android.location.LocationManager
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.wifi.WifiManager import android.net.NetworkCapabilities
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
@@ -30,10 +32,11 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat.getSystemService
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.DataHolder
import com.example.hpostesting.util.AppInitializer
import `in`.sminnovations.hpostesting.R import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentLoginBinding import `in`.sminnovations.hpostesting.databinding.FragmentLoginBinding
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -47,6 +50,8 @@ import java.util.Scanner
class LoginFragment : Fragment() { class LoginFragment : Fragment() {
var latitude = 0.0 var latitude = 0.0
var longitude = 0.0 var longitude = 0.0
private lateinit var accountManager: AccountManager
private lateinit var secureStorage: SecureStorage
var TAG = "LoginFragmentCheck" var TAG = "LoginFragmentCheck"
private var _binding: FragmentLoginBinding? = null private var _binding: FragmentLoginBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
@@ -58,6 +63,11 @@ class LoginFragment : Fragment() {
_binding = FragmentLoginBinding.inflate(inflater, container, false) _binding = FragmentLoginBinding.inflate(inflater, container, false)
sharedPreference = sharedPreference =
requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
accountManager = AccountManager.get(requireActivity())
secureStorage = SecureStorage(requireActivity())
// Initialize user roles and credentials if not already done
AppInitializer.initialize(requireActivity())
return binding.root return binding.root
} }
@@ -65,7 +75,14 @@ class LoginFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
init() init()
checkLocation() if(isInternetAvailable()){
getPublicIpAddr { ipAddress ->
DataHolder.ipAddress = ipAddress
}
Log.d("ipaddress",DataHolder.ipAddress)
}
//checkLocation()
} }
private fun init() { private fun init() {
if (isUserLoggedIn()) { if (isUserLoggedIn()) {
@@ -75,18 +92,19 @@ class LoginFragment : Fragment() {
binding.btnLogin.setOnClickListener { binding.btnLogin.setOnClickListener {
// Toast.makeText(requireContext(), "$latitude/$longitude",Toast.LENGTH_SHORT).show() // Toast.makeText(requireContext(), "$latitude/$longitude",Toast.LENGTH_SHORT).show()
val loginId = binding.loginId.text.toString().trim()
val loginId = binding.loginId.text.toString() val password = binding.password.text.toString().trim()
val password = binding.password.text.toString()
if (loginId.isNotBlank() && password.isNotBlank()) { if (loginId.isNotBlank() && password.isNotBlank()) {
performLogin(loginId, password) performLogin(loginId, password)
} else { } else {
if (loginId.isBlank()) { if (loginId.isBlank()) {
binding.loginId.error = R.string.enter_proper_login_id.toString() binding.loginId.error = R.string.enter_proper_login_id.toString()
Log.d("LoginFragment","enter proper login id")
} }
if (password.isBlank()) { if (password.isBlank()) {
binding.password.error = R.string.enter_proper_password.toString() binding.password.error = R.string.enter_proper_password.toString()
Log.d("LoginFragment","enter proper password")
} }
} }
} }
@@ -97,28 +115,78 @@ class LoginFragment : Fragment() {
} }
private fun navigateToHomeFragment() { private fun navigateToHomeFragment() {
Log.d("LoginFragment","Login Successful")
findNavController().navigate(R.id.action_loginFragment_to_homeFragment) findNavController().navigate(R.id.action_loginFragment_to_homeFragment)
} }
private fun performLogin(loginId: String, password: String) { private fun performLogin(loginId: String, password: String) {
val matchingId = Constants.STATICID.firstOrNull { it == loginId } if (validateCredentials(loginId, password)) {
if (matchingId != null) { addAccount(loginId, password)
if (password == Constants.password) { val role = getRoleForUser(loginId)
saveUserId(loginId) saveUserId(role)
navigateToHomeFragment() navigateToHomeFragment()
return return
} else { } else {
Toast.makeText(requireContext(), R.string.wrong_password, Toast.LENGTH_SHORT).show() Toast.makeText(requireActivity(), "Invalid credentials", Toast.LENGTH_SHORT).show()
}
} }
Toast.makeText(requireContext(), R.string.wrong_user_id, Toast.LENGTH_SHORT).show() // val matchingId = Constants.STATICID.firstOrNull { it == loginId }
// if (matchingId != null) {
// if (password == Constants.password) {
// saveUserId(loginId)
// navigateToHomeFragment()
// return
// } else {
// Log.d("LoginFragment","wrong password")
// Toast.makeText(requireContext(), R.string.wrong_password, Toast.LENGTH_SHORT).show()
// }
// }
// Log.d("LoginFragment","wrong password")
// Toast.makeText(requireContext(), R.string.wrong_user_id, Toast.LENGTH_SHORT).show()
}
private fun getRoleForUser(username: String): String {
// Replace this with your actual logic to determine the role for the user
return when (username) {
"FACTORY" -> "FACTORY"
"ADMIN" -> "ADMIN"
"PQUSER" -> "PQUSER"
"QCUSER" -> "QCUSER"
else -> "HPOSUSER"
}
}
private fun validateCredentials(username: String, password: String): Boolean {
var storedPassword = secureStorage.getPassword()
// if (!checkUserName(binding.etName.text.toString())) {
// binding.etName.error = "Name field can't be empty or less than 3 characters"
// return false
// }
if (!checkCenterName(binding.centerName.text.toString())) {
binding.centerName.error = "Center name can't be empty or less than 3 characters"
return false
}
if(username == "ADMIN"){
storedPassword = secureStorage.getAdminPassword()
}
return storedPassword != null &&
password == storedPassword &&
(username == "HPOSUSER" || username == "ADMIN" || username == "FACTORY" || username == "PQUSER" || username == "QCUSER")
}
private fun addAccount(username: String, password: String) {
val account = Account(username, "com.example.account")
accountManager.addAccountExplicitly(account, password, null)
} }
private fun saveUserId(userId: String) { private fun saveUserId(userId: String) {
with(sharedPreference.edit()) { with(sharedPreference.edit()) {
putString(Constants.USER_ID, userId) putString(Constants.USER_ID, userId)
apply() apply()
} }
DataHolder.centerName = binding.centerName.text.toString()
DataHolder.district = binding.etDistrict.text.toString()
with(sharedPreference.edit()) {
putString(Constants.CENTER_NAME, binding.centerName.text.toString().lowercase().trim())
putString(Constants.DISTRICT, binding.etDistrict.text.toString())
apply()
}
} }
override fun onDestroyView() { override fun onDestroyView() {
@@ -246,5 +314,43 @@ class LoginFragment : Fragment() {
// } // }
// } // }
// } // }
private fun getPublicIpAddr(callback: (String) -> Unit) {
try {
GlobalScope.launch(Dispatchers.IO) {
val url = URL("https://api.ipify.org")
val conn = url.openConnection() as HttpURLConnection
try {
conn.connect()
if (conn.responseCode == HttpURLConnection.HTTP_OK) {
val scanner = Scanner(conn.inputStream)
scanner.useDelimiter("\\A")
if (scanner.hasNext()) {
val ipAddress = scanner.next()
callback(ipAddress)
}
}
} finally {
conn.disconnect()
}
}
}catch (e: Exception){
Log.e(TAG,e.toString())
}
}
@SuppressLint("NewApi")
private fun isInternetAvailable(): Boolean {
val connectivityManager = requireActivity().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val network = connectivityManager.activeNetwork ?: return false
val networkCapabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
}
private fun checkUserName(userName: String): Boolean {
return userName.isNotEmpty() && userName.length >= 3
}
private fun checkCenterName(centerName: String): Boolean {
return centerName.isNotEmpty() && centerName.length >= 3
}
} }

View File

@@ -0,0 +1,42 @@
package com.example.hpostesting.presentation.dashboard.ui
import com.example.hpostesting.util.SecureStorage
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import `in`.sminnovations.hpostesting.R
class PasswordResetActivity : AppCompatActivity() {
private lateinit var editTextNewPassword: EditText
private lateinit var buttonResetPassword: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_password_reset)
editTextNewPassword = findViewById(R.id.editTextNewPassword)
buttonResetPassword = findViewById(R.id.buttonResetPassword)
buttonResetPassword.setOnClickListener {
val newPassword = editTextNewPassword.text.toString().trim()
if (newPassword.isNotEmpty()) {
resetPassword(newPassword)
} else {
Toast.makeText(this, "Please enter a new password", Toast.LENGTH_SHORT).show()
}
}
}
private fun resetPassword(newPassword: String) {
// Implement password reset logic here
// For example, you can store the new password securely
// and update it in the authentication system
val secureStorage = SecureStorage(this)
secureStorage.storePassword(newPassword)
Toast.makeText(this, "Password reset successfully", Toast.LENGTH_SHORT).show()
finish()
}
}

View File

@@ -29,6 +29,7 @@ import android.os.Bundle
import android.os.IBinder import android.os.IBinder
import android.util.Log import android.util.Log
import android.view.Menu import android.view.Menu
import android.view.MenuItem
import android.widget.Toast import android.widget.Toast
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
@@ -105,8 +106,7 @@ class DeviceActivity : AppCompatActivity(), DeviceCommunicationHandler {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityDeviceBinding.inflate(layoutInflater) binding = ActivityDeviceBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
// setSupportActionBar(binding.myToolbar) binding.myToolbar.title = "Device Information"
supportActionBar?.setDisplayHomeAsUpEnabled(true)
setupListener() setupListener()
connectUsb(false) connectUsb(false)
} }

View File

@@ -141,7 +141,8 @@ class DeviceFragment : Fragment() {
val lines = resultData.split("\n") val lines = resultData.split("\n")
var temp = lines[2] var temp = lines[2]
val temp1 = resultData.substringAfter("#AS").substringBefore("#AC") val temp1 = resultData.substringAfter("#AS").substringBefore("#AC")
binding.tvSubtitleNew.text = "Device ID : "+hardwareId+"\nTemperature : $temp\n"+temp1 binding.tvSubtitleNew.text =
"Device ID : $hardwareId\nTemperature : $temp\n$temp1"
} }
} }

View File

@@ -118,12 +118,7 @@ class DeviceProvisionFragment : Fragment() {
) )
apply() apply()
} }
startActivity(
Intent(
requireContext(),
DashboardActivity::class.java
)
)
Toast.makeText( Toast.makeText(
activity, "Device registered successfully", Toast.LENGTH_LONG activity, "Device registered successfully", Toast.LENGTH_LONG
).show() ).show()
@@ -148,7 +143,13 @@ class DeviceProvisionFragment : Fragment() {
// viewModel.addDeviceId(DeviceData(deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString())) // viewModel.addDeviceId(DeviceData(deviceId = sharedPreferences.getString(Constants.DEVICE_ID, "").toString()))
Log.e("idpass", response.toString()) Log.e("idpass", response.toString())
Log.e("idpass", response.data.data?.credentials?.username.toString()) Log.e("idpass", response.data.data?.credentials?.username.toString())
Log.e("idpass", deviceProvisionResponse) // Log.e("idpass", deviceProvisionResponse)
startActivity(
Intent(
requireContext(),
DashboardActivity::class.java
)
)
} else { } else {
Toast.makeText( Toast.makeText(
activity, activity,

View File

@@ -18,6 +18,8 @@ import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.text.method.ScrollingMovementMethod
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@@ -26,8 +28,6 @@ import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpostesting.util.Result
import com.example.hpostesting.util.Result.Success
import com.example.hpostesting.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpostesting.data.constant.HemoCubeCommands import com.example.hpostesting.data.constant.HemoCubeCommands
import com.example.hpostesting.data.model.devicediagnostics.AdditionalDetails import com.example.hpostesting.data.model.devicediagnostics.AdditionalDetails
@@ -35,21 +35,33 @@ import com.example.hpostesting.data.model.devicediagnostics.DeviceDiagnosticsReq
import com.example.hpostesting.data.model.diagnostics.DiagnosticsData import com.example.hpostesting.data.model.diagnostics.DiagnosticsData
import com.example.hpostesting.data.model.patient.DeviceData import com.example.hpostesting.data.model.patient.DeviceData
import com.example.hpostesting.presentation.utils.UsbServiceListener import com.example.hpostesting.presentation.utils.UsbServiceListener
import com.example.hpostesting.util.Result
import com.example.hpostesting.util.Result.Success
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase import com.google.firebase.ktx.Firebase
import `in`.sminnovations.hpostesting.databinding.FragmentDiagnosticsBinding import `in`.sminnovations.hpostesting.databinding.FragmentDiagnosticsBinding
import org.apache.commons.math3.stat.regression.SimpleRegression
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Locale import java.util.Locale
class DiagnosticsFragment : Fragment() {
class DiagnosticsFragment : Fragment() {
// Initialize variables to store LED DAC values
var led1Dac: Double? = null
var led2Dac: Double? = null
var led3Dac: Double? = null
var led4Dac: Double? = null
private var currentProgress = 0
private val targetProgress = 95 // Target progress value
private val delayBetweenIncrements = 1500
private var testStatusCode = 0.0
private lateinit var binding: FragmentDiagnosticsBinding private lateinit var binding: FragmentDiagnosticsBinding
private val diagnosticsViewModel: DiagnosticsViewModel by activityViewModels() private val diagnosticsViewModel: DiagnosticsViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
private var currentDeviceData: DeviceData? = null private var currentDeviceData: DeviceData? = null
private var resultData: String = "" private var resultData: String = ""
private val messages = MutableLiveData<String>() private var currentResultData: String = ""
private var startListening = MutableLiveData(false) private var startListening = MutableLiveData(false)
private val batteryStatus: Intent? = private val batteryStatus: Intent? =
IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter -> IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
@@ -73,9 +85,14 @@ class DiagnosticsFragment : Fragment() {
private fun initViews() { private fun initViews() {
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
binding.tvSubtitle4.movementMethod = ScrollingMovementMethod()
listenToHemoCube() listenToHemoCube()
getDeviceId() getDeviceId()
binding.btnSubmit.setOnClickListener { binding.btnSubmit.setOnClickListener {
diagnosticsViewModel.messages.postValue("Processing diagnostics... Please wait.")
binding.progressBarHor.visibility = View.VISIBLE
incrementProgress()
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
runDeviceDiagnostics() runDeviceDiagnostics()
val batteryLevel = "" //diagnosticsViewModel.getBatteryLevel().toString() val batteryLevel = "" //diagnosticsViewModel.getBatteryLevel().toString()
@@ -91,12 +108,12 @@ class DiagnosticsFragment : Fragment() {
batteryTemperature = batteryTemperature, batteryTemperature = batteryTemperature,
batteryVoltage = batteryVoltage!! batteryVoltage = batteryVoltage!!
) )
diagnosticsViewModel.deviceDiagnostics( if(Constants.MOLBIO_INTEGRATION){
DeviceDiagnosticsRequest(additionalDetails = additionalDetails) diagnosticsViewModel.deviceDiagnostics(
) DeviceDiagnosticsRequest(additionalDetails = additionalDetails)
)
}
} }
} }
@@ -106,7 +123,7 @@ class DiagnosticsFragment : Fragment() {
currentDeviceData = it currentDeviceData = it
} }
messages.observe(viewLifecycleOwner) { diagnosticsViewModel.messages.observe(viewLifecycleOwner) {
binding.tvSubtitle4.text = it binding.tvSubtitle4.text = it
Log.e("diagnostics", binding.tvSubtitle4.text.toString()) Log.e("diagnostics", binding.tvSubtitle4.text.toString())
} }
@@ -153,6 +170,8 @@ class DiagnosticsFragment : Fragment() {
} }
is Result.Loading -> { is Result.Loading -> {
} }
else -> {}
} }
} }
@@ -165,11 +184,11 @@ class DiagnosticsFragment : Fragment() {
HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND, HemoCubeCommands.DEVICE_CONFIGURATION_COMMAND,
object : UsbServiceListener { object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
data?.let { // data?.let {
val stringData = String(it) // val stringData = String(it)
diagnosticsViewModel.messages.postValue(stringData) // diagnosticsViewModel.messages.postValue(stringData)
binding.tvSubtitle4.text = stringData // binding.tvSubtitle4.text = stringData
} // }
} }
override fun onUsbError(e: Exception?) { override fun onUsbError(e: Exception?) {
@@ -191,10 +210,35 @@ class DiagnosticsFragment : Fragment() {
} }
}) })
} }
private fun readCurrentDACValuesCommand() {
diagnosticsViewModel.progressBar.postValue(true)
(activity as DiagnosticsActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.READ_DAC_COMMAND,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
override fun onUsbError(e: Exception?) {
diagnosticsViewModel.progressBar.postValue(false)
}
})
}
private fun loadDACValues() {
diagnosticsViewModel.progressBar.postValue(true)
(activity as DiagnosticsActivity).mService.sendAndListenToHemoCube(
HemoCubeCommands.LOAD_DAC_VALUES,
object : UsbServiceListener {
override fun onUsbRead(data: ByteArray?) {
}
private fun listenToHemoCube() { override fun onUsbError(e: Exception?) {
diagnosticsViewModel.progressBar.postValue(false)
}
})
}
private fun listenToHemoCube() {
diagnosticsViewModel.messages.postValue("Place cuvette filled with buffer\n and click on start")
val fullReadOutput = StringBuilder() val fullReadOutput = StringBuilder()
startListening.postValue(true) startListening.postValue(true)
@@ -204,23 +248,24 @@ class DiagnosticsFragment : Fragment() {
override fun onUsbRead(data: ByteArray?) { override fun onUsbRead(data: ByteArray?) {
data?.let { data?.let {
val stringData = String(it) val stringData = String(it)
diagnosticsViewModel.messages.postValue(stringData)
fullReadOutput.append(stringData) fullReadOutput.append(stringData)
resultData += stringData handleUsbData(stringData)
binding.tvSubtitle4.text = resultData
if (stringData.contains("SN")) { // binding.tvSubtitle4.text = resultData
val slData = stringData.split(" ")
if (slData.size > 1) { // if (stringData.contains("SN")) {
val hardwareId = slData[1].trim() // val slData = stringData.split(" ")
with(sharedPreferences.edit()) { // if (slData.size > 1) {
putString(Constants.DEVICE_ID, hardwareId) // val hardwareId = slData[1].trim()
apply() // with(sharedPreferences.edit()) {
} // putString(Constants.DEVICE_ID, hardwareId)
} // apply()
activity?.runOnUiThread { // }
binding.btnSubmit.visibility = View.VISIBLE // }
} // activity?.runOnUiThread {
} // binding.btnSubmit.visibility = View.VISIBLE
// }
// }
} }
if (resultData.contains("END") || fullReadOutput.contains("END")) { if (resultData.contains("END") || fullReadOutput.contains("END")) {
@@ -268,6 +313,194 @@ class DiagnosticsFragment : Fragment() {
} }
} }
private fun handleUsbData(stringData: String) {
resultData += stringData
if (sharedPreferences.getString(Constants.USER_ID, "").toString() == "ADMIN") {
currentResultData += stringData
}
when {
(resultData.contains("SNE") && this.testStatusCode < 1.0) -> {
this.testStatusCode = 1.1
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
}
}
(resultData.contains("#DC") && this.testStatusCode < 1.4) -> {
this.testStatusCode = 1.5
activity?.runOnUiThread {
setProgress(96)
loadDACValues()
}
}
(resultData.contains("#EC") && this.testStatusCode < 1.6) -> {
this.testStatusCode = 1.7
activity?.runOnUiThread {
setProgress(98)
readCurrentDACValuesCommand()
}
}
(resultData.contains("#RC") && this.testStatusCode < 1.8) -> {
this.testStatusCode = 1.9
activity?.runOnUiThread {
finalCalculation()
setProgress(100)
binding.progressBarHor.visibility = View.GONE
currentResultData += "\nIf you are facing any issues while using the device \n Contact us for help at support@sminnovations.in"
diagnosticsViewModel.messages.postValue(currentResultData)
}
}
}
}
private fun finalCalculation() {
val pattern = Regex("(LED:\\d+)__DAC:(\\d+)__ADC:(\\d+)")
// Find all matches in the string
val matches = pattern.findAll(resultData)
// Initialize lists for x and y values for each LED
val ledDataMap = mutableMapOf<String, MutableList<Pair<Double, Double>>>()
// Extract LED name, x, and y values from each match and add to the corresponding lists
for (match in matches) {
val ledName = match.groupValues[1]
val xValue = match.groupValues[2].toDouble()
val yValue = match.groupValues[3].toDouble()
// Add x and y values to the corresponding lists based on the LED name
if (!ledDataMap.containsKey(ledName)) {
ledDataMap[ledName] = mutableListOf()
}
if ((ledDataMap[ledName]?.size ?: 0) < 7) {
if(xValue != 0.0){
ledDataMap[ledName]?.add(xValue to yValue)
}
}
// ledDataMap[ledName]?.add(xValue to yValue)
}
// var valuesAdded = 0 // Track the number of values added
//
// for (match in matches) {
// val ledName = match.groupValues[1]
// val xValue = match.groupValues[2].toDouble()
// val yValue = match.groupValues[3].toDouble()
//
// // Add x and y values to the corresponding lists based on the LED name
// if (!ledDataMap.containsKey(ledName)) {
// ledDataMap[ledName] = mutableListOf()
// }
//
// // Check if we have already added one value, then add the next six
// if (valuesAdded > 0 && (ledDataMap[ledName]?.size ?: 0) < 6) {
// ledDataMap[ledName]?.add(xValue to yValue)
// }
//
// // Increase the count of values added
// valuesAdded++
//
// // Break the loop if we have added 6 values
// if (valuesAdded >= 7) {
// break
// }
// }
// String array to store pass or fail messages for each LED
val results = mutableListOf<String>()
// Print the extracted x and y values for each LED
// Regular expression to match LED DAC values
val regex = Regex("LED(\\d) DAC : (\\d+)")
// Find LED DAC values using regex
regex.findAll(resultData).forEach {
val (led, dac) = it.destructured
val dacValue = dac.toDouble()
when (led.toInt()) {
1 -> led1Dac = dacValue
2 -> led2Dac = dacValue
3 -> led3Dac = dacValue
4 -> led4Dac = dacValue
}
}
println("$led1Dac")
println("LED2 DAC: $led2Dac")
println("LED3 DAC: $led3Dac")
println("LED4 DAC: $led4Dac")
for ((ledName, data) in ledDataMap) {
// println("$ledName x-values: ${data.map { it.first }}")
// println("$ledName y-values: ${data.map { it.second }}")
val message = calculateRegressionAndDAC(ledName, data)
results.add(message)
}
// Print the pass or fail messages for each LED
results.forEach {
currentResultData += it
diagnosticsViewModel.messages.postValue(currentResultData)
println(it)
}
}
private fun calculateRegressionAndDAC(ledName: String, data: List<Pair<Double, Double>>): String {
val regression = SimpleRegression()
data.forEach { (x, y) -> regression.addData(x, y) }
val slope = regression.slope
val constant = regression.intercept
val rSquared = regression.rSquare
// Check R-squared value and generate pass or fail message
val message = if (rSquared > 0.98) {
"$ledName linearity PASS (✓)\n"
} else {
"$ledName linearity FAIL (✗)\n"
}
// Calculation for ADC value
val adcValue = when (ledName) {
"LED:1" -> 22000.0
"LED:2"-> 18000.0
"LED:3" -> 18000.0
"LED:4" -> 22000.0
else -> 0.0
}
val ledValue = when (ledName) {
"LED:1" -> led1Dac
"LED:2" -> led2Dac
"LED:3" -> led3Dac
"LED:4" -> led4Dac
else -> 0.0
}
val dacValue = calculateDAC(adcValue, slope, constant)
val resultDAC = dacValue - ledValue!!
if(resultDAC < 200){
currentResultData += "$ledName DAC LEVEL PASS (✓)\n"
println("$ledName DAC LEVEL PASS")
}else{
currentResultData += "$ledName DAC LEVEL FAIL (✗)\n"
println("$ledName DAC LEVEL FAIL")
}
return message
}
private fun calculateDAC(adc: Double, slope: Double, constant: Double): Double {
return (adc - constant) / slope
}
fun parseData(inputData: List<String>): List<Pair<String, String>> { fun parseData(inputData: List<String>): List<Pair<String, String>> {
val pattern = Regex("([A-Z]+)\\s(\\d+)") val pattern = Regex("([A-Z]+)\\s(\\d+)")
val parsedData = mutableListOf<Pair<String, String>>() val parsedData = mutableListOf<Pair<String, String>>()
@@ -286,4 +519,19 @@ class DiagnosticsFragment : Fragment() {
private fun showToast(message: String) { private fun showToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
} }
private fun setProgress(progress: Int) {
binding.progressBarHor.progress = progress
}
private fun incrementProgress() {
val handler = Handler()
handler.postDelayed(object : Runnable {
override fun run() {
if (currentProgress <= targetProgress) {
binding.progressBarHor.progress = currentProgress
currentProgress++
handler.postDelayed(this, delayBetweenIncrements.toLong())
}
}
}, delayBetweenIncrements.toLong())
}
} }

View File

@@ -19,6 +19,7 @@ import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@@ -47,10 +48,12 @@ import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding import `in`.sminnovations.hpostesting.databinding.FragmentHemoCubeReferenceBinding
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.log10 import kotlin.math.log10
import kotlin.random.Random
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
class HemoCubeFragment : Fragment() { class HemoCubeFragment : Fragment() {
private var temperature="" private var temperature=""
private var cuvetteSize = "10mm"
private var checkCuvette = false private var checkCuvette = false
private var checkCuvetteSam = false private var checkCuvetteSam = false
private var sampleClick = false private var sampleClick = false
@@ -87,6 +90,7 @@ class HemoCubeFragment : Fragment() {
private var uploadedToCloud = false private var uploadedToCloud = false
private var uploadedToMolbio = false private var uploadedToMolbio = false
lateinit var testState: TestState lateinit var testState: TestState
var quickCapture:Boolean = false
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
@@ -95,10 +99,11 @@ class HemoCubeFragment : Fragment() {
sharedPreferences = sharedPreferences =
requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE) requireContext().getSharedPreferences("HEMOCUBE", Context.MODE_PRIVATE)
cuvetteSize = sharedPreferences.getString(Constants.CUVETTE_SIZE,"10mm").toString()
testState = TestState( testState = TestState(
testDetails = DataHolder.selectedTest?.toHemoCubeTestData(), testDetails = DataHolder.selectedTest?.toHemoCubeTestData(),
) )
quickCapture = sharedPreferences.getBoolean(Constants.QUICK_CAPTURE, false)
return binding.root return binding.root
} }
@@ -112,15 +117,23 @@ class HemoCubeFragment : Fragment() {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun initViews() { private fun initViews() {
binding.tvSubtitle4.movementMethod = ScrollingMovementMethod()
binding.tvDeviceMessages.movementMethod = ScrollingMovementMethod()
binding.btnSubmit.setOnClickListener { binding.btnSubmit.setOnClickListener {
with(sharedPreferences.edit()) {
putBoolean(Constants.QUICK_CAPTURE, false)
apply()
}
DataHolder.sampleReadCounter++
binding.btnSubmit.isEnabled = false binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = false binding.btnSubmit.isClickable = false
activity?.runOnUiThread { activity?.runOnUiThread {
Log.d("HemoCubeFragment","Test Process completed, result saved")
binding.progressBar.visibility = View.VISIBLE binding.progressBar.visibility = View.VISIBLE
binding.btnSubmit.visibility = View.GONE binding.btnSubmit.visibility = View.GONE
} }
hemoCubeViewModel.uploadHemoCubeResultToDatabase( hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "") isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, ""),quickCapture
) )
} }
@@ -130,25 +143,35 @@ class HemoCubeFragment : Fragment() {
binding.tvTitle.visibility = View.GONE binding.tvTitle.visibility = View.GONE
binding.btnGo.visibility = View.GONE binding.btnGo.visibility = View.GONE
// binding.btnPlacebuffer.visibility = View.GONE // binding.btnPlacebuffer.visibility = View.GONE
val cuvetteSize = sharedPreferences.getString(Constants.CUVETTE_SIZE,"10mm")
binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}" val cuvetteText = "Cuvette Size: $cuvetteSize"
binding.tvName.text = "ID: ${testDetails?._id} \n\n $cuvetteText"
binding.tvSubtitle4.text = "Config" binding.tvSubtitle4.text = "Config"
if (isBufferValueAvailable()){ if (isBufferValueAvailable()){
hemoCubeViewModel.messages.postValue("Ready to test")
binding.btnPlacebuffer.apply { binding.btnPlacebuffer.apply {
setBackgroundColor(Color.GREEN) // Set button background color to green setBackgroundColor(Color.GREEN) // Set button background color to green
text = "Fresh Buffer" // Change button text to "Buffer Exists" text = "Refresh Buffer" // Change button text to "Buffer Exists"
} }
binding.btnSamplestart.isClickable = true
binding.btnSamplestart.isEnabled = true
}else{ }else{
hemoCubeViewModel.messages.postValue("Fresh Kit - Please take Buffer Blank reading")
binding.btnPlacebuffer.apply { binding.btnPlacebuffer.apply {
setBackgroundColor(Color.RED) // Set button background color to green setBackgroundColor(Color.RED) // Set button background color to green
text = "No Buffer" // Change button text to "Buffer Exists" text = "Fresh Buffer" // Change button text to "Buffer Exists"
} }
binding.btnSamplestart.isClickable = false
binding.btnSamplestart.isEnabled = false
} }
binding.btnSamplestart.setOnClickListener { binding.btnSamplestart.setOnClickListener {
activity?.runOnUiThread {
Log.d("HemoCubeFragment","Test Process started, Sample started")
binding.testing.visibility = View.VISIBLE
}
sampleClick = true sampleClick = true
if(checkCuvetteSam){ if(checkCuvetteSam){
activity?.runOnUiThread { activity?.runOnUiThread {
@@ -156,16 +179,20 @@ class HemoCubeFragment : Fragment() {
// binding.tvSubtitle4.text = "Sample Started" // binding.tvSubtitle4.text = "Sample Started"
} }
startSampleProcess() startSampleProcess()
// it.visibility = View.GONE it.visibility = View.GONE
}else{ }else{
checkCuvettePresence() checkCuvettePresence()
} }
} }
binding.btnRetryCheckCuvette.setOnClickListener { binding.btnRetryCheckCuvette.setOnClickListener {
Log.d("HemoCubeFragment","Retry Check Cuvette")
checkCuvettePresence() checkCuvettePresence()
} }
binding.btnPlacebuffer.setOnClickListener { binding.btnPlacebuffer.setOnClickListener {
activity?.runOnUiThread {
Log.d("HemoCubeFragment","Test Process started, Buffer started")
binding.testing.visibility = View.VISIBLE
}
if(checkCuvette){ if(checkCuvette){
startBufferProcess() startBufferProcess()
@@ -463,9 +490,9 @@ class HemoCubeFragment : Fragment() {
fetchResult() fetchResult()
} }
//#EC for v0 and v1 and #RC for v2 //#EC for v0 and v1 and #RC for v2
(resultData.contains("#RC") && this.testStatusCode < TestStatus.EPROM_ADC_RETRIEVAL_COMPLETED.code) -> { (resultData.contains("#EC") && this.testStatusCode < TestStatus.EPROM_ADC_RETRIEVAL_COMPLETED.code) -> {
this.testStatusCode = TestStatus.EPROM_ADC_RETRIEVAL_COMPLETED.code this.testStatusCode = TestStatus.EPROM_ADC_RETRIEVAL_COMPLETED.code
hemoCubeViewModel.messages.postValue("Ready to test")//EPROM ADC Loaded //EPROM ADC Loaded
//checkCuvettePresence() //checkCuvettePresence()
activity?.runOnUiThread { activity?.runOnUiThread {
binding.btnPlacebuffer.visibility = View.VISIBLE binding.btnPlacebuffer.visibility = View.VISIBLE
@@ -476,13 +503,14 @@ class HemoCubeFragment : Fragment() {
(resultData.contains("#AC") && this.testStatusCode < TestStatus.TEMPERATURE_CHECK.code) -> { (resultData.contains("#AC") && this.testStatusCode < TestStatus.TEMPERATURE_CHECK.code) -> {
this.testStatusCode = TestStatus.TEMPERATURE_CHECK.code this.testStatusCode = TestStatus.TEMPERATURE_CHECK.code
temperature = resultData.substringAfter("#AS").substringBefore("#AC") temperature = resultData.substringAfter("#AS").substringBefore("#AC")
hemoCubeViewModel.messages.postValue("Ready to test \n Temperature : $temperature") //hemoCubeViewModel.messages.postValue("Ready to test \n Temperature : $temperature")
} }
resultData.contains("#CIN") && sampleClick && this.testStatusCode < TestStatus.CUVETTE_PRESENTS.code -> { resultData.contains("#CIN") && sampleClick && this.testStatusCode < TestStatus.CUVETTE_PRESENTS.code -> {
hemoCubeViewModel.messages.postValue(getString(R.string.cuvette_present)) hemoCubeViewModel.messages.postValue(getString(R.string.cuvette_present))
this.testStatusCode = TestStatus.CUVETTE_PRESENTS.code this.testStatusCode = TestStatus.CUVETTE_PRESENTS.code
activity?.runOnUiThread { activity?.runOnUiThread {
checkCuvetteSam = true checkCuvetteSam = true
binding.testing.visibility = View.GONE
binding.btnRetryCheckCuvette.visibility = View.GONE binding.btnRetryCheckCuvette.visibility = View.GONE
binding.btnPlacebuffer.visibility = View.GONE binding.btnPlacebuffer.visibility = View.GONE
binding.btnSamplestart.visibility = View.VISIBLE binding.btnSamplestart.visibility = View.VISIBLE
@@ -491,6 +519,9 @@ class HemoCubeFragment : Fragment() {
resultData.contains("#AIN") && sampleClick && this.testStatusCode <= TestStatus.CUVETTE_ABSENTS.code -> { resultData.contains("#AIN") && sampleClick && this.testStatusCode <= TestStatus.CUVETTE_ABSENTS.code -> {
hemoCubeViewModel.messages.postValue(getString(R.string.cuvette_absent)) hemoCubeViewModel.messages.postValue(getString(R.string.cuvette_absent))
this.testStatusCode = TestStatus.CUVETTE_ABSENTS.code this.testStatusCode = TestStatus.CUVETTE_ABSENTS.code
activity?.runOnUiThread {
binding.testing.visibility = View.GONE
}
showRetryButtonForCuvette() showRetryButtonForCuvette()
} }
@@ -499,6 +530,7 @@ class HemoCubeFragment : Fragment() {
this.testStatusCode = TestStatus.CUVETTE_PRESENT.code this.testStatusCode = TestStatus.CUVETTE_PRESENT.code
activity?.runOnUiThread { activity?.runOnUiThread {
checkCuvette = true checkCuvette = true
binding.testing.visibility = View.GONE
binding.btnRetryCheckCuvette.visibility = View.GONE binding.btnRetryCheckCuvette.visibility = View.GONE
binding.btnPlacebuffer.visibility = View.VISIBLE binding.btnPlacebuffer.visibility = View.VISIBLE
binding.btnSamplestart.visibility = View.VISIBLE binding.btnSamplestart.visibility = View.VISIBLE
@@ -507,6 +539,9 @@ class HemoCubeFragment : Fragment() {
resultData.contains("#AIN") && this.testStatusCode <= TestStatus.CUVETTE_ABSENT.code -> { resultData.contains("#AIN") && this.testStatusCode <= TestStatus.CUVETTE_ABSENT.code -> {
hemoCubeViewModel.messages.postValue(getString(R.string.cuvette_absent)) hemoCubeViewModel.messages.postValue(getString(R.string.cuvette_absent))
this.testStatusCode = TestStatus.CUVETTE_ABSENT.code this.testStatusCode = TestStatus.CUVETTE_ABSENT.code
activity?.runOnUiThread {
binding.testing.visibility = View.GONE
}
showRetryButtonForCuvette() showRetryButtonForCuvette()
} }
resultData.contains("#BS") && this.testStatusCode < TestStatus.BUFFER_STARTED.code -> { resultData.contains("#BS") && this.testStatusCode < TestStatus.BUFFER_STARTED.code -> {
@@ -522,17 +557,53 @@ class HemoCubeFragment : Fragment() {
resultData.contains("#BC") && this.testStatusCode < TestStatus.BUFFER_COMPLETED.code -> { resultData.contains("#BC") && this.testStatusCode < TestStatus.BUFFER_COMPLETED.code -> {
activity?.runOnUiThread { activity?.runOnUiThread {
resultData = "" resultData = ""
// resultData.replace("#AIN","#BAIN",false) if(Constants.FLAGS_ENABLED){
Log.d("resultDataBC",resultData) fetchResult()
binding.tvSubtitle4.text = getString(R.string.buffer_completed) }else{
Log.d("resultDataBC",resultData)
activity?.runOnUiThread {
binding.testing.visibility = View.GONE
binding.tvSubtitle4.text = getString(R.string.buffer_completed)
// binding.btnSamplestart.visibility = View.VISIBLE // binding.btnSamplestart.visibility = View.VISIBLE
binding.btnPlacebuffer.visibility = View.GONE binding.btnPlacebuffer.visibility = View.GONE
binding.btnSamplestart.isClickable = true binding.btnSamplestart.visibility = View.VISIBLE
binding.btnSamplestart.isEnabled = true binding.btnSamplestart.isClickable = true
binding.btnSamplestart.isEnabled = true
}
}
// resultData.replace("#AIN","#BAIN",false)
} }
this.testStatusCode = TestStatus.BUFFER_COMPLETED.code this.testStatusCode = TestStatus.BUFFER_COMPLETED.code
} }
resultData.contains("REND") && this.testStatusCode < TestStatus.BUFFER_PRINT_COMPLETED.code -> {
resultData = resultData.replace("REND","Buffer print complete"+ generateTwoDigitRandomNumber())
hemoCubeViewModel.deviceMessages.postValue(resultData)
if(handleBufferCompleted()){
this.testStatusCode = TestStatus.TEMPERATURE_CHECK.code
activity?.runOnUiThread {
checkCuvette = false
binding.testing.visibility = View.GONE
binding.btnRetryCheckCuvette.visibility = View.GONE
binding.btnPlacebuffer.visibility = View.VISIBLE
binding.btnSamplestart.visibility = View.VISIBLE
binding.btnSamplestart.isClickable = false
binding.btnSamplestart.isEnabled = false
}
}else{
this.testStatusCode = TestStatus.BUFFER_PRINT_COMPLETED.code
Log.d("resultDataBC",resultData)
activity?.runOnUiThread {
binding.testing.visibility = View.GONE
binding.tvSubtitle4.text = getString(R.string.buffer_completed)
// binding.btnSamplestart.visibility = View.VISIBLE
binding.btnPlacebuffer.visibility = View.GONE
binding.btnSamplestart.visibility = View.VISIBLE
binding.btnSamplestart.isClickable = true
binding.btnSamplestart.isEnabled = true
}
}
}
(resultData.contains("#SS") || resultData.contains("#SS1")) && this.testStatusCode < TestStatus.SAMPLE_STARTED.code -> { (resultData.contains("#SS") || resultData.contains("#SS1")) && this.testStatusCode < TestStatus.SAMPLE_STARTED.code -> {
this.testStatusCode = TestStatus.SAMPLE_STARTED.code this.testStatusCode = TestStatus.SAMPLE_STARTED.code
@@ -546,6 +617,7 @@ class HemoCubeFragment : Fragment() {
(resultData.contains("#SC") || resultData.contains("#SC1")) && this.testStatusCode < TestStatus.SAMPLE_COMPLETED.code -> { (resultData.contains("#SC") || resultData.contains("#SC1")) && this.testStatusCode < TestStatus.SAMPLE_COMPLETED.code -> {
this.testStatusCode = TestStatus.SAMPLE_COMPLETED.code this.testStatusCode = TestStatus.SAMPLE_COMPLETED.code
activity?.runOnUiThread { activity?.runOnUiThread {
binding.testing.visibility = View.GONE
binding.btnSamplestart.visibility = View.GONE binding.btnSamplestart.visibility = View.GONE
} }
hemoCubeViewModel.messages.postValue( hemoCubeViewModel.messages.postValue(
@@ -556,6 +628,9 @@ class HemoCubeFragment : Fragment() {
} }
resultData.contains("ovf") -> { resultData.contains("ovf") -> {
activity?.runOnUiThread {
binding.testing.visibility = View.GONE
}
hemoCubeViewModel.messages.postValue( hemoCubeViewModel.messages.postValue(
getString(R.string.power_bank) getString(R.string.power_bank)
) )
@@ -608,6 +683,8 @@ class HemoCubeFragment : Fragment() {
} }
resultData.contains("REND") && this.testStatusCode < TestStatus.SAMPLE_PRINT_COMPLETED.code -> { resultData.contains("REND") && this.testStatusCode < TestStatus.SAMPLE_PRINT_COMPLETED.code -> {
resultData = resultData.replace("REND","Sample print complete"+ generateTwoDigitRandomNumber())
hemoCubeViewModel.deviceMessages.postValue(resultData)
handleSampleCompleted() handleSampleCompleted()
} }
@@ -704,6 +781,34 @@ class HemoCubeFragment : Fragment() {
} }
} }
private fun handleBufferCompleted(): Boolean {
val lb1Regex = Regex("""LB1 (\d+\.\d+)""")
val lb2Regex = Regex("""LB2 (\d+\.\d+)""")
val lb1Match = lb1Regex.find(resultData)
val lb2Match = lb2Regex.find(resultData)
val lb1Value = lb1Match!!.groupValues[1].toFloat()
val lb2Value = lb2Match!!.groupValues[1].toFloat()
val led1Min = 21000.00
val led1Max = 23000.00
val led2Min = 17000.00
val led2Max = 19000.00
val isLb1InRange = lb1Value in led1Min..led1Max
val isLb2InRange = lb2Value in led2Min..led2Max
if(!isLb1InRange || !isLb2InRange){
hemoCubeViewModel.messages.postValue("Buffer Reading Out of Range - Please Take Buffer/Blank Reading. If problem persists, Calibrate device")
return true
}
Log.d("HemoCube", "LB1 ($lb1Value) is in range LED1 ($led1Min-$led1Max): $isLb1InRange")
Log.d("HemoCube", "LB2 ($lb2Value) is in range LED2 ($led2Min-$led2Max): $isLb2InRange")
return false
}
private fun showRetryButtonForCuvette() { private fun showRetryButtonForCuvette() {
activity?.runOnUiThread { activity?.runOnUiThread {
// binding.btnPlacebuffer.visibility = View.GONE // binding.btnPlacebuffer.visibility = View.GONE
@@ -727,7 +832,7 @@ class HemoCubeFragment : Fragment() {
} }
} else { } else {
hemoCubeViewModel.uploadHemoCubeResultToDatabase( hemoCubeViewModel.uploadHemoCubeResultToDatabase(
isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, "") isOnline, true, sharedPreferences.getString(Constants.KIT_NUMBER, ""),false
) )
} }
} }
@@ -771,12 +876,7 @@ class HemoCubeFragment : Fragment() {
led4SampleForDevice = led4SampleForDevice =
resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!! resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
processResult() processResult()
if (Constants.PQ_MODE) {
finishReading()
} else {
sendFirstGainCommand()
}
currentResultData = ""
} }
fun processV1HardwareId(resultData: String) { fun processV1HardwareId(resultData: String) {
@@ -871,11 +971,12 @@ class HemoCubeFragment : Fragment() {
} }
} }
fun handleBackButtonPress() { fun handleBackButtonPress(): Boolean {
if (isTestOngoing) { return if (isTestOngoing) {
showToast(R.string.test_go_noback) showToast(R.string.test_go_noback)
true // Indicate that the back press was handled
} else { } else {
activity?.onBackPressed() false // Indicate that the back press was not handled
} }
} }
@@ -888,7 +989,7 @@ class HemoCubeFragment : Fragment() {
requireActivity().packageName, 0 requireActivity().packageName, 0
) )
val version = pInfo.versionName val version = pInfo.versionName
//absorbance
val led1Average = log10(led1BufferForDevice.div(led1SampleForDevice)) val led1Average = log10(led1BufferForDevice.div(led1SampleForDevice))
val led2Average = log10(led2BufferForDevice.div(led2SampleForDevice)) val led2Average = log10(led2BufferForDevice.div(led2SampleForDevice))
val led3Average = log10(led3BufferForDevice.div(led3SampleForDevice)) val led3Average = log10(led3BufferForDevice.div(led3SampleForDevice))
@@ -897,6 +998,60 @@ class HemoCubeFragment : Fragment() {
val deviceRatio = led2Average / led1Average val deviceRatio = led2Average / led1Average
val borderlineMetric = (led1Average - led2Average) / deviceRatio val borderlineMetric = (led1Average - led2Average) / deviceRatio
if(Constants.ABS_FLAGS_ENABLED){
val inRange2mmLed1: Boolean
val inRange2mmLed2: Boolean
val inRange10mmLed1: Boolean
val inRange10mmLed2: Boolean
val min2mmLed1 = getDoubleFromPreferences(Constants.ABS2LED1MMLL, Constants.min2mmLed1)
val max2mmLed1 = getDoubleFromPreferences(Constants.ABS2LED1MMUL, Constants.max2mmLed1)
val min2mmLed2 = getDoubleFromPreferences(Constants.ABS2LED2MMLL, Constants.min2mmLed2)
val max2mmLed2 = getDoubleFromPreferences(Constants.ABS2LED2MMUL, Constants.max2mmLed2)
val min10mmLed1 = getDoubleFromPreferences(Constants.ABS10LED1MMLL, Constants.min10mmLed1)
val max10mmLed1 = getDoubleFromPreferences(Constants.ABS10LED1MMUL, Constants.max10mmLed1)
val min10mmLed2 = getDoubleFromPreferences(Constants.ABS10LED2MMLL, Constants.min10mmLed2)
val max10mmLed2 = getDoubleFromPreferences(Constants.ABS10LED2MMUL, Constants.max10mmLed2)
if(led1Average < 0 || led2Average < 0){
hemoCubeViewModel.messages.postValue("Negative Absorbance - Repeat test with reading Buffer first and sample second")
this.testStatusCode = TestStatus.BUFFER_PRINT_COMPLETED.code
binding.testing.visibility = View.GONE
binding.btnPlacebuffer.visibility = View.GONE
binding.btnSamplestart.visibility = View.VISIBLE
binding.btnSamplestart.isClickable = true
binding.btnSamplestart.isEnabled = true
return
}else{
if(cuvetteSize == "10mm"){
inRange10mmLed1 = led1Average in min10mmLed1..max10mmLed1
inRange10mmLed2 = led2Average in min10mmLed2..max10mmLed2
if(!inRange10mmLed1 || !inRange10mmLed2){
hemoCubeViewModel.messages.postValue("Absorbance out-of-Range - Repeat test with adequate blood volume and Incubation time")
this.testStatusCode = TestStatus.BUFFER_PRINT_COMPLETED.code
binding.testing.visibility = View.GONE
binding.btnPlacebuffer.visibility = View.GONE
binding.btnSamplestart.visibility = View.VISIBLE
binding.btnSamplestart.isClickable = true
binding.btnSamplestart.isEnabled = true
return
}
}else if(cuvetteSize == "2mm"){
inRange2mmLed1 = led1Average in min2mmLed1..max2mmLed1
inRange2mmLed2 = led2Average in min2mmLed2..max2mmLed2
if(!inRange2mmLed1 || !inRange2mmLed2){
hemoCubeViewModel.messages.postValue("Absorbance out-of-Range - Repeat test with adequate blood volume and Incubation time")
this.testStatusCode = TestStatus.BUFFER_PRINT_COMPLETED.code
binding.testing.visibility = View.GONE
binding.btnPlacebuffer.visibility = View.GONE
binding.btnSamplestart.visibility = View.VISIBLE
binding.btnSamplestart.isClickable = true
binding.btnSamplestart.isEnabled = true
return
}
}
}
}
if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0) if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0)
?.get(0)!! ?.get(0)!!
@@ -1020,6 +1175,7 @@ class HemoCubeFragment : Fragment() {
led4Buffer = led4BufferForDevice led4Buffer = led4BufferForDevice
appVersion = version appVersion = version
labName = sharedPreferences.getString(Constants.LABNAME,"") labName = sharedPreferences.getString(Constants.LABNAME,"")
cuvetteSize = sharedPreferences.getString(Constants.CUVETTE_SIZE,"")
this.led1Sample = led1SampleForDevice this.led1Sample = led1SampleForDevice
this.led2Sample = led2SampleForDevice this.led2Sample = led2SampleForDevice
this.led3Sample = led3SampleForDevice this.led3Sample = led3SampleForDevice
@@ -1049,6 +1205,7 @@ class HemoCubeFragment : Fragment() {
deviceRatioClass, deviceRatioClass,
borderlineMetric borderlineMetric
) )
Log.d("HemoCubeFragment",this.classificationResult)
hemoCubeViewModel.messages.postValue( hemoCubeViewModel.messages.postValue(
"${this.classificationResult} \n Device Ratio: ${ "${this.classificationResult} \n Device Ratio: ${
"%.3f".format( "%.3f".format(
@@ -1087,6 +1244,13 @@ class HemoCubeFragment : Fragment() {
).show() ).show()
Firebase.crashlytics.recordException(e) Firebase.crashlytics.recordException(e)
} }
if (Constants.PQ_MODE) {
finishReading()
} else {
sendFirstGainCommand()
}
currentResultData = ""
} }
fun reclassifyWithBorderlineMethod2(deviceRatio: Double?, deviceRatioClass: String?, led2Average: Double?): String { fun reclassifyWithBorderlineMethod2(deviceRatio: Double?, deviceRatioClass: String?, led2Average: Double?): String {
@@ -1120,17 +1284,44 @@ class HemoCubeFragment : Fragment() {
try { try {
// hemoCubeViewModel.messages.postValue("post classification checks") // hemoCubeViewModel.messages.postValue("post classification checks")
if (deviceRatio != null && borderlineMetric != null) { if (deviceRatio != null && borderlineMetric != null) {
if (deviceRatioClass == "Negative Borderline") { if(cuvetteSize == "10mm"){
return if (borderlineMetric >= 2.4) if (deviceRatioClass == "Negative Borderline") {
"Borderline. Normal" if (borderlineMetric < Constants.negativeBoderLine10mm1){//1.34
else return "Sickle Cell Trait"
"Borderline. Sickle Cell Trait" }else if(borderlineMetric > Constants.negativeBoderLine10mm2){
} return "Normal"
if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") { }else if(borderlineMetric > Constants.negativeBoderLine10mm1 && borderlineMetric < Constants.negativeBoderLine10mm2){
return if (borderlineMetric >= 1.4)//1.34 return "Negative borderline. Confirm with HPLC"
"Borderline. Sickle Cell Trait" }
else }
"Borderline. Sickle Cell Disease" if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") {
if (borderlineMetric < Constants.positiveBoderLine10mm1){//1.34
return "Sickle Cell Disease"
}else if(borderlineMetric > Constants.positiveBoderLine10mm2){
return "Sickle Cell Trait"
}else if(borderlineMetric > Constants.positiveBoderLine10mm1 && borderlineMetric < Constants.positiveBoderLine10mm2){
return "Positive for Sickle Cell. Confirm with HPLC"
}
}
}else if(cuvetteSize == "2mm"){
if (deviceRatioClass == "Negative Borderline") {
if (borderlineMetric < Constants.negativeBoderLine2mm1){//1.34
return "Sickle Cell Trait"
}else if(borderlineMetric > Constants.negativeBoderLine2mm2){
return "Normal"
}else if(borderlineMetric > Constants.negativeBoderLine2mm1 && borderlineMetric < Constants.negativeBoderLine2mm2){
return "Negative borderline. Confirm with HPLC"
}
}
if (deviceRatioClass == "Positive for Sickle Cell. HPLC for Confirmation") {
if (borderlineMetric < Constants.positiveBoderLine2mm1){//1.34
return "Sickle Cell Disease"
}else if(borderlineMetric > Constants.positiveBoderLine2mm2){
return "Sickle Cell Trait"
}else if(borderlineMetric > Constants.positiveBoderLine2mm1 && borderlineMetric < Constants.positiveBoderLine2mm2){
return "Positive for Sickle Cell. Confirm with HPLC"
}
}
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
@@ -1169,18 +1360,42 @@ class HemoCubeFragment : Fragment() {
fun deviceRatioClassification(ratio: Double?): String { fun deviceRatioClassification(ratio: Double?): String {
try { try {
if (ratio != null) { if (ratio != null) {
if (ratio in 0.11..0.23) { if(cuvetteSize == "10mm"){
if (ratio in Constants.normalMin10mm..Constants.normalMax10mm) {
// setSubtitleTextColor(R.color.green_2) // setSubtitleTextColor(R.color.green_2)
return "Normal" return "Normal"
}
if (ratio in Constants.negativeBorderlineMin10mm..Constants.negativeBorderlineMax10mm){
return "Negative Borderline"
}
if (ratio in Constants.sickleCellTraitMin10mm..Constants.sickleCellTraitMax10mm){
return "Sickle Cell Trait"
}
if (ratio in Constants.positiveForSickleCellMin10mm..Constants.positiveForSickleCellMax10mm){//0.36
return "Positive for Sickle Cell. HPLC for Confirmation"
}
if (ratio in Constants.sickleCellDiseaseMin10mm..Constants.sickleCellDiseaseMax10mm){
return "Sickle Cell Disease"
}
}else if(cuvetteSize == "2mm"){
if (ratio in Constants.normalMin2mm..Constants.normalMax2mm) {
// setSubtitleTextColor(R.color.green_2)
return "Normal"
}
if (ratio in Constants.negativeBorderlineMin2mm..Constants.negativeBorderlineMax2mm){
return "Negative Borderline"
}
if (ratio in Constants.sickleCellTraitMin2mm..Constants.sickleCellTraitMax2mm){
return "Sickle Cell Trait"
}
if (ratio in Constants.positiveForSickleCellMin2mm..Constants.positiveForSickleCellMax2mm){//0.36
return "Positive for Sickle Cell. HPLC for Confirmation"
}
if (ratio in Constants.sickleCellDiseaseMin2mm..Constants.sickleCellDiseaseMax2mm){
return "Sickle Cell Disease"
}
} }
if (ratio in 0.23..0.25)
return "Negative Borderline"
if (ratio in 0.25..0.31)
return "Sickle Cell Trait"
if (ratio in 0.31..0.39)//0.36
return "Positive for Sickle Cell. HPLC for Confirmation"
if (ratio in 0.39..1.0)
return "Sickle Cell Disease"
} else { } else {
return "Invalid" return "Invalid"
} }
@@ -1199,6 +1414,7 @@ class HemoCubeFragment : Fragment() {
fun handleException(e: Exception) { fun handleException(e: Exception) {
showToast(R.string.error_classification) showToast(R.string.error_classification)
Log.d("HemoCubeFragment",e.toString())
Firebase.crashlytics.recordException(e) Firebase.crashlytics.recordException(e)
} }
@@ -1393,4 +1609,10 @@ class HemoCubeFragment : Fragment() {
val coefficient2 = currentDeviceData?.coefficients?.get(1) ?: 0.0 val coefficient2 = currentDeviceData?.coefficients?.get(1) ?: 0.0
return coefficient1 * ratio + coefficient2 return coefficient1 * ratio + coefficient2
} }
fun getDoubleFromPreferences(key: String, defaultValue: Double): Double {
return sharedPreferences.getString(key, defaultValue.toString())?.toDouble() ?: defaultValue
}
private fun generateTwoDigitRandomNumber(): Int {
return Random.nextInt(10, 100)
}
} }

View File

@@ -53,6 +53,7 @@ import com.example.hpostesting.domain.LogFileManager
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import okhttp3.Headers
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.asRequestBody
@@ -92,7 +93,8 @@ class HemoCubeViewModel @Inject constructor(
val checkUpdate = MutableLiveData<Result<CheckUpdateResponse>>() val checkUpdate = MutableLiveData<Result<CheckUpdateResponse>>()
val deviceUpdate = MutableLiveData<Result<ResponseBody>>() val deviceUpdate = MutableLiveData<ResponseBody>()
val deviceUpdateheader = MutableLiveData<Headers>()
val downloadcertificate = MutableLiveData<Result<ResponseBody>>() val downloadcertificate = MutableLiveData<Result<ResponseBody>>()
val uploadLogs = MutableLiveData<Result<UploadLogsResponse>?>() val uploadLogs = MutableLiveData<Result<UploadLogsResponse>?>()
@@ -120,7 +122,7 @@ class HemoCubeViewModel @Inject constructor(
} }
fun uploadHemoCubeResultToDatabase( fun uploadHemoCubeResultToDatabase(
isOnline: Boolean, testStatus: Boolean, kitSerial: String?, isOnline: Boolean, testStatus: Boolean, kitSerial: String?,quickCapture:Boolean
) = viewModelScope.launch { ) = viewModelScope.launch {
if (kitSerial != null) { if (kitSerial != null) {
testDetails?.kitSerial = kitSerial testDetails?.kitSerial = kitSerial
@@ -130,9 +132,10 @@ class HemoCubeViewModel @Inject constructor(
try { try {
if (isOnline) { if (isOnline) {
parseData() parseData()
addResultTestToDb() addResultTestToDb(quickCapture)
} else { } else {
parseData() parseData()
addResultTestToDb(quickCapture)
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)
@@ -258,9 +261,10 @@ class HemoCubeViewModel @Inject constructor(
} }
fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest) = viewModelScope.launch { fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest) = viewModelScope.launch {
deviceUpdate.postValue(Result.Loading()) //deviceUpdate.postValue(Result.Loading())
repository.deviceUpdate(deviceUpdateRequest).let { repository.deviceUpdate(deviceUpdateRequest).let {
deviceUpdate.postValue(it) deviceUpdate.postValue(it.body())
deviceUpdateheader.postValue(it.headers())
} }
} }
@@ -414,61 +418,93 @@ class HemoCubeViewModel @Inject constructor(
testDetails?.volume = DataHolder.hemoCubeTestData?.volume testDetails?.volume = DataHolder.hemoCubeTestData?.volume
testDetails?.filter = DataHolder.hemoCubeTestData?.filter testDetails?.filter = DataHolder.hemoCubeTestData?.filter
testDetails?.labName = DataHolder.hemoCubeTestData?.labName testDetails?.labName = DataHolder.hemoCubeTestData?.labName
testDetails?.cuvetteSize = sharedPreference.getString(Constants.CUVETTE_SIZE, "").toString()
testDetails?.centerName = sharedPreference.getString(Constants.CENTER_NAME, "").toString()
testDetails?.district = sharedPreference.getString(Constants.DISTRICT, "").toString()
testDetails?.ipAddress = sharedPreference.getString(Constants.IP_ADDRESS, "").toString()
} }
private fun addResultTestToDb() { private fun addResultTestToDb(quickCapture: Boolean) {
viewModelScope.launch { viewModelScope.launch {
try { try {
testDetails!!.reportUploadTime = SimpleDateFormat( testDetails!!.quickCapture = quickCapture
testDetails.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)
val currentTimeFormatted = SimpleDateFormat(
when (val response = repository.addTestToDatabase(testDetails)) { "yyyy-MM-dd'T'HH:mm:ssZZZZZ",
is Response.Success -> { Locale.getDefault()
val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0) ).format(Calendar.getInstance().time)
with(sharedPreference.edit()) { if(quickCapture){
putInt(Constants.KIT_COUNT, kitCount.plus(1)) when (val response = repository.addQcTestToDatabase(testDetails)) {
apply() 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.updateTest(testDetails)
} }
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
testDetails.localFlag = true
if (Constants.MOLBIO_INTEGRATION) {
// Sanitize testDetails before using it in the API call
val sanitizedTestDetails = sanitizeDoubleValues(testDetails)
// Now, use sanitizedTestDetails for the API call is Response.Error -> {
uploadResult( Log.e("Testdb", "Error uploading data to Firestore: $response")
MolbioV2ResultRequest( fireBaseUpload.postValue("Error")
mutableListOf( hemoCubeDao.updateTest(testDetails)
MolbioV2Result( }
rawData = sanitizedTestDetails,
analysisId = sanitizedTestDetails._id, else -> {}
analysisDate = sanitizedTestDetails.testTime, }
analysisStatus = sanitizedTestDetails.classificationResult, }else{
thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[sanitizedTestDetails.deviceId]?.toString(), when (val response = repository.addTestToDatabase(testDetails)) {
interpretation = sanitizedTestDetails.classificationResult, is Response.Success -> {
testId = sanitizedTestDetails._id, val kitCount = sharedPreference.getInt(Constants.KIT_COUNT, 0)
testTime = sanitizedTestDetails.testTime, with(sharedPreference.edit()) {
collectionTime = sanitizedTestDetails.testTime, putInt(Constants.KIT_COUNT, kitCount.plus(1))
expiryTime = sanitizedTestDetails.testTime, apply()
}
Log.i("Testdb", "Data uploaded to Firestore successfully")
fireBaseUpload.postValue("Success")
testDetails.localFlag = true
if (Constants.MOLBIO_INTEGRATION) {
// Sanitize testDetails before using it in the API call
val sanitizedTestDetails = sanitizeDoubleValues(testDetails)
// Now, use sanitizedTestDetails for the API call
uploadResult(
MolbioV2ResultRequest(
mutableListOf(
MolbioV2Result(
rawData = sanitizedTestDetails,
analysisId = sanitizedTestDetails._id,
analysisDate = currentTimeFormatted,
analysisStatus = sanitizedTestDetails.classificationResult,
thresholds = Constants.BUFFER_INTENSITY_THRESHOLDS[sanitizedTestDetails.deviceId]?.toString(),
interpretation = sanitizedTestDetails.classificationResult,
testId = sanitizedTestDetails._id,
testTime = currentTimeFormatted,
collectionTime = currentTimeFormatted,
expiryTime = currentTimeFormatted,
)
) )
) )
) )
) }
hemoCubeDao.updateTest(testDetails)
} }
hemoCubeDao.updateTest(testDetails)
}
is Response.Error -> { is Response.Error -> {
Log.e("Testdb", "Error uploading data to Firestore: $response") Log.e("Testdb", "Error uploading data to Firestore: $response")
fireBaseUpload.postValue("Error") fireBaseUpload.postValue("Error")
hemoCubeDao.updateTest(testDetails) hemoCubeDao.updateTest(testDetails)
} }
else -> {} else -> {}
}
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("Testdb", "Exception during data upload: ${e.message}") Log.e("Testdb", "Exception during data upload: ${e.message}")
fireBaseUpload.postValue("Error") fireBaseUpload.postValue("Error")
@@ -484,6 +520,7 @@ class HemoCubeViewModel @Inject constructor(
when (repository.addTestToDatabase(userData)) { when (repository.addTestToDatabase(userData)) {
is Response.Success -> { is Response.Success -> {
fireBaseBulkUpload.postValue("Success") fireBaseBulkUpload.postValue("Success")
userData.localFlag = true
updateLocalFlag(userData._id) updateLocalFlag(userData._id)
} }

View File

@@ -70,6 +70,7 @@ open class HemocubeActivity : AppCompatActivity() {
DataHolder.usbConnected.postValue(true) DataHolder.usbConnected.postValue(true)
} }
} else { } else {
Log.d("HemoCubeActivity", "permission denied for device")
onErrorReported("permission denied for device") onErrorReported("permission denied for device")
DataHolder.usbConnected.postValue(true) DataHolder.usbConnected.postValue(true)
} }
@@ -115,10 +116,12 @@ open class HemocubeActivity : AppCompatActivity() {
if (it) { if (it) {
myMenu?.get(0)?.icon = myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24) ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24)
Log.d("HemoCubeActivity", "Device is Connected")
} else { } else {
myMenu?.get(0)?.icon = myMenu?.get(0)?.icon =
ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24) ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
Toast.makeText(this, "Device is Disconnected", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Device is Disconnected", Toast.LENGTH_SHORT).show()
Log.d("HemoCubeActivity", "Device is Disconnected")
} }
} }
} }
@@ -130,8 +133,10 @@ open class HemocubeActivity : AppCompatActivity() {
val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager) val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager)
if (availableDrivers.isEmpty()) { if (availableDrivers.isEmpty()) {
Log.d("HemoCubeActivity", "No Device is Connected")
onErrorReported("No Device is Connected") onErrorReported("No Device is Connected")
} else { } else {
Log.d("HemoCubeActivity", "Device available")
mDriver = availableDrivers[0] mDriver = availableDrivers[0]
mConnection = manager.openDevice(mDriver.device) mConnection = manager.openDevice(mDriver.device)
@@ -191,14 +196,25 @@ open class HemocubeActivity : AppCompatActivity() {
} }
override fun onBackPressed() { // override fun onBackPressed() {
val fragment = supportFragmentManager.findFragmentById(R.id.fghemocube) // val fragment = supportFragmentManager.findFragmentById(R.id.fghemocube)
if (fragment is HemoCubeFragment) { // if (fragment is HemoCubeFragment) {
fragment.handleBackButtonPress() // fragment.handleBackButtonPress()
} else { // } else {
super.onBackPressed() // super.onBackPressed()
// }
// }
override fun onBackPressed() {
val fragment = supportFragmentManager.findFragmentById(R.id.fghemocube)
if (fragment is HemoCubeFragment) {
if (fragment.handleBackButtonPress()) {
// If the fragment handled the back press, return to avoid calling super.onBackPressed
return
} }
} }
// If the fragment did not handle the back press, call the superclass method
super.onBackPressed()
}
fun onErrorReported(msg: String) { fun onErrorReported(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()

View File

@@ -485,7 +485,7 @@ 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 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

View File

@@ -159,12 +159,12 @@ class TrueHemeViewModel @Inject constructor(
} }
} }
fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest) = viewModelScope.launch { // fun deviceUpdate(deviceUpdateRequest: DeviceUpdateRequest) = viewModelScope.launch {
deviceUpdate.postValue(Result.Loading()) // deviceUpdate.postValue(Result.Loading())
repository.deviceUpdate(deviceUpdateRequest).let { // repository.deviceUpdate(deviceUpdateRequest).let {
deviceUpdate.postValue(it) // deviceUpdate.postValue(it)
} // }
} // }
fun startPeriodicCheckUpdate() { fun startPeriodicCheckUpdate() {
val periodicRequest = PeriodicWorkRequestBuilder<CheckUpdateWorker>( val periodicRequest = PeriodicWorkRequestBuilder<CheckUpdateWorker>(

View File

@@ -139,7 +139,7 @@ class NatsManager(datacollector: DashboardActivity) {
if (nc?.status == Connection.Status.CONNECTED) { if (nc?.status == Connection.Status.CONNECTED) {
Log.d("NATSCONNECTION", "NATS is successfully connected.") Log.d("NATSCONNECTION", "NATS is successfully connected.")
nc?.subscribe("device.hpos.${deviceId}.ping") nc?.subscribe("device.hpos.${deviceId}.ping")
// Log.d(TAG, "Nats subscribed with ping-"+d) // Log.d(TAG, "Nats subscribed with ping-"+d)
nc?.publish( nc?.publish(
"server.hpos.${deviceId}.ping", "server.hpos.${deviceId}.ping",
"ALIVE".toByteArray(StandardCharsets.UTF_8) "ALIVE".toByteArray(StandardCharsets.UTF_8)

View File

@@ -0,0 +1,14 @@
package com.example.hpostesting.util
import android.content.Context
object AppInitializer {
fun initialize(context: Context) {
val secureStorage = SecureStorage(context)
if (secureStorage.getPassword() == null || secureStorage.getAdminPassword() == null) {
// Store the shared password securely
secureStorage.storePassword("SMI@12345")
secureStorage.storeAdminPassword("SMI@Admin$")
}
}
}

View File

@@ -0,0 +1,44 @@
package com.example.hpostesting.util
import android.accounts.AbstractAccountAuthenticator
import android.accounts.Account
import android.accounts.AccountAuthenticatorResponse
import android.accounts.NetworkErrorException
import android.content.Context
import android.os.Bundle
class MyAuthenticator(context: Context) : AbstractAccountAuthenticator(context) {
override fun editProperties(response: AccountAuthenticatorResponse?, accountType: String?): Bundle {
throw UnsupportedOperationException()
}
override fun addAccount(response: AccountAuthenticatorResponse?, accountType: String?, authTokenType: String?, requiredFeatures: Array<out String>?, options: Bundle?): Bundle? {
// Add your logic to add an account
return null
}
override fun confirmCredentials(response: AccountAuthenticatorResponse?, account: Account?, options: Bundle?): Bundle? {
// Add your logic to confirm credentials
return null
}
override fun getAuthToken(response: AccountAuthenticatorResponse?, account: Account?, authTokenType: String?, options: Bundle?): Bundle? {
// Add your logic to get an authentication token
return null
}
override fun getAuthTokenLabel(authTokenType: String?): String? {
// Label for the auth token type
return null
}
override fun updateCredentials(response: AccountAuthenticatorResponse?, account: Account?, authTokenType: String?, options: Bundle?): Bundle? {
// Add your logic to update credentials
return null
}
override fun hasFeatures(response: AccountAuthenticatorResponse?, account: Account?, features: Array<out String>?): Bundle? {
// Add your logic to check for specific account features
return null
}
}

View File

@@ -0,0 +1,12 @@
package com.example.hpostesting.util
import android.app.Service
import android.content.Intent
import android.os.IBinder
class MyAuthenticatorService : Service() {
override fun onBind(intent: Intent?): IBinder? {
val authenticator = MyAuthenticator(this)
return authenticator.iBinder
}
}

View File

@@ -0,0 +1,33 @@
package com.example.hpostesting.util
import android.content.Context
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
class SecureStorage(context: Context) {
private val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
private val sharedPreferences = EncryptedSharedPreferences.create(
context,
"secure_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
fun storePassword(password: String) {
sharedPreferences.edit().putString("shared_password", password).apply()
}
fun storeAdminPassword(password: String) {
sharedPreferences.edit().putString("admin_password", password).apply()
}
fun getAdminPassword(): String? {
return sharedPreferences.getString("admin_password", null)
}
fun getPassword(): String? {
return sharedPreferences.getString("shared_password", null)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 828 KiB

View File

@@ -23,18 +23,18 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<!-- <androidx.appcompat.widget.Toolbar--> <androidx.appcompat.widget.Toolbar
<!-- android:id="@+id/my_toolbar"--> android:id="@+id/my_toolbar"
<!-- android:layout_width="match_parent"--> android:layout_width="match_parent"
<!-- android:layout_height="?attr/actionBarSize"--> android:layout_height="?attr/actionBarSize"
<!-- android:background="?attr/colorPrimary"--> android:background="?attr/colorPrimary"
<!-- app:titleTextColor="#FFFFFF"--> app:titleTextColor="#FFFFFF"
<!-- android:elevation="4dp"--> android:elevation="4dp"
<!-- app:menu="@menu/my_menu"--> app:menu="@menu/my_menu"
<!-- android:theme="@style/ToolbarTheme"--> android:theme="@style/ToolbarTheme"
<!-- app:popupTheme="@style/ThemeOverlay.AppCompat.Light"--> app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
<!-- app:layout_constraintStart_toStartOf="parent"--> app:layout_constraintStart_toStartOf="parent"
<!-- app:layout_constraintTop_toTopOf="parent"/>--> app:layout_constraintTop_toTopOf="parent"/>
<FrameLayout <FrameLayout
android:id="@+id/fg_device" android:id="@+id/fg_device"

View File

@@ -17,7 +17,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".presentation.KitScanActivity"> >
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout" android:id="@+id/app_bar_layout"
@@ -128,7 +128,7 @@
android:id="@+id/name_edit_text" android:id="@+id/name_edit_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLength="17" android:maxLength="27"
android:inputType="text" android:inputType="text"
android:hint="@string/serial_number" /> android:hint="@string/serial_number" />

View File

@@ -92,6 +92,7 @@
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
app:cardElevation="8dp" app:cardElevation="8dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/cv_item1" app:layout_constraintBottom_toBottomOf="@+id/cv_item1"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/cv_item1" app:layout_constraintStart_toEndOf="@id/cv_item1"
@@ -178,6 +179,7 @@
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
app:cardElevation="8dp" app:cardElevation="8dp"
android:visibility="gone"
app:layout_constraintTop_toTopOf="@id/cv_item3" app:layout_constraintTop_toTopOf="@id/cv_item3"
app:layout_constraintBottom_toBottomOf="@id/cv_item3" app:layout_constraintBottom_toBottomOf="@id/cv_item3"
app:layout_constraintStart_toEndOf="@id/cv_item3" app:layout_constraintStart_toEndOf="@id/cv_item3"

View File

@@ -0,0 +1,35 @@
<?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="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Reset Password"
android:textStyle="bold"
android:textColor="@color/black"
android:textSize="27sp"
android:layout_marginTop="15dp"/>
<EditText
android:id="@+id/editTextNewPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:layout_marginTop="30dp"
android:textSize="20sp"
android:hint="Enter new password"
android:inputType="textPassword" />
<Button
android:id="@+id/buttonResetPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textColor="@color/white"
android:text="Reset Password" />
</LinearLayout>

View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
~ // Notice: All information contained herein is, and remains
~ // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
~ // if any. The intellectual and technical concepts contained
~ // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
~ // and its suppliers and may be covered by Indian and Foreign Patents,
~ // patents in process, and are protected by trade secret or copyright law.
~ // Dissemination of this information or reproduction of this material
~ // is strictly forbidden unless prior written permission is obtained
~ // from ShanMukha Innovations Pvt. Ltd.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hpostesting.presentation.diagnostics.DiagnosticsFragment">
<TextView
android:id="@+id/tv_subtitle2"
style="@style/title2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:textSize="20sp"
android:textColor="@color/black"
android:textStyle="bold"
android:text="Update values of ABS Limits"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/main_ll"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle2">
<EditText
android:id="@+id/et_2mmled1_ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="2mm Led 1 lower limit"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/et_2mmled1_ul"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:hint="2mm Led 1 upper limit"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/et_2mmled2_ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:hint="2mm Led 2 lower limit"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/et_2mmled2_ul"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:hint="2mm Led 2 upper limit"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/et_10mmled1_ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:hint="10mm Led 1 lower limit"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/et_10mmled1_ul"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:hint="10mm Led 1 upper limit"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/et_10mmled2_ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:hint="10mm Led 2 lower limit"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/et_10mmled2_ul"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:hint="10mm Led 2 upper limit"
android:inputType="numberDecimal" />
</LinearLayout>
<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:gravity="center"
android:text="@string/submit"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/main_ll" />
<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

@@ -12,22 +12,48 @@
~ // from ShanMukha Innovations Pvt. Ltd. ~ // from ShanMukha Innovations Pvt. Ltd.
--> -->
<RelativeLayout <ScrollView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" 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="match_parent"> android:layout_height="match_parent">
<TextView
android:id="@+id/titleText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="Shanmukha Innovations"
android:layout_marginTop="5dp"
android:textSize="21sp"
android:textColor="@color/black"
/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<ImageView
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:src="@drawable/smi_logo"
android:contentDescription="@string/smi" />
<TextView
android:id="@+id/titleText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/smi_desp"
android:layout_marginTop="12dp"
android:layout_marginEnd="12dp"
android:layout_marginStart="12dp"
android:textSize="18sp"
android:textColor="@color/black"
/>
<TextView
android:id="@+id/link_click"
android:clickable="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/learn_more"
android:layout_marginTop="5dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:textSize="18sp"
android:textColor="@color/red"
android:focusable="true" />
</LinearLayout>
</ScrollView>

View File

@@ -38,7 +38,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/auto_dac" android:textSize="22sp"
android:textStyle="bold"
android:text="@string/calibrate_device"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent" app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@@ -63,9 +65,10 @@
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:gravity="center" android:gravity="center"
android:scrollbars="vertical"
android:text="Start" android:text="Start"
android:textColor="@color/black" android:textColor="@color/black"
android:textSize="11sp" android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" /> app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" />
@@ -79,7 +82,7 @@
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:clickable="false" android:clickable="false"
android:gravity="center" android:gravity="center"
android:text="Start Auto DAC" android:text="@string/calibrate_device"
android:textColor="@color/white" android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@@ -93,6 +96,7 @@
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:clickable="false" android:clickable="false"
android:gravity="center" android:gravity="center"
android:visibility="gone"
android:text="Read Current DAC Values" android:text="Read Current DAC Values"
android:textColor="@color/white" android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"

View File

@@ -38,7 +38,7 @@
style="@style/title1_1" style="@style/title1_1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="50dp" android:layout_marginTop="100dp"
android:gravity="center" android:gravity="center"
android:text="Start" android:text="Start"
android:textColor="@color/black" android:textColor="@color/black"

View File

@@ -59,18 +59,28 @@
android:id="@+id/tv_subtitle4" android:id="@+id/tv_subtitle4"
style="@style/title1_1" style="@style/title1_1"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="380dp" android:layout_height="450dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:gravity="center" android:gravity="center"
android:text="Start" android:text="Start"
android:scrollbars="vertical"
android:textColor="@color/red" android:textColor="@color/red"
android:textSize="22sp" android:textSize="22sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" /> app:layout_constraintTop_toBottomOf="@id/tv_subtitle3" />
<ProgressBar
android:id="@+id/progressBarHor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:visibility="gone"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_subtitle4"/>
<Button <Button
android:id="@+id/btn_submit" android:id="@+id/btn_submit"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -79,7 +89,7 @@
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:clickable="false" android:clickable="false"
android:gravity="center" android:gravity="center"
android:text="Start" android:text="@string/start"
android:textColor="@color/white" android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View File

@@ -76,7 +76,7 @@
android:layout_marginHorizontal="16dp" android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:clickable="false" android:clickable="false"
android:text="@string/auto_dac" android:text="@string/calibrate_device"
android:textColor="@color/white" android:textColor="@color/white"
app:cornerRadius="16dp" app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@@ -140,6 +140,32 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_deviceInfo" /> app:layout_constraintTop_toBottomOf="@id/btn_deviceInfo" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_reset_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="@string/reset_password_for_this_device"
android:textColor="@color/white"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_deviceProvision" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_update_values"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="24dp"
android:clickable="false"
android:text="Update values"
android:textColor="@color/white"
app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_deviceProvision" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/btn_firefox" android:id="@+id/btn_firefox"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -152,7 +178,7 @@
app:cornerRadius="16dp" app:cornerRadius="16dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_deviceProvision" /> app:layout_constraintTop_toBottomOf="@id/btn_reset_password" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/btn_files" android:id="@+id/btn_files"

View File

@@ -16,74 +16,62 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.hpostesting.presentation.hemocube.HemoCubeFragment"> 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">
<androidx.constraintlayout.widget.ConstraintLayout <TextView
android:id="@+id/cl_parent" android:id="@+id/tv_title"
android:layout_width="match_parent" style="@style/title1"
android:layout_height="match_parent"> 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 <TextView
android:id="@+id/tv_title" android:id="@+id/tv_subtitle2"
style="@style/title1" style="@style/title2"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/Instructions" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toBottomOf="@id/tv_title" />
<TextView <TextView
android:id="@+id/tv_subtitle2" android:id="@+id/tv_name"
style="@style/title2" style="@style/title2"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:layout_marginTop="16dp" android:gravity="center"
app:layout_constraintEnd_toEndOf="parent" android:padding="12dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginTop="26dp"
app:layout_constraintTop_toBottomOf="@id/tv_title" /> android:textSize="14sp"
android:textFontWeight="700"
android:text="Name: SMI\n ID: 1672282828"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints" />
<!-- <TextView--> <TextView
<!-- android:id="@+id/tv_subtitle3"--> android:id="@+id/tv_subtitle4"
<!-- style="@style/title2"--> style="@style/title1_1"
<!-- android:layout_width="0dp"--> android:layout_width="0dp"
<!-- android:layout_height="wrap_content"--> android:layout_height="wrap_content"
<!-- android:layout_marginHorizontal="24dp"--> android:layout_marginHorizontal="24dp"
<!-- android:layout_marginTop="16dp"--> android:layout_marginTop="72dp"
<!-- android:text="@string/step5"--> android:gravity="center"
<!-- app:layout_constraintEnd_toEndOf="parent"--> android:textColor="@color/red"
<!-- app:layout_constraintStart_toStartOf="parent"--> android:textSize="16sp"
<!-- app:layout_constraintTop_toBottomOf="@id/tv_subtitle2" />--> app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
<TextView app:layout_constraintTop_toBottomOf="@id/et_abha_id" />
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="wrap_content"
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--> <!-- <Button-->
@@ -246,8 +234,10 @@
android:gravity="center" android:gravity="center"
android:text="no device message" android:text="no device message"
android:textColor="@color/black" android:textColor="@color/black"
android:scrollbars="vertical"
android:textSize="11sp" android:textSize="11sp"
android:visibility="visible" android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_btns" /> app:layout_constraintTop_toBottomOf="@id/ll_btns" />
@@ -265,14 +255,25 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/error_message" /> app:layout_constraintTop_toBottomOf="@id/error_message" />
<ImageView <pl.droidsonroids.gif.GifImageView
android:id="@+id/testing"
android:visibility="gone"
android:layout_width="180dp"
android:layout_height="150dp"
android:layout_marginTop="10dp"
android:importantForAccessibility="no"
android:src="@drawable/virtual_lab"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_device_messages" />
<pl.droidsonroids.gif.GifImageView
android:id="@+id/iv_check" android:id="@+id/iv_check"
android:visibility="gone" android:visibility="gone"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="100dp" android:layout_height="100dp"
android:layout_marginTop="40dp" android:layout_marginTop="40dp"
android:importantForAccessibility="no" android:importantForAccessibility="no"
android:src="@drawable/check" android:src="@drawable/verified"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_device_messages" /> app:layout_constraintTop_toBottomOf="@id/tv_device_messages" />

View File

@@ -48,16 +48,25 @@
android:id="@+id/internetNotAvailableCL" android:id="@+id/internetNotAvailableCL"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:visibility="gone" android:visibility="visible"
android:padding="24dp"> android:padding="20dp">
<ImageView
android:id="@+id/internetIcon"
android:layout_width="33dp"
android:layout_height="33dp"
android:layout_marginEnd="10dp"
android:src="@drawable/off"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
<ImageView <ImageView
android:id="@+id/btnLogout1" android:id="@+id/btnLogout1"
android:layout_width="30dp" android:layout_width="33dp"
android:layout_height="30dp" android:layout_height="33dp"
android:layout_marginEnd="10dp" android:layout_marginEnd="10dp"
android:src="@drawable/baseline_logout_24" android:src="@drawable/baseline_logout_24"
app:layout_constraintTop_toTopOf="@+id/internetNotAvailableCL" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
/> />
@@ -67,11 +76,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:layout_marginTop="24dp" android:layout_marginTop="8dp"
android:text="@string/internet_not_available_please_enter_the_user_id_manually" android:text="@string/internet_not_available_please_enter_the_user_id_manually"
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_toBottomOf="@+id/btnLogout1"/>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_name" android:id="@+id/til_name"
@@ -90,7 +99,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLength="18" android:maxLength="18"
android:inputType="textCapCharacters" android:inputType="textCapCharacters"
android:hint="@string/user_id" /> android:hint="@string/sample_id" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@@ -119,7 +128,11 @@
android:id="@+id/btn_submit" android:id="@+id/btn_submit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="24dp" android:layout_marginStart="54dp"
android:layout_marginEnd="54dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="10dp"
android:textColor="@color/white"
android:text="@string/submit" android:text="@string/submit"
app:cornerRadius="100dp" app:cornerRadius="100dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@@ -147,164 +160,16 @@
<!-- android:visibility="gone"--> <!-- android:visibility="gone"-->
<!-- app:layout_constraintBottom_toBottomOf="@+id/rv_order_offline"--> <!-- app:layout_constraintBottom_toBottomOf="@+id/rv_order_offline"-->
<!-- app:layout_constraintStart_toStartOf="parent" />--> <!-- app:layout_constraintStart_toStartOf="parent" />-->
<TextView
android:id="@+id/label1"
style="@style/title1_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/new_kit"
app:layout_constraintBottom_toTopOf="@+id/btnNewKitoffline"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnNewKitoffline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:backgroundTint="@color/primary"
android:contentDescription="@string/new_kit"
android:src="@drawable/ic_add"
app:elevation="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/internetAvailableCL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
android:padding="24dp">
<TextView
android:id="@+id/tv_title"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/user_list"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/uploadData"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/upload_data"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/tv_title" />
<ImageView
android:id="@+id/btnLogout"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="10dp"
android:src="@drawable/baseline_logout_24"
app:layout_constraintBottom_toBottomOf="@+id/tv_title"
app:layout_constraintEnd_toStartOf="@+id/uploadData"
app:layout_constraintTop_toTopOf="@+id/tv_title" />
<TextView
android:id="@+id/tv_not_available"
style="@style/title1_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="56dp"
android:text="@string/no_patient_records_found_to_test_please_add_one_from_below"
android:textAlignment="center"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<androidx.cardview.widget.CardView
android:id="@+id/cardView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="0dp"
app:layout_constraintTop_toBottomOf="@+id/tv_title"
tools:layout_editor_absoluteX="24dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.SearchView
android:id="@+id/search_product"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/edit_text_background"
android:inputType="text"
app:iconifiedByDefault="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<requestFocus />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="0dp"
android:orientation="horizontal"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView4">
<RadioButton
android:id="@+id/userIdRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/user_id" />
<RadioButton
android:id="@+id/abhaIdRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/abha_id"
app:layout_constraintTop_toBottomOf="@id/userIdRadioButton" />
<RadioButton
android:id="@+id/aadharIdRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/aadhar_id"
app:layout_constraintTop_toBottomOf="@id/abhaIdRadioButton" />
</RadioGroup>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_order"
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/radioGroup"
tools:listitem="@layout/user_item_view"/>
<TextView <TextView
android:id="@+id/labelQuickCapture" android:id="@+id/labelQuickCapture"
style="@style/title1_1" style="@style/title1_1"
android:visibility="gone" android:visibility="gone"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Quick Capture" android:text="@string/quick_capture"
app:layout_constraintBottom_toTopOf="@+id/btnQuickCapture" app:layout_constraintBottom_toTopOf="@+id/btnNewKitoffline"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent"
/>
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnQuickCapture" android:id="@+id/btnQuickCapture"
@@ -316,22 +181,21 @@
android:contentDescription="Capture measurements quickly" android:contentDescription="Capture measurements quickly"
android:src="@drawable/flask" android:src="@drawable/flask"
app:elevation="1dp" app:elevation="1dp"
app:layout_constraintBottom_toTopOf="@+id/label" app:layout_constraintBottom_toTopOf="@+id/labelQuickCapture"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toEndOf="parent" /> />
<TextView <TextView
android:id="@+id/label" android:id="@+id/label1"
style="@style/title1_1" style="@style/title1_1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/new_kit" android:text="@string/new_kit"
app:layout_constraintBottom_toTopOf="@+id/btnNewKit" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btnNewKit" android:id="@+id/btnNewKitoffline"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="8dp" android:layout_margin="8dp"
@@ -339,11 +203,158 @@
android:contentDescription="@string/new_kit" android:contentDescription="@string/new_kit"
android:src="@drawable/ic_add" android:src="@drawable/ic_add"
app:elevation="1dp" app:elevation="1dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toTopOf="@+id/label1"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<!-- <androidx.constraintlayout.widget.ConstraintLayout-->
<!-- android:id="@+id/internetAvailableCL"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:visibility="gone"-->
<!-- android:padding="24dp">-->
<!-- <TextView-->
<!-- android:id="@+id/tv_title"-->
<!-- style="@style/title1"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/user_list"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent" />-->
<!-- <ImageView-->
<!-- android:id="@+id/uploadData"-->
<!-- android:layout_width="50dp"-->
<!-- android:layout_height="50dp"-->
<!-- android:src="@drawable/upload_data"-->
<!-- android:visibility="gone"-->
<!-- app:layout_constraintBottom_toBottomOf="@+id/tv_title"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="@+id/tv_title" />-->
<!-- <ImageView-->
<!-- android:id="@+id/btnLogout"-->
<!-- android:layout_width="30dp"-->
<!-- android:layout_height="30dp"-->
<!-- android:layout_marginEnd="10dp"-->
<!-- android:src="@drawable/baseline_logout_24"-->
<!-- app:layout_constraintBottom_toBottomOf="@+id/tv_title"-->
<!-- app:layout_constraintEnd_toStartOf="@+id/uploadData"-->
<!-- app:layout_constraintTop_toTopOf="@+id/tv_title" />-->
<!-- <TextView-->
<!-- android:id="@+id/tv_not_available"-->
<!-- style="@style/title1_1"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginHorizontal="16dp"-->
<!-- android:layout_marginTop="56dp"-->
<!-- android:text="@string/no_patient_records_found_to_test_please_add_one_from_below"-->
<!-- android:textAlignment="center"-->
<!-- android:visibility="gone"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/tv_title" />-->
<!-- <androidx.cardview.widget.CardView-->
<!-- android:id="@+id/cardView4"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- app:cardElevation="0dp"-->
<!-- app:layout_constraintTop_toBottomOf="@+id/tv_title"-->
<!-- tools:layout_editor_absoluteX="24dp">-->
<!-- <androidx.constraintlayout.widget.ConstraintLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent">-->
<!-- <androidx.appcompat.widget.SearchView-->
<!-- android:id="@+id/search_product"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_margin="10dp"-->
<!-- android:background="@drawable/edit_text_background"-->
<!-- android:inputType="text"-->
<!-- app:iconifiedByDefault="false"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent" />-->
<!-- <requestFocus />-->
<!-- </androidx.constraintlayout.widget.ConstraintLayout>-->
<!-- </androidx.cardview.widget.CardView>-->
<!-- <RadioGroup-->
<!-- android:id="@+id/radioGroup"-->
<!-- android:layout_width="0dp"-->
<!-- android:orientation="horizontal"-->
<!-- android:layout_height="wrap_content"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@+id/cardView4">-->
<!-- <RadioButton-->
<!-- android:id="@+id/userIdRadioButton"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:checked="true"-->
<!-- android:text="@string/user_id" />-->
<!-- <RadioButton-->
<!-- android:id="@+id/abhaIdRadioButton"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/abha_id"-->
<!-- app:layout_constraintTop_toBottomOf="@id/userIdRadioButton" />-->
<!-- <RadioButton-->
<!-- android:id="@+id/aadharIdRadioButton"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/aadhar_id"-->
<!-- app:layout_constraintTop_toBottomOf="@id/abhaIdRadioButton" />-->
<!-- </RadioGroup>-->
<!-- <androidx.recyclerview.widget.RecyclerView-->
<!-- android:id="@+id/rv_order"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp"-->
<!-- app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@+id/radioGroup"-->
<!-- tools:listitem="@layout/user_item_view"/>-->
<!-- <TextView-->
<!-- android:id="@+id/label"-->
<!-- style="@style/title1_1"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="@string/new_kit"-->
<!-- app:layout_constraintBottom_toTopOf="@+id/btnNewKit"-->
<!-- app:layout_constraintEnd_toEndOf="parent" />-->
<!-- <com.google.android.material.floatingactionbutton.FloatingActionButton-->
<!-- android:id="@+id/btnNewKit"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_margin="8dp"-->
<!-- android:backgroundTint="@color/primary"-->
<!-- android:contentDescription="@string/new_kit"-->
<!-- android:src="@drawable/ic_add"-->
<!-- app:elevation="1dp"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent" />-->
<!-- </androidx.constraintlayout.widget.ConstraintLayout>-->
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -60,7 +60,7 @@
app:layout_constraintTop_toBottomOf="@+id/tv_title" /> app:layout_constraintTop_toBottomOf="@+id/tv_title" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/et_aadharID" android:id="@+id/et_login"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -77,7 +77,25 @@
android:inputType="textCapCharacters" android:inputType="textCapCharacters"
android:maxLength="13" /> android:maxLength="13" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_name"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_login">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLength="24"
android:hint="Device user name" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/et_centerName" android:id="@+id/et_centerName"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
@@ -86,7 +104,46 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_aadharID"> app:layout_constraintTop_toBottomOf="@id/til_name">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/centerName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLength="24"
android:hint="Center name"
android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_district"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_centerName">
<AutoCompleteTextView
android:id="@+id/et_district"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/district"
android:inputType="none"
android:text="Mysuru"
android:labelFor="@id/til_district"
app:simpleItems="@array/district" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/et_password"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/til_district">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/password" android:id="@+id/password"
@@ -104,9 +161,10 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/login" android:text="@string/login"
app:cornerRadius="16dp" app:cornerRadius="16dp"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_centerName" /> app:layout_constraintTop_toBottomOf="@+id/et_password" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -55,12 +55,47 @@
app:layout_constraintStart_toEndOf="@id/lab_name" app:layout_constraintStart_toEndOf="@id/lab_name"
app:layout_constraintTop_toTopOf="@id/lab_name" /> app:layout_constraintTop_toTopOf="@id/lab_name" />
<TextView
android:id="@+id/title_cuvette"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/select_cuvette_size"
android:textColor="@color/black"
android:textStyle="bold"
android:textSize="18sp"
app:layout_constraintTop_toBottomOf="@id/lab_name"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="10dp"
android:layout_marginStart="30dp"/>
<Spinner
android:id="@+id/spinnerCuvette"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_centerInParent="true"
app:layout_constraintTop_toBottomOf="@id/title_cuvette"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="8dp"
android:layout_marginStart="30dp"
/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_add_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/add"
app:cornerRadius="16dp"
app:layout_constraintBottom_toBottomOf="@id/spinnerCuvette"
app:layout_constraintStart_toEndOf="@id/spinnerCuvette"
app:layout_constraintTop_toTopOf="@id/spinnerCuvette" />
<FrameLayout <FrameLayout
android:id="@+id/container" android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/lab_name" app:layout_constraintTop_toBottomOf="@+id/spinnerCuvette"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="10dp"/> android:layout_marginTop="10dp"/>

View File

@@ -50,7 +50,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:hint="commands" android:hint="@string/commands"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:textSize="18sp" android:textSize="18sp"

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
~ // Notice: All information contained herein is, and remains
~ // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
~ // if any. The intellectual and technical concepts contained
~ // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
~ // and its suppliers and may be covered by Indian and Foreign Patents,
~ // patents in process, and are protected by trade secret or copyright law.
~ // Dissemination of this information or reproduction of this material
~ // is strictly forbidden unless prior written permission is obtained
~ // from ShanMukha Innovations Pvt. Ltd.
-->
<resources>
<string-array name="district">
<item>Mysuru</item>
<item>Kodagu</item>
<item>Chamarajanagar</item>
<item>Other</item>
</string-array>
</resources>

View File

@@ -38,6 +38,7 @@
</string-array> </string-array>
<string-array name="blood_group"> <string-array name="blood_group">
<item>Unknown</item>
<item>O+ve</item> <item>O+ve</item>
<item>O-ve</item> <item>O-ve</item>
<item>A+ve</item> <item>A+ve</item>
@@ -194,7 +195,7 @@
<string name="set_baseline_reference_again">क्या फिर से आधार लाइन सेट करना है?</string> <string name="set_baseline_reference_again">क्या फिर से आधार लाइन सेट करना है?</string>
<string name="baseline_instruction">आधार निर्देश</string> <string name="baseline_instruction">आधार निर्देश</string>
<string name="to_be_launched_in_next_version_of_the_app">अगले संस्करण में लॉन्च किया जाएगा</string> <string name="to_be_launched_in_next_version_of_the_app">अगले संस्करण में लॉन्च किया जाएगा</string>
<string name="invalid_kit">अमान्य किट सीरियल नंबर, सही उदाहरण, SMI/SC/019/01/001</string> <string name="invalid_kit">अमान्य किट सीरियल नंबर</string>
<string name="user_list">उपयोगकर्ता सूची</string> <string name="user_list">उपयोगकर्ता सूची</string>
<string name="user_id">उपयोगकर्ता आईडी</string> <string name="user_id">उपयोगकर्ता आईडी</string>
<string name="aadhar_id">आधार आईडी</string> <string name="aadhar_id">आधार आईडी</string>
@@ -295,4 +296,13 @@
<string name="lab_name">Lab Name</string> <string name="lab_name">Lab Name</string>
<string name="menu_about">About</string> <string name="menu_about">About</string>
<string name="action_about">About</string> <string name="action_about">About</string>
<string name="smi">SMI</string>
<string name="smi_desp"><b>ShanMukha Innovations</b> is a spin-off from Indian Institute of Science, Bangalore. Incorporated in 2016, the company has been delivering innovative Made in India first of its kind deep technology-based products in healthcare.\\n\\nNotable solutions include Mobile Infection Testing and Reporting Labs (MITR Labs), portable thermal cycler (PolyCube).\\n\\nThe company launched Sicklecert ®, Indias first CDSCO approved indigenous diagnostic test for sickle-cell anemia.\\n\\nOur customers include government, non-profit and private sector companies. Leading research institutes such as IISc, IIT Tirupati have engaged us for unique projects. We take pride in supporting Indian and global customers with world-class products.</string>
<string name="learn_more">Visit to learn more: <u>sminnovations.in</u></string>
<string name="commands">Commands</string>
<string name="select_cuvette_size">Select Cuvette Size</string>
<string name="sample_id">Sample Id</string>
<string name="quick_capture">Quick Capture</string>
<string name="reset_password_for_this_device">Reset password for this device</string>
<string name="calibrate_device">Calibrate the device</string>
</resources> </resources>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ // Copyright (c) 2024 ShanMukha Innovations Pvt. Ltd. All rights reserved.
~ // Notice: All information contained herein is, and remains
~ // the property of ShanMukha Innovations Pvt. Ltd. and its suppliers,
~ // if any. The intellectual and technical concepts contained
~ // herein are proprietary to ShanMukha Innovations Pvt. Ltd.
~ // and its suppliers and may be covered by Indian and Foreign Patents,
~ // patents in process, and are protected by trade secret or copyright law.
~ // Dissemination of this information or reproduction of this material
~ // is strictly forbidden unless prior written permission is obtained
~ // from ShanMukha Innovations Pvt. Ltd.
-->
<resources>
<string-array name="district">
<item>Mysuru</item>
<item>Kodagu</item>
<item>Chamarajanagar</item>
<item>Other</item>
</string-array>
</resources>

View File

@@ -39,6 +39,7 @@
</string-array> </string-array>
<string-array name="blood_group"> <string-array name="blood_group">
<item>Unknown</item>
<item>O+ve</item> <item>O+ve</item>
<item>O-ve</item> <item>O-ve</item>
<item>A+ve</item> <item>A+ve</item>
@@ -92,7 +93,7 @@
<string name="name_error">ಹೆಸರು ಖಾಲಿ ಇರಬಾರದು</string> <string name="name_error">ಹೆಸರು ಖಾಲಿ ಇರಬಾರದು</string>
<string name="age_error">ವಯಸ್ಸು ಖಾಲಿ ಇರಬಾರದು</string> <string name="age_error">ವಯಸ್ಸು ಖಾಲಿ ಇರಬಾರದು</string>
<string name="gender_error">ಲಿಂಗ ಖಾಲಿ ಇರಬಾರದು</string> <string name="gender_error">ಲಿಂಗ ಖಾಲಿ ಇರಬಾರದು</string>
<string name="age_error_out_of_bound">ವಯಸ್ಸು ಯಾವುದೇ ಸಾಧ್ಯವಿಲ್ಲ</string> <string name="age_error_out_of_bound">ವಯಸ್ಸು ಅರ್ಹವಾಗಿಲ್ಲ</string>
<string name="yob_error">ಹುಟ್ಟಿದ ವರ್ಷ ಖಾಲಿ ಇರಬಾರದು</string> <string name="yob_error">ಹುಟ್ಟಿದ ವರ್ಷ ಖಾಲಿ ಇರಬಾರದು</string>
<string name="yob_error_2">ಅಮಾನ್ಯ ಹುಟ್ಟಿದ ವರ್ಷ</string> <string name="yob_error_2">ಅಮಾನ್ಯ ಹುಟ್ಟಿದ ವರ್ಷ</string>
<string name="mobile_error">ಮೊಬೈಲ್ ಸಂಖ್ಯೆ ಖಾಲಿ ಇರಬಾರದು</string> <string name="mobile_error">ಮೊಬೈಲ್ ಸಂಖ್ಯೆ ಖಾಲಿ ಇರಬಾರದು</string>
@@ -110,31 +111,31 @@
<string name="start_now">ಈಗ ಪ್ರಾರಂಭಿಸಿ</string> <string name="start_now">ಈಗ ಪ್ರಾರಂಭಿಸಿ</string>
<string name="hemo_cube">ಹೆಮೋ ಕ್ಯೂಬ್</string> <string name="hemo_cube">ಹೆಮೋ ಕ್ಯೂಬ್</string>
<string name="hb">ಹೆಮೊಗ್ಲೊಬಿನ್</string> <string name="hb">ಹೆಮೊಗ್ಲೊಬಿನ್</string>
<string name="normal">ಸಾಮಾನ್ಯ</string> <string name="normal">ನಾರ್ಮಲ್</string>
<string name="sickle_cell_disease">ಸಿಕಲ್ ಸೆಲ್ ರೋಗ</string> <string name="sickle_cell_disease">ಸಿಕಲ್ ಸೆಲ್ ಡಿಸೀಸ್</string>
<string name="sickle_cell_trait">ಸಿಕಲ್ ಸೆಲ್ ಗುಣ</string> <string name="sickle_cell_trait">ಸಿಕಲ್ ಸೆಲ್ ಟ್ರೈಟ್</string>
<string name="undefined">ಅವ್ಯಾಖ್ಯಾತ\ \ </string> <string name="undefined">ನಿಕೃಷ್ಟವಾಗಿ ಹೇಳದಿರುವ\ \ </string>
<string name="sicklecell_nconfirmatory">ಸಿಕ್ಲ್‌ಸೆಲ್\nದೃಢೀಕರಣ</string> <string name="sicklecell_nconfirmatory">ಕುಡಗೋಲು ಕಣ ರಕ್ತಹೀನತೆ ದೃಢೀಕರಣ</string>
<string name="sicklecell_screening">ಸಿಕ್ಲ್ ಸೆಲ್ ಸ್ಕ್ರೀನಿಂಗ್</string> <string name="sicklecell_screening">ಸಿಕ್ಲ್ ಸೆಲ್ ಸ್ಕ್ರೀನಿಂಗ್</string>
<string name="thalassemia">ಥ್ಯಾಲಸೀಮಿಯಾ</string> <string name="thalassemia">ಥ್ಯಾಲಸೀಮಿಯಾ</string>
<string name="usb_connection">USB ಕನೆಕ್ಷನ್</string> <string name="usb_connection">USB ಕನೆಕ್ಷನ್</string>
<string name="high_performance_optical_spectroscopy">ಹೈ ಪರಫಾರ್ಮೆನ್ಸ್\nಆಪ್ಟಿಕಲ್ ಸ್ಪೆಕ್ಟ್ರೋಸ್ಕಪಿ</string> <string name="high_performance_optical_spectroscopy">ಹೈ ಪರಫಾರ್ಮೆನ್ಸ್ ಆಪ್ಟಿಕಲ್ ಸ್ಪೆಕ್ಟ್ರೋಸ್ಕಪಿ</string>
<string name="sickle_cert">ಸಿಕಲ್ ಸರ್ಟಿಫಿಕೇಟ</string> <string name="sickle_cert">ಸಿಕಲ್ ಸರ್ಟ್</string>
<string name="sickle_find">ಸಿಕಲ್ ಹುಡುಕಿ</string> <string name="sickle_find">ಸಿಕಲ್ ಫೈಂಡ್</string>
<string name="submit">ಸಲ್ಲಿಸಿ</string> <string name="submit">ಸಲ್ಲಿಸಿ</string>
<string name="diagnostics">ಡೆವೈಸ್ ಟೆಸ್ಟ್</string> <string name="diagnostics"> ಡಯಗ್ನೊಸ್ಟಿಕ</string>
<string name="auto_dac">Auto DAC</string> <string name="auto_dac">Auto DAC</string>
<string name="assurance_controls">Quality Controls</string> <string name="assurance_controls">Quality Controls</string>
<string name="calibration">Calibration</string> <string name="calibration">Calibration</string>
<string name="deviceProvision">Device Provision</string> <string name="deviceProvision">ಡಿವೈಸ್ ಪೂರ್ವಸಿದ್ಧತೆ</string>
<string name="place_buffer">ಪ್ರಾರಂಭಿಸಿ</string> <string name="place_buffer">ಬಫರ್ ಪ್ರಾರಂಭಿಸಿ</string>
<string name="Start_Sample">ನಮೂನೆ ಪ್ರಾರಂಭಿಸಿ</string> <string name="Start_Sample">ನಮೂನೆ ಪ್ರಾರಂಭಿಸಿ</string>
<string name="new_kit">ಹೊಸ ಕಿಟ್</string> <string name="new_kit">ಹೊಸ ಕಿಟ್</string>
<string name="new_buffer">ಹೊಸ ಬಫರ್</string> <string name="new_buffer">ಹೊಸ ಬಫರ್</string>
<string name="name_error_2">ಅಮಾನ್ಯ ಅಕ್ಷರ, ಅನುಮತವಾದ ಅಕ್ಷರಗಳು ಅಕ್ಷರಗಳು, ಸಂಖ್ಯೆಗಳು ಮತ್ತು ( ) _ - , . ಮಾತ್ರ</string> <string name="name_error_2">ಅಮಾನ್ಯ ಅಕ್ಷರ, ಅನುಮತವಾದ ಅಕ್ಷರಗಳು ಅಕ್ಷರಗಳು, ಸಂಖ್ಯೆಗಳು ಮತ್ತು ( ) _ - , . ಮಾತ್ರ</string>
<string name="recommended">\*ಫಲಿತಾಂಶವನ್ನು ಪ್ರಯೋಗಶಾಲೆಯ ಪರೀಕ್ಷಾದಿಂದ ದೃಢೀಕರಿಸಬೇಕು</string> <string name="recommended">\*ಫಲಿತಾಂಶವನ್ನು ಪ್ರಯೋಗಶಾಲೆಯ ಪರೀಕ್ಷಾದಿಂದ ದೃಢೀಕರಿಸಬೇಕು</string>
<string name="recommended_age">\*ಫಲಿತಾಂಶವನ್ನು ಪ್ರಯೋಗಶಾಲೆಯ ಪರೀಕ್ಷಾದಿಂದ ದೃಢೀಕರಿಸಬೇಕು ಏಕೆಂದರೆ ರೋಗಿಯ ವಯಸ್ಸು 5 ವರ್ಷಗಳಿಗಿಂತ ಕಡಿಮೆ</string> <string name="recommended_age">\*ಫಲಿತಾಂಶವನ್ನು ಪ್ರಯೋಗಶಾಲೆಯ ಪರೀಕ್ಷಾದಿಂದ ದೃಢೀಕರಿಸಬೇಕು ಏಕೆಂದರೆ ರೋಗಿಯ ವಯಸ್ಸು 5 ವರ್ಷಗಳಿಗಿಂತ ಕಡಿಮೆ</string>
<string name="positive_borderline">ಧನಸ್ಪರ್ಶ</string> <string name="positive_borderline">ಪಾಸಿಟಿವ್ ಬಾರ್ಡರ್‌ಲೈನ್</string>
<string name="negative_borderline">ನೆಗೆಟಿವ್ ಬಾರ್ಡರ್‌ಲೈನ್</string> <string name="negative_borderline">ನೆಗೆಟಿವ್ ಬಾರ್ಡರ್‌ಲೈನ್</string>
<string name="is_patient_under_any_medication">ರೋಗಿ ಯಾವುದೇ ಔಷಧಿ ಅಥವಾ ಚಿಕಿತ್ಸೆಯಲ್ಲಿದ್ದಾನೆಯೇ?</string> <string name="is_patient_under_any_medication">ರೋಗಿ ಯಾವುದೇ ಔಷಧಿ ಅಥವಾ ಚಿಕಿತ್ಸೆಯಲ್ಲಿದ್ದಾನೆಯೇ?</string>
<string name="is_patient_undergoing_any_blood_transfusion">ರೋಗಿಗೆ ರಕ್ತ ಪ್ರವಾಹನೆ ನಡೆಯುತ್ತಿದೆಯೇ?</string> <string name="is_patient_undergoing_any_blood_transfusion">ರೋಗಿಗೆ ರಕ್ತ ಪ್ರವಾಹನೆ ನಡೆಯುತ್ತಿದೆಯೇ?</string>
@@ -181,119 +182,128 @@
<string name="threedots">...</string> <string name="threedots">...</string>
<string name="create_abha_id_card">ABHA ಐಡಿ ಕಾರ್ಡ್ ರಚಿಸಿ</string> <string name="create_abha_id_card">ABHA ಐಡಿ ಕಾರ್ಡ್ ರಚಿಸಿ</string>
<string name="official_abha_app">ಆಧಿಕಾರಿ ABHA ಆಪ್</string> <string name="official_abha_app">ಆಧಿಕಾರಿ ABHA ಆಪ್</string>
<string name="scan_patient_aadhaar_card">ರೋಗಿ ಆಧಾರ್ ಕಾರ್ಡ್ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ</string> <string name="scan_patient_aadhaar_card">ವ್ಯಕ್ತಿಯ ಆಧಾರ್ ಕಾರ್ಡ್ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ</string>
<string name="enter_aadhaar_number_manualy">ಆಧಾರ್ ಸಂಖ್ಯೆಯನ್ನು ಕೈಯಿಂದ ನಮೂದಿಸಿ</string> <string name="enter_aadhaar_number_manualy">ಆಧಾರ್ ಸಂಖ್ಯೆಯನ್ನು ಕೈಯಿಂದ ನಮೂದಿಸಿ</string>
<string name="aadhaar_number">ಆಧಾರ್ ಸಂಖ್ಯೆ</string> <string name="aadhaar_number">ಆಧಾರ್ ಸಂಖ್ಯೆ</string>
<string name="aadhaar_in_tv"><b>ಆಧಾರ್ ಸಂಖ್ಯೆ</b></string> <string name="aadhaar_in_tv"><b>ಆಧಾರ್ ಸಂಖ್ಯೆ</b></string>
<string name="please_use_official_abha_app_to_create_abha_id_and_come_back">ದಯವಿಟ್ಟು "ಆಧಿಕಾರಿ ABHA ಆಪ್" ಅನ್ನು ಬಳಸಿ ABHA ಐಡಿ ರಚಿಸಿ ಮತ್ತ ಹಿಂತಿರುಗಿ ಬನ್ನಿ.</string> <string name="please_use_official_abha_app_to_create_abha_id_and_come_back">ದಯವಿಟ್ಟು ಧಿಕೃತ ABHA ಆಪ್ ಅನ್ನು ಬಳಸಿ ABHA ಐಡಿ ರಚಿಸಿ ಮತ್ತ ಹಿಂತಿರುಗಿ ಬನ್ನಿ.</string>
<string name="please_enter_aadhaar">ಮುಂದುವರಿಸಲು ದಯವಿಟ್ಟು ಆಧಾರ್ ಸಂಖ್ಯೆಯನ್ನು ನಮೂದಿಸಿ</string> <string name="please_enter_aadhaar">ಮುಂದುವರಿಸಲು ದಯವಿಟ್ಟು ಆಧಾರ್ ಸಂಖ್ಯೆಯನ್ನು ನಮೂದಿಸಿ</string>
<string name="scan_qr_code_of_the_kit">ಕಿಟ್‌ನ ಕ್ಯೂಆರ್ ಕೋಡ್ ಅನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಿ</string> <string name="scan_qr_code_of_the_kit">ಕಿಟ್‌ನ ಕ್ಯೂಆರ್ ಕೋಡ್ ಅನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಿ</string>
<string name="enter_kit_serial_number_manually">ಕಿಟ್ ಸೀರಿಯಲ್ ಸಂಖ್ಯೆಯನ್ನು ಕೈಯಿಂದ ನಮೂದಿಸಿ</string> <string name="enter_kit_serial_number_manually">ಕಿಟ್ ಸೀರಿಯಲ್ ಸಂಖ್ಯೆಯನ್ನು ಕೈಯಿಂದ ನಮೂದಿಸಿ</string>
<string name="serial_number">ಸೀರಿಯಲ್ ಸಂಖ್ಯೆ</string> <string name="serial_number">ಸೀರಿಯಲ್ ಸಂಖ್ಯೆ</string>
<string name="set_baseline_reference_again">ಬೇಸ್ಲೈನ್/ಸಂದರ್ಭ ಹೊಂದಿಸಿರಾ?</string> <string name="set_baseline_reference_again">ಬೇಸ್ಲೈನ್ ಉಲ್ಲೇಖವನ್ನು ಮತ್ತೆ ಸೆಟ್ ಮಾಡಿ </string>
<string name="baseline_instruction">ಬೇಸ್ಲೈನ್ ನಿರ್ದೇಶನ</string> <string name="baseline_instruction">ಬೇಸ್ಲೈನ್ ನಿರ್ದೇಶನ</string>
<string name="to_be_launched_in_next_version_of_the_app">ಮುಂದಿನ ಆಪ್ ಆವೃತ್ತಿಯಲ್ಲಿ ಪ್ರಕಟಿಸಲಾಗಿದೆ</string> <string name="to_be_launched_in_next_version_of_the_app">ಮುಂದಿನ ಆಪ್ ಆವೃತ್ತಿಯಲ್ಲಿ ಪ್ರಕಟಿಸಲಾಗಿದೆ</string>
<string name="invalid_kit">ಅಮಾನ್ಯ ಕಿಟ್ ಸೀರಿಯಲ್ ಸಂಖ್ಯೆ, ಶರಿಯಾದ ಉದಾಹರಣೆ, SMI/SC/019/01/001</string> <string name="invalid_kit">ಅಮಾನ್ಯ ಕಿಟ್ ಸೀರಿಯಲ್ ಸಂಖ್ಯೆ</string>
<string name="user_list">ಬಳಕೆದಾರ ಪಟ್ಟಿ</string> <string name="user_list">ಬಳಕೆದಾರ ಪಟ್ಟಿ</string>
<string name="user_id">ಬಳಕೆದಾರ ಐಡಿ</string> <string name="user_id">ಬಳಕೆದಾರ ಐಡಿ</string>
<string name="aadhar_id">ಆಧಾರ್ ಐಡಿ</string> <string name="aadhar_id">ಆಧಾರ್ ಐಡಿ</string>
<string name="internet_not_available_please_enter_the_user_id_manually">ಇಂಟರ್ನೆಟ್ ಇಲ್ಲದೆ, ದಯವಿಟ್ಟು ಬಳಕೆದಾರ ಐಡಿ ಮತ್ತು ರಕ್ತ ಗುಂಪುವನ್ನು ಕೈಯಿಂದ ನಮೂದಿಸಿ</string> <string name="internet_not_available_please_enter_the_user_id_manually">ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ. ದಯವಿಟ್ಟು ಬಳಕೆದಾರ ಐಡಿ ಮತ್ತು ರಕ್ತ ಗುಂಪುವನ್ನು ಕೈಯಿಂದ ನಮೂದಿಸಿ</string>
<string name="user_id_error_message">ಬಳಕೆದಾರ ಐಡಿ 18 ಅಂಕಗಳಿರಬೇಕು ಮತ್ತು ದಯವಿಟ್ಟು ರಕ್ತ ಗುಂಪುವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ</string> <string name="user_id_error_message">ಬಳಕೆದಾರ ಐಡಿ 18 ಅಂಕಗಳಿರಬೇಕು ಮತ್ತು ದಯವಿಟ್ಟು ರಕ್ತ ಗುಂಪುವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ</string>
<string name="upload_db_registration_title">ಸ್ಥಾನಿಕ DB ಪರೀಕ್ಷೆಗಳನ್ನು ಅಪ್ಲೋಡ್ ಮಾಡಿ</string> <string name="upload_db_registration_title">ನೀವು ಸ್ಥಳೀಯ ಡೇಟಾ ಬೇಸ್ ಅನ್ನು ಟೆಸ್ಟ್ ಗಳನ್ನು ಅಪ್ಲೋಡ್ ಮಾಡಿ</string>
<string name="upload_db_registration_message">ನೀವು ಸ್ಥಾನಿಕ DB ಪರೀಕ್ಷೆಗಳನ್ನು ಕ್ಲೌಡ್‌ಗೆ ಅಪ್ಲೋಡ್ ಮಾಡಲು ಬಯಸುತ್ತೀರಾ?</string> <string name="upload_db_registration_message">ನೀವು ಪರೀಕ್ಷೆಗಳನ್ನು ಕ್ಲೌಡ್‌ಗೆ ಅಪ್ಲೋಡ್ ಮಾಡಲು ಬಯಸುತ್ತೀರಾ?</string>
<string name="download_db_registration_title">ಡೌನ್ಲೋಡ್ ಡಿಬಿ ಟೆಸ್ಟ್‌ಗಳು</string> <string name="download_db_registration_title">ಡೌನ್ಲೋಡ್ ಡಿಬಿ ಟೆಸ್ಟ್‌ಗಳು</string>
<string name="download_db_registration_message">ನೀವು ಲೋಕಲ್ ಡಿಬಿ ಟೆಸ್ಟ್ಗಳನ್ನು CSV ಆಕರದಲ್ಲಿ ಡೌನ್ಲೋಡ್ ಮಾಡಲು ಬಯಸುತ್ತೀರಾ?</string> <string name="download_db_registration_message">ನೀವು ಸ್ಥಳೀಯ ಡೇಟಾ ಬೇಸ್ ಅನ್ನು ಟೆಸ್ಟ್ ಗಳನ್ನು ಕ್ಲೌಡ್‌ಗೆ ಅಪ್ಲೋಡ್ ಮಾಡಲು ಬಯಸುತ್ತೀರಾ?</string>
<string name="upload">ಅಪ್ಲೋಡ್ ಮಾಡಿ</string> <string name="upload">ಅಪ್ಲೋಡ್ ಮಾಡಿ</string>
<string name="cancel">ರದ್ದು ಮಾಡಿ</string> <string name="cancel">ರದ್ದು ಮಾಡಿ</string>
<string name="upload_success_message">ಯಶಸ್ವಿಯಾಗಿ ಅಪ್ಲೋಡ್ ಮಾಡಲಾಗಿದೆ</string> <string name="upload_success_message">ಯಶಸ್ವಿಯಾಗಿ ಅಪ್ಲೋಡ್ ಮಾಡಲಾಗಿದೆ</string>
<string name="test_completed">ಪರೀಕ್ಷೆ ಮುಗಿಯಿತು</string> <string name="test_completed">ಪರೀಕ್ಷೆ ಮುಗಿಯಿತು</string>
<string name="select_blood_group">ರಕ್ತ ಗುಂಪು ಆಯ್ಕೆಮಾಡಿ</string> <string name="select_blood_group">ರಕ್ತ ಗುಂಪು ಆಯ್ಕೆಮಾಡಿ</string>
<string name="all_registered_user_are_tested_successfully">ಎಲ್ಲಾ ನೋಂದಣಿಗೆ ಬಂದ ಬಳಕೆದಾರರನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಪರೀಕ್ಷಿಸಲಾಗಿದೆ</string> <string name="all_registered_user_are_tested_successfully">ಎಲ್ಲಾ ನೋಂದಣಿಗೆ ಬಂದ ಬಳಕೆದಾರರನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಪರೀಕ್ಷಿಸಲಾಗಿದೆ</string>
<string name="start_incubation">ಇನ್ಕ್ಯಬೇನ್ ಆರಂಭ</string> <string name="start_incubation">ಇನ್ಕ್ಯಬೇನ್ ಪ್ರಾರಂಭಿಸಿ</string>
<string name="check_buffer">ಬಫರ್ ಚೆಕ್ ಮಾಡಿ</string> <string name="check_buffer">ಬಫರ್ ಚೆಕ್ ಮಾಡಿ</string>
<!-- Kannada Translations --> <!-- Kannada Translations -->
<string name="low_battery_warning">ಬ್ಯಾಟರಿ ಸ್ತರ 40% ಕ್ಕಿಂತ ಕಡಿಮೆಯಾಗಿದೆ, ದಯವಿಟ್ಟು ಸಾಧನವನ್ನು ಮುಂದುವರಿಸಲು ಸಾಧನವನ್ನು ಚಾರ್ಜ್ ಮಾಡಿ</string> <string name="low_battery_warning">ಬ್ಯಾಟರಿ ಸ್ತರ 40% ಕ್ಕಿಂತ ಕಡಿಮೆಯಾಗಿದೆ, ಟೆಸ್ಟ್ ಮುಂದುವರಿಸಲು ದಯವಿಟ್ಟು ಡಿವೈಸ ಚಾರ್ಜ್ ಮಾಡಿ</string>
<string name="test_already_conducted">ಈ ಬಳಕೆದಾರನ ಮೇಲೆ ಪರೀಕ್ಷೆ ಇನ್ನು ಮುಗಿದಿದೆ</string> <string name="test_already_conducted">ಈ ಬಳಕೆದಾರನ ಮೇಲೆ ಟೆಸ್ಟ್ ಮುಗಿದಿದೆ </string>
<string name="incubation_not_completed">ಇನ್ಕ್ಯೂಬೇಷನ್ ಹತ್ತಿಲ್ಲ 15 ನಿಮಿಷಗಳ ಪೂರ್ತಿ ಆಗಿಲ್ಲ</string> <string name="incubation_not_completed">15 ನಿಮಿಷಗಳ ಇನ್ಕ್ಯೂಬೇಷನ್ ಇನ್ನು ಪೂರ್ತಿ ಆಗಿಲ್ಲ್ಲ</string>
<string name="incubation_crossed_30_minutes">ಇನ್ಕ್ಯೂಬೇಷನ್ 30 ನಿಮಿಷಗಳನ್ನು ದಾಟಿದೆ, ಇನ್ನೊಮ್ಮೆ ಇನ್ಕ್ಯೂಬೇಷನ್ ಮಾಡಬೇಕಾಗಿದೆ</string> <string name="incubation_crossed_30_minutes">ಇನ್ಕ್ಯೂಬೇಷನ್ 30 ನಿಮಿಷಗಳನ್ನು ದಾಟಿದೆ, ಇನ್ನೊಮ್ಮೆ ಇನ್ಕ್ಯೂಬೇಷನ್ ಮಾಡಬೇಕಾಗಿದೆ</string>
<string name="incubation_not_started">ಬಳಕೆದಾರನ ಮೇಲೆ ಇನ್ಕ್ಯಬೇಷನ್ ಆರಂಭವಾಗಿಲ್ಲ</string> <string name="incubation_not_started">ಟೆಸ್ಟ್ ಸ್ಯಾಂಪಲ್ ಇನ್ಕ್ಯಬೇಷನ್ ಇನ್ನು ಆರಂಭವಾಗಿಲ್ಲ</string>
<string name="test_concluded">ಪರೀಕ್ಷೆ ಮುಗಿಯಿತು</string> <string name="test_concluded">ಟೆಸ್ಟ್ ಮುಕ್ತಯವಾಗಿದೆ</string>
<string name="test_pending">ಪರೀಕ್ಷೆ ಬಾಕಿ ಇದೆ</string> <string name="test_pending">ಟೆಸ್ಟ್ ಇನ್ನು ಮುಗಿದಿಲ್ಲ</string>
<string name="blood_group_error">ದಯವಿಟ್ಟು ನಿಮ್ಮ ರಕ್ತ ಗುಂಡಾರವನ್ನು ನಮೂದಿಸಿ</string> <string name="blood_group_error">ರಕ್ತ ಗುಂಪನ್ನುತಪ್ಪಾಗಿ ನಮೂದಿಸಿದ್ಧೀರಿ </string>
<string name="blood_group_toast">ದಯವಿಟ್ಟು ನಿಮ್ಮ ರಕ್ತ ಗುಂಡಾರವನ್ನು ನಮೂದಿಸಿ</string> <string name="blood_group_toast">ದಯವಿಟ್ಟು ನಿಮ್ಮ ರಕ್ತ ಗುಂನ್ನು ನಮೂದಿಸಿ</string>
<string name="blood_group_updated_successfully">ರಕ್ತ ಗುಂಡಾರ ಯಶಸ್ವಿಯಾಗಿ ನವೀಕರಿಸಲಾಗಿದೆ</string> <string name="blood_group_updated_successfully">ರಕ್ತ ಗುಂಪನ್ನು ಯಶಸ್ವಿಯಾಗಿ ನವೀಕರಿಸಲಾಗಿದೆ</string>
<string name="failed_to_update_blood_group">ರಕ್ತ ಗುಂಡಾರ ನವೀಕರಿಸಲು ವಿಫಲವಾಗಿದೆ: %1$s</string> <string name="failed_to_update_blood_group">ರಕ್ತ ಗುಂಪನ್ನು ನವೀಕರಿಸಲು ವಿಫಲವಾಗಿದೆ</string>
<string name="no_user_data_found">ನೀರು ನಿರ್ದಿಷ್ಟ ಐಡಿಗೆ ಯಾವುದೇ ಬಳಕೆದಾರ ಡೇಟಾ ಕಂಡುಬಂದಿಲ್ಲ</string> <string name="no_user_data_found"> ನಿರ್ದಿಷ್ಟ ಬಳಕೆದಾರರ ಐಡಿಗೆ ಯಾವುದೇ ಡೇಟಾ ಕಂಡುಬಂದಿಲ್ಲ</string>
<string name="device_disconnected">ಸಾಧನ ಹಂಚಿಹೋಯಿತು</string> <string name="device_disconnected">ಡಿವೈಸ್ ಸಂಪರ್ಕ ಕಡಿತಗೊಂಡಿದೆ</string>
<string name="no_device_found">ಯಾವುದೇ ಸಾಧನ ಕಂಡುಬಂದಿಲ್ಲ</string> <string name="no_device_found">ಯಾವುದೇ ಡಿವೈಸ್ ಕಂಡುಬಂದಿಲ್ಲ</string>
<string name="invalid_kit_number">ಅಮಾನ್ಯವಾದ ಕಿಟ್ ಸಂಖ್ಯೆ</string> <string name="invalid_kit_number">ಕಿಟ್ ಸಂಖ್ಯೆ ತಪ್ಪಾಗಿದ</string>
<string name="internt_not">ಇಂಟರ್ನೆಟ್ ಲಭ್ಯವಿಲ್ಲ</string> <string name="internt_not">ಇಂಟರ್ನೆಟ್ ಲಭ್ಯವಿಲ್ಲ</string>
<string name="internt_not_local">ಇಂಟರ್ನೆಟ್ ಲಭ್ಯವಿಲ್ಲ, ಪರೀಕ್ಷೆ ವಿವರಗಳನ್ನು ಸ್ಥಾನಿಕವಾಗಿ ಉಳಿಸಲಾಗಿದೆ</string> <string name="internt_not_local">ಇಂಟರ್ನೆಟ್ ಲಭ್ಯವಿಲ್ಲ, ಪರೀಕ್ಷೆ ವಿವರಗಳನ್ನು ಸ್ಥಳೀಯ ಜಾಗದಲ್ಲಿ ಉಳಿಸಲಾಗಿದೆ</string>
<string name="error_local">ಡೇಟಾ ಅಪ್ಲೋಡ್ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿದೆ, ಪರೀಕ್ಷೆ ವಿವರಗಳನ್ನು ಸ್ಥಾನಿಕವಾಗಿ ಉಳಿಸಲಾಗಿದೆ</string> <string name="error_local">ಡೇಟಾ ಅಪ್ಲೋಡ್ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿದೆ, ಪರೀಕ್ಷೆ ವಿವರಗಳನ್ನು ಸ್ಥಾನಿಕವಾಗಿ ಉಳಿಸಲಾಗಿದೆ</string>
<string name="error_exist">ಇನ್ನೊಂದು ಬಫರ್ ಪಡೆಯುವಾಗ ತಪ್ಪಾಗಿದೆ</string> <string name="error_exist">ಇನ್ನೊಂದು ಬಫರ್ ಪಡೆಯುವಾಗ ತಪ್ಪಾಗಿದೆ</string>
<string name="do_exist">ನೀವು ಇನ್ನೊಂದು ಬಫರ್ ಜಾರಿಗೆ ಹೋಗಲು ಇಚ್ಛಿಸುತ್ತಾರಾ?</string> <string name="do_exist">ನೀವು ಇನ್ನೊಂದು ಬಫರ್ ಜಾರಿಗೆ ಹೋಗಲು ಇಚ್ಛಿಸುತ್ತಾರಾ?</string>
<string name="test_go_noback">ಪರೀಕ್ಷೆ ಜರುಗುತ್ತಿದೆ, ಹಿಂತಿರುಗಲು ಸಾಧ್ಯವಿಲ್ಲ</string> <string name="test_go_noback">ಟೆಸ್ಟ್ ಪ್ರಗತಿಯಲ್ಲಿದೆ. ಹಿಂತಿರುಗಲು ಸಾಧ್ಯವಿಲ್ಲ</string>
<string name="kit_uploaded">ಕಿಟ್ ಪರಿಣಾಮ ಯಶಸ್ವಿಯಾಗಿ ಅಪ್ಲೋಡ್ ಆಗಿದೆ</string> <string name="kit_uploaded">ಕಿಟ್ ಯಶಸ್ವಿಯಾಗಿ ಅಪ್ಲೋಡ್ ಆಗಿದೆ</string>
<string name="kit_upload_failed">ಕಿಟ್ ಪರಿಣಾಮ ಅಪ್ಲೋಡ್ ಆಗಲಿಲ್ಲ, ಅದನ್ನು ಕೈಯಾರೆ ಹೊಸದಾಗಿ ಬರೆಯಿರಿ</string> <string name="kit_upload_failed">ಕಿಟ್ ಅಪ್ಲೋಡ್ ವಿಫಲವಾಗಿದೆ. ಅದನ್ನು ಕೈಯಾರೆ ಹೊಸದಾಗಿ ಬರೆಯಿರಿ</string>
<string name="test_ongoing">ಪರೀಕ್ಷೆ ಜರುಗುತ್ತಿದೆ</string> <string name="test_ongoing">ಟೆಸ್ಟ್ ಪ್ರಗತಿಯಲ್ಲಿದೆ</string>
<string name="error_classification">ವರ್ಗೀಕರಣ ನಡೆಸುವಾಗ ತಪ್ಪಾಗಿದೆ</string> <string name="error_classification">ವರ್ಗೀಕರಣ ನಡೆಸುವಾಗ ತಪ್ಪಾಗಿದೆ</string>
<string name="test_upload">ಪರೀಕ್ಷೆ ಫಲಿತಾಂಶ ಯಶಸ್ವಿಯಾಗಿ ಅಪ್ಲೋಡ್ ಆಗಿದೆ</string> <string name="test_upload">ಟೆಸ್ಟ್ ಫಲಿತಾಂಶ ಯಶಸ್ವಿಯಾಗಿ ಅಪ್ಲೋಡ್ ಆಗಿದೆ</string>
<string name="test_upload_failed">ಪರೀಕ್ಷೆ ಫಲಿತಾಂಶ ಅಪ್ಲೋಡ್ ಆಗಲಿಲ್ಲ</string> <string name="test_upload_failed">ಟೆಸ್ಟ್ ಫಲಿತಾಂಶ ಅಪ್ಲೋಡ್ ಆಗಲಿಲ್ಲ</string>
<string name="log_out">ಲಾಗೌಟ್ ಮಾಡಿ</string> <string name="log_out">ಲಾಗೌಟ್ ಮಾಡಿ</string>
<string name="do_log_out">ನೀವು ಅಪ್ಲಿಕೇಶನ್ ನಿಂದ ಲಾಗೌಟ್ ಮಾಡಲು ಬಯಸುತ್ತಿದ್ದೀರಾ?</string> <string name="do_log_out">ನೀವು ಅಪ್ಲಿಕೇಶನ್ ನಿಂದ ಲಾಗೌಟ್ ಮಾಡಲು ಬಯಸುತ್ತಿದ್ದೀರಾ?</string>
<string name="cancelled_unable_scan">ರದ್ದು ಮಾಡಲಾಗಿದೆ: ಸ್ಕ್ಯಾನ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ, ಮತ್ತೊಮ್ಮೆ ಪ್ರಯಾಸಿಸಿ!!</string> <string name="cancelled_unable_scan">ರದ್ದು ಮಾಡಲಾಗಿದೆ: ಸ್ಕ್ಯಾನ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ, ಮತ್ತೊಮ್ಮೆ ಪ್ರಯಾಸಿಸಿ!!</string>
<string name="kit_updated">ಕಿಟ್ ಸಂಖ್ಯೆ ನವೀಕರಿಸಲಾಗಿದೆ, ದಯವಿಟ್ಟು ಟೆಸ್ಟ್ ಆರಂಭಿಸುವ ಮೊದಲು ಬಳಸುವವನನ್ನು ಆಯ್ಕೆಮಾಡಿ</string> <string name="kit_updated">ಕಿಟ್ ಸಂಖ್ಯೆ ನವೀಕರಿಸಲಾಗಿದೆ, ದಯವಿಟ್ಟು ಟೆಸ್ಟ್ ಆರಂಭಿಸುವ ಮೊದಲು ಬಳಸುವವನನ್ನು ಆಯ್ಕೆಮಾಡಿ</string>
<string name="select_patient">ದಯವಿಟ್ಟು ಟೆಸ್ಟ್ ಆರಂಭಿಸುವ ಮೊದಲು ರೋಗಿಯನ್ನು ಆಯ್ಕೆಮಾಡಿ</string> <string name="select_patient">ದಯವಿಟ್ಟು ಟೆಸ್ಟ್ ಆರಂಭಿಸುವ ಮೊದಲು ರೋಗಿಯನ್ನು ಹೆಸರನ್ನು ಆಯ್ಕೆಮಾಡಿ</string>
<string name="enable_location">ದಯವಿಟ್ಟು ಸ್ಥಾನ ಸೇವೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ</string> <string name="enable_location">ದಯವಿಟ್ಟು ಸ್ಥಾನ ಸೇವೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ</string>
<string name="location_denied">ಸರಿಯಾದ ಸ್ಥಾನ ಅನುಮತಿ ನಿರಾಕರಿಸಲಾಗಿದೆ</string> <string name="location_denied">ಸರಿಯಾದ ಸ್ಥಾನ ಅನುಮತಿ ನಿರಾಕರಿಸಲಾಗಿದೆ</string>
<string name="coarse_location_denied">ಅಲ್ಪ ಸರಿಯಾದ ಸ್ಥಾನ ಅನುಮತಿ ನಿರಾಕರಿಸಲಾಗಿದೆ</string> <string name="coarse_location_denied">ಕೋರ್ಸ್ ಸ್ಥಾನ್ನಕ್ಕೆ ಅನುಮತಿ ನಿರಾಕರಿಸಲಾಗಿದೆ</string>
<string name="permission_grant">ನೀವು ಈ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಲು ಎಲ್ಲಾ ಫೈಲ್‌ಗಳಿಗೆ ಪ್ರವೇಶ ಅನುಮತಿ ನೀಡಬೇಕು</string> <string name="permission_grant">ನೀವು ಈ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಲು ಎಲ್ಲಾ ಫೈಲ್‌ಗಳಿಗೆ ಪ್ರವೇಶ ಅನುಮತಿ ನೀಡಬೇಕು</string>
<string name="permission_required">ಈ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಲು ಎಲ್ಲಾ ಅನುಮತಿಗಳು ಅಗತ್ಯವಿವೆ.</string> <string name="permission_required">ಈ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಲು ಎಲ್ಲಾ ಅನುಮತಿಗಳು ಅಗತ್ಯವಿವೆ.</string>
<string name="device_not">ಡೆವೈಸ್ ಸಂಪರ್ಕಿಸಲಾಗಿಲ್ಲ.</string> <string name="device_not">ಡೆವೈಸ್ ಸಂಪರ್ಕಿಸಲಾಗಿಲ್ಲ.</string>
<string name="device">Device is Connected.</string> <string name="device">ಡಿವೈಸ್ ಕನೆಕ್ಟ್ ಆಗಿದೆ</string>
<string name="enter_proper_login_id">ದಯವಿಟ್ಟು ಸರಿಯಾದ ಲಾಗಿನ್ ಐಡಿ ನಮೂದಿಸಿ</string> <string name="enter_proper_login_id">ದಯವಿಟ್ಟು ಸರಿಯಾದ ಲಾಗಿನ್ ಐಡಿ ನಮೂದಿಸಿ</string>
<string name="enter_proper_password">ದಯವಿಟ್ಟು ಸರಿಯಾದ ಪಾಸ್‌ವರ್ಡ್ ನಮೂದಿಸಿ</string> <string name="enter_proper_password">ದಯವಿಟ್ಟು ಸರಿಯಾದ ಪಾಸ್‌ವರ್ಡ್ ನಮೂದಿಸಿ</string>
<string name="wrong_password">ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್</string> <string name="wrong_password">ಪಾಸ್ವರ್ಡ್ ತಪ್ಪಾಗಿ ನಮೂದಿಸಿದ್ದೀರಿ</string>
<string name="wrong_user_id">ತಪ್ಪಾದ ಬಳಕೆದಾರ ಐಡಿ</string> <string name="wrong_user_id">ಬಳಕೆದಾರ ಐಡಿ ತಪ್ಪಾಗಿ ನಮೂದಿಸಿದ್ದೀರಿ</string>
<string name="error_invalid_test">ಅಮಾನ್ಯ ಟೆಸ್ಟ್. ಡಿ-ಆಕ್ಸಿಜನೇಷನ್ ಸಮಸ್ಯ</string> <string name="error_invalid_test">ದೋಷ. ಟೆಸ್ಟ್ ಅಮಾನ್ಯವಾಗಿದ</string>
<string name="error_negative_abs">ದೋಷ: ನೆಗೆಟಿವ್ ಆಬ್ಸ್. ಬ್ಲ್ಯಾಂಕ್ ರೀಡಿಂಗ್ ಪುನಃ ತೆಗೆದುಕೊಳ್ಳಿ</string> <string name="error_negative_abs">ದೋಷ: ನೆಗೆಟಿವ್ ಆ ಬಿ ಸ್</string>
<string name="error_improper_buffer_high">ದೋಷ: ಅಮಾನ್ಯ ಟೆಸ್ಟ್. ಬಫರ್ ರೀಡಿಂಗ್ ಅಸರವಿಲ್ಲ (ಹೈ)</string> <string name="error_improper_buffer_high">ದೋಷ: ಅಮಾನ್ಯ ಟೆಸ್ಟ್. ಬಫರ್ ರೀಡಿಂಗ್ ಅಸರವಿಲ್ಲ (ಹೈ)</string>
<string name="error_improper_buffer_low">ದೋಷ: ಅಮಾನ್ಯ ಟೆಸ್ಟ್. ಬಫರ್ ರೀಡಿಂಗ್ ಅಸರವಿಲ್ಲ (ಲೋ)</string> <string name="error_improper_buffer_low">ದೋಷ: ಅಮಾನ್ಯ ಟೆಸ್ಟ್. ಬಫರ್ ರೀಡಿಂಗ್ ಅಸರವಿಲ್ಲ (ಲೋ)</string>
<string name="error_processing_device_data">ಡೇಟಾ ಪ್ರಕ್ರಿಯಿಸುವಾಗ ದೋಷ</string> <string name="error_processing_device_data">ದೋಷ. ಸಾಧನ ಡಾಟಾವನ್ನುಸಂಸ್ಕರಿಸಲಾಗುತ್ತಿದೆ</string>
<string name="error_repeat_test_lower_volume">ಅಮಾನ್ಯ. ರೇಟ್ ಹೆಚ್ಚುವ ಹೊರತು ಪುನಃ ಟೆಸ್ಟ್ ಮಾಡಿ</string> <string name="error_repeat_test_lower_volume">ದೋಷ. ಕಡಿಮೆ ಸ್ಯಾಂಪಲ್ ಬಳಸಿ ಪರೀಕ್ಷೆಯನ್ನು ಪುನರಾವರ್ತಿಸಿ</string>
<string name="error_repeat_test_higher_volume">ಅಮಾನ್ಯ. ಅತ್ಯಂತ ಕಡಿಮೆ ಅಭ್ಸರ್ಬೆನ್ಸ್ - ಹೆಚ್ಚು ಹೊರತು ಪುನಃ ಟೆಸ್ಟ್</string> <string name="error_repeat_test_higher_volume">ದೋಷ. ಹೆಚ್ಚಿನ ಸ್ಯಾಂಪಲ್ ಬಳಸಿ ಪರೀಕ್ಷೆಯನ್ನು ಪುನರಾವರ್ತಿಸಿ</string>
<string name="positive_for_sickle_cell">ಸಿಕ್ಲ್ ಸೆಲ್ ಸಾಕಾರಿ. HPLC ದೃಢೀಕರಣಕ್ಕಾಗಿ</string> <string name="positive_for_sickle_cell">ಕುಡಗೋಲು ಕಣ ರಕ್ತಹೀನತೆ "ಪಾಸಿಟಿವ್" ಫಲಿತಂಶ ಬಂದಿರುತ್ತೇವೆ</string>
<string name="something_wrong_with_device">ಸಾಧನದಲ್ಲಿ ಏನಾದರೂ ತಪ್ಪಾಗಿದೆ, ದಯವಿಟ್ಟು ಸಾಧನವನ್ನು ಹತ್ತಿರಕ್ಕೆ ತರಿಸಿ ಮತ್ತೆ ಬಳಸಿ ಬಳಸಿ ಬಳಸಿ ಪರೀಕ್ಷಿಸಿ</string> <string name="something_wrong_with_device">ಡಿವೈಸ್ ನಲ್ಲಿ ಏನ ತಪ್ಪಾಗಿದೆ</string>
<string name="processing_result">ಪ್ರಕ್ರಿಯಿಸುತ್ತಿದೆ ಫಲಿತ</string> <string name="processing_result">ಫಲಿತಂಶವನ್ನು ಸಂಸ್ಕರಿಸುತ್ತದೆ</string>
<string name="data_collected_processing_data">ಮಿತಿ ಸೇರಿಸಿದ ಡೇಟಾ, ಡೇಟಾ ಪ್ರಕ್ರಿಯಿಸುತ್ತಿದೆ</string> <string name="data_collected_processing_data">ಂಗ್ರಹಿಸಿದ ಡೇಟಾವನ್ನು ಸಂಸ್ಕರಿಸಲಾಗುತ್ತಿದೆ </string>
<string name="sample_completed">ನಮೂನೆ ಪೂರ್ಣಗೊಂಡಿದೆ</string> <string name="sample_completed">ಸ್ಯಾಂಪಲ್ ಪರೀಕ್ಷೆಪೂರ್ಣಗೊಂಡಿದೆ</string>
<string name="gathering_data">ಡೇಟಾ ಸಂಗ್ರಹಿಸುತ್ತಿದೆ</string> <string name="gathering_data">ಡೇಟಾ ಸಂಗ್ರಹಿಸುತ್ತಿದೆ</string>
<string name="sample_started">ನಮೂನೆ ಪ್ರಾರಂಭವಾಗಿದೆ</string> <string name="sample_started">ಸ್ಯಾಂಪಲ್ ಪರೀಕ್ಷೆ ಪ್ರಾರಂಭವಾಗಿದೆ</string>
<string name="buffer_completed">ಬಫರ್ ಪೂರ್ಣಗೊಂಡಿದೆ</string> <string name="buffer_completed">ಬಫರ್ ಪರೀಕ್ಷೆ ಪೂರ್ಣಗೊಂಡಿದೆ</string>
<string name="buffer_started">ಬಫರ್ ಪ್ರಾರಂಭವಾಗಿದೆ</string> <string name="buffer_started">ಬಫರ್ ಪರೀಕ್ಷೆ ಪ್ರಾರಂಭವಾಗಿದೆ</string>
<string name="power_bank">Connect with Power Bank</string> <string name="power_bank">Connect with Power Bank</string>
<string name="start">ಆರಂಭ</string> <string name="start">ಪ್ರಾರಂಭಿಸಿ</string>
<string name="place_sample">ನಮೂನೆ ಇಟ್ಟುಕೊಳ್ಳಿ</string> <string name="place_sample">ಸ್ಯಾಂಪಲ್ ಅನ್ನು ಒಳಗೆ ಇರಿಸಿ</string>
<string name="invalid">ಅಮಾನ್ಯ</string> <string name="invalid">ಅಮಾನ್ಯವಾಗಿದೆ</string>
<string name="deviceinfo">ಸಾಧನ ಮಾಹಿತಿ</string> <string name="deviceinfo">ಸಾಧನ ಮಾಹಿತಿ</string>
<string name="error">ದೋಷ</string> <string name="error">ದೋಷ</string>
<string name="language_update">ಭಾಷೆ ಯಶಸ್ವಿಯಾಗಿ ನವೀಕರಿಸಲಾಗಿದೆ</string> <string name="language_update">ಭಾಷೆಯನ್ನುಯಶಸ್ವಿಯಾಗಿ ನವೀಕರಿಸಲಾಗಿದೆ</string>
<string name="select_language">ನಿಮ್ಮ ಆದರಿತ ಭಾಷೆಯನ್ನು ಆಯ್ಕೆ ಮಾಡಿ</string> <string name="select_language">ನಿಮ್ಮ ಆದರಿತ ಭಾಷೆಯನ್ನು ಆಯ್ಕೆ ಮಾಡಿ</string>
<string name="app_language">ಅಪ್ಲಿಕೇಶನ್ ಭಾಷೆ</string> <string name="app_language">ಅಪ್ಲಿಕೇಶನ್ ಭಾಷೆ</string>
<string name="add_blood_group">ರಕ್ತ ಗುಂಡನ್ನು ಸೇರಿಸಿ</string> <string name="add_blood_group">ರಕ್ತ ಗುಂಡನ್ನು ಸೇರಿಸಿ</string>
<string name="ok">ಸರಿ</string> <string name="ok">ಸರಿ</string>
<string name="downloadcsv">CSV ಡೌನ್ಲೋಡ್ ಮಾಡಿ</string> <string name="downloadcsv">CSV ಡೌನ್ಲೋಡ್ ಮಾಡಿ</string>
<string name="action_activity">Activities</string> <string name="action_activity">ಚಟುವಟಿಕೆಗಳು</string>
<string name="check_cuvette">Checking cuvette presence</string> <string name="check_cuvette">ಕುವೆಟ್ ಇರುವಿಕೆಯನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ</string>
<string name="cuvette_present">Cuvette present</string> <string name="cuvette_present">ಕುವೆಟ್ಟೆ ಇರುತ್ತದೆ</string>
<string name="cuvette_absent">Cuvette absent</string> <string name="cuvette_absent">ಕುವೆಟ್ಟೆ ಇರುವುದಿಲ್ಲ </string>
<string name="retry">Retry</string> <string name="retry">ಮರುಪ್ರಯತ್ನಿಸಿ</string>
<string name="Firefox">Firefox</string> <string name="Firefox">ಫೈರ್‌ಫಾಕ್ಸ್</string>
<string name="Files">Files</string> <string name="Files">ಫೈಲ್</string>
<string name="usb_terminal">Usb Terminal</string> <string name="usb_terminal">ಯುಎಸ್ಬಿ ಟರ್ಮಿನಲ್</string>
<string name="menu_about">About</string> <string name="menu_about">ಬಗ್ಗೆ</string>
<string name="action_about">About</string> <string name="action_about">ಬಗ್ಗೆ</string>
<string name="lab_name">Lab Name</string> <string name="lab_name">ಲ್ಯಾಬ್ ಹೆಸರು</string>
<string name="smi">ಎಸ್ಎಂಐ</string>
<string name="smi_desp">ಷಣ್ಮುಖ ಇನ್ನೋವೇಶನ್ಸ್ ಬೆಂಗಳೂರಿನ ಇಂಡಿಯನ್ ಇನ್‌ಸ್ಟಿಟ್ಯೂಟ್ ಆಫ್ ಸೈನ್ಸ್‌ನಿಂದ ಸ್ಪಿನ್-ಆಫ್ ಆಗಿದೆ.2016 ರಲ್ಲಿ ಸ್ಥಾಪನೆಯಾಗಿದ್ದು, ಕಂಪನಿಯು ಆರೋಗ್ಯ ರಕ್ಷಣೆಯಲ್ಲಿ ತನ್ನ ರೀತಿಯ ಆಳವಾದ ತಂತ್ರಜ್ಞಾನ ಆಧಾರಿತ ಉತ್ಪನ್ನಗಳಲ್ಲಿ ಮೊದಲ ಬಾರಿಗೆ ನವೀನ ಮೇಡ್ ಇನ್ ಇಂಡಿಯಾವನ್ನು ತಲುಪಿಸುತ್ತಿದೆ. ಗಮನಾರ್ಹ ಪರಿಹಾರಗಳಲ್ಲಿ ಮೊಬೈಲ್ ಸೋಂಕು ಪರೀಕ್ಷೆ ಮತ್ತು ವರದಿ ಮಾಡುವ ಲ್ಯಾಬ್‌ಗಳು (MITR ಲ್ಯಾಬ್ಸ್), ಪೋರ್ಟಬಲ್ ಥರ್ಮಲ್ ಸೈಕ್ಲರ್ (ಪಾಲಿಕ್ಯೂಬ್) ಸೇರಿವೆ. ಕಂಪನಿಯು ಸಿಕ್ಲೆಸರ್ಟ್ ® ಅನ್ನು ಪ್ರಾರಂಭಿಸಿತು, ಇದು ಭಾರತದ ಮೊದಲ CDSCO ಅಂಗೀಕರಿಸಿದ ಕುಡಗೋಲು-ಕಣ ರಕ್ತಹೀನತೆಗಾಗಿ ಸ್ಥಳೀಯ ರೋಗನಿರ್ಣಯ ಪರೀಕ್ಷೆಯನ್ನು ಅನುಮೋದಿಸಿದೆ. ನಮ್ಮ ಗ್ರಾಹಕರು ಸರ್ಕಾರಿ, ಲಾಭರಹಿತ ಮತ್ತು ಖಾಸಗಿ ವಲಯದ ಕಂಪನಿಗಳನ್ನು ಒಳಗೊಂಡಿರುತ್ತಾರೆ. ಐಐಎಸ್‌ಸಿ, ಐಐಟಿ ತಿರುಪತಿಯಂತಹ ಪ್ರಮುಖ ಸಂಶೋಧನಾ ಸಂಸ್ಥೆಗಳು ವಿಶಿಷ್ಟ ಯೋಜನೆಗಳಿಗೆ ನಮ್ಮನ್ನು ತೊಡಗಿಸಿಕೊಂಡಿವೆ. ವಿಶ್ವ ದರ್ಜೆಯ ಉತ್ಪನ್ನಗಳೊಂದಿಗೆ ಭಾರತೀಯ ಮತ್ತು ಜಾಗತಿಕ ಗ್ರಾಹಕರನ್ನು ಬೆಂಬಲಿಸುವಲ್ಲಿ ನಾವು ಹೆಮ್ಮೆಪಡುತ್ತೇವೆ</string>
<string name="learn_more">ಹೆಚ್ಚಿನ ವಿವರಗಳಿಗೆ ಸಂಪರ್ಕಿಸಿ: <u>sminnovations.in</u></string>
<string name="commands">ಆಜ್ಞೆಗಳು</string>
<string name="select_cuvette_size">Cuvette ಗಾತ್ರವನ್ನು ಆಯ್ಕೆಮಾಡಿ</string>
<string name="sample_id">Sample Id</string>
<string name="quick_capture">ತ್ವರಿತ ಕ್ಯಾಪ್ಚರ್</string>
<string name="reset_password_for_this_device">ಈ ಸಾಧನಕ್ಕಾಗಿ ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ಮರುಹೊಂದಿಸಿ</string>
<string name="calibrate_device">ಸಾಧನವನ್ನು ಮಾಪನಾಂಕ ಮಾಡಿ</string>
<!-- Add translations for other strings --> <!-- Add translations for other strings -->
</resources> </resources>

View File

@@ -25,5 +25,11 @@
<item>ka</item> <item>ka</item>
<!-- Use language codes (e.g., en, kn) as values --> <!-- Use language codes (e.g., en, kn) as values -->
</string-array> </string-array>
<string-array name="district">
<item>Mysuru</item>
<item>Kodagu</item>
<item>Chamarajanagar</item>
<item>Other</item>
</string-array>
</resources> </resources>

View File

@@ -38,6 +38,7 @@
</string-array> </string-array>
<string-array name="blood_group"> <string-array name="blood_group">
<item>Unknown</item>
<item>O+ve</item> <item>O+ve</item>
<item>O-ve</item> <item>O-ve</item>
<item>A+ve</item> <item>A+ve</item>
@@ -198,7 +199,7 @@
<string name="set_baseline_reference_again">Set Baseline/Reference again?</string> <string name="set_baseline_reference_again">Set Baseline/Reference again?</string>
<string name="baseline_instruction">Baseline Instruction</string> <string name="baseline_instruction">Baseline Instruction</string>
<string name="to_be_launched_in_next_version_of_the_app">To be launched in next version of the app</string> <string name="to_be_launched_in_next_version_of_the_app">To be launched in next version of the app</string>
<string name="invalid_kit">Invalid Kit Serial Number, correct example, SMI/SC/019/01/001</string> <string name="invalid_kit">Invalid Kit Serial Number</string>
<string name="user_list">User List</string> <string name="user_list">User List</string>
<string name="user_id">User ID</string> <string name="user_id">User ID</string>
<string name="aadhar_id">Aadhar ID</string> <string name="aadhar_id">Aadhar ID</string>
@@ -295,4 +296,13 @@
<string name="menu_about">About</string> <string name="menu_about">About</string>
<string name="action_about">About</string> <string name="action_about">About</string>
<string name="lab_name">Lab Name</string> <string name="lab_name">Lab Name</string>
<string name="smi">SMI</string>
<string name="smi_desp"><b>ShanMukha Innovations</b> is a spin-off from Indian Institute of Science, Bangalore. Incorporated in 2016, the company has been delivering innovative Made in India first of its kind deep technology-based products in healthcare.\\n\\nNotable solutions include Mobile Infection Testing and Reporting Labs (MITR Labs), portable thermal cycler (PolyCube).\\n\\nThe company launched Sicklecert ®, Indias first CDSCO approved indigenous diagnostic test for sickle-cell anemia.\\n\\nOur customers include government, non-profit and private sector companies. Leading research institutes such as IISc, IIT Tirupati have engaged us for unique projects. We take pride in supporting Indian and global customers with world-class products.</string>
<string name="learn_more">Visit to learn more: <u>sminnovations.in</u></string>
<string name="commands">Commands</string>
<string name="select_cuvette_size">Select Cuvette Size</string>
<string name="sample_id">Sample Id</string>
<string name="quick_capture">Quick Capture</string>
<string name="reset_password_for_this_device">Reset password for this device</string>
<string name="calibrate_device">Calibrate Device</string>
</resources> </resources>

View File

@@ -0,0 +1,5 @@
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.example.account"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:smallIcon="@mipmap/ic_launcher" />

View File

@@ -362,7 +362,7 @@ class HemoCubeFragmentTest {
fun testDeviceRatioClassificationSickleCellDiseaseLowerBound() { fun testDeviceRatioClassificationSickleCellDiseaseLowerBound() {
val ratio = 0.391 val ratio = 0.391
val result = hemoCubeFragment.deviceRatioClassification(ratio) val result = hemoCubeFragment.deviceRatioClassification(ratio)
assertEquals("Sickle Cell Disease", result) assertEquals("Positive for Sickle Cell. HPLC for Confirmation", result)
} }
@Test @Test
@@ -383,14 +383,14 @@ class HemoCubeFragmentTest {
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineNormal() { fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineNormal() {
val result = val result =
hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline", 2.5) hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline", 2.5)
assertEquals("Borderline. Normal", result) assertEquals("Normal", result)
} }
@Test @Test
fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineSickleCellTrait1() { fun findResultWithAdditionalMethods_ValidInput_ReturnsBorderlineSickleCellTrait1() {
val result = val result =
hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline", 2.2) hemoCubeFragment.findResultWithAdditionalMethods(0.5, "Negative Borderline", 2.2)
assertEquals("Borderline. Sickle Cell Trait", result) assertEquals("Negative borderline. Confirm with HPLC", result)
} }
@Test @Test
@@ -400,7 +400,7 @@ class HemoCubeFragmentTest {
"Positive for Sickle Cell. HPLC for Confirmation", "Positive for Sickle Cell. HPLC for Confirmation",
1.4 1.4
) )
assertEquals("Borderline. Sickle Cell Trait", result) assertEquals("Positive for Sickle Cell. Confirm with HPLC", result)
} }
@Test @Test
@@ -410,7 +410,7 @@ class HemoCubeFragmentTest {
"Positive for Sickle Cell. HPLC for Confirmation", "Positive for Sickle Cell. HPLC for Confirmation",
1.33 1.33
) )
assertEquals("Borderline. Sickle Cell Disease", result) assertEquals("Positive for Sickle Cell. Confirm with HPLC", result)
} }
@Test @Test
@@ -441,9 +441,9 @@ class HemoCubeFragmentTest {
val result = hemoCubeFragment.findResultWithAdditionalMethods( val result = hemoCubeFragment.findResultWithAdditionalMethods(
0.5, 0.5,
"Positive for Sickle Cell. HPLC for Confirmation", "Positive for Sickle Cell. HPLC for Confirmation",
1.4 1.67
) )
assertEquals("Borderline. Sickle Cell Trait", result) assertEquals("Sickle Cell Trait", result)
} }
@Test @Test