Change the project into Testing app
This commit is contained in:
@@ -2,15 +2,19 @@ plugins {
|
|||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'org.jetbrains.kotlin.android'
|
id 'org.jetbrains.kotlin.android'
|
||||||
id 'com.google.firebase.appdistribution'
|
id 'com.google.firebase.appdistribution'
|
||||||
|
id 'dagger.hilt.android.plugin'
|
||||||
id 'com.google.gms.google-services'
|
id 'com.google.gms.google-services'
|
||||||
|
id 'androidx.navigation.safeargs.kotlin'
|
||||||
|
id 'kotlin-kapt'
|
||||||
}
|
}
|
||||||
//apply plugin: 'kotlin-android'
|
//apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdk 33
|
compileSdk 33
|
||||||
|
namespace 'in.sminnovations.hpostesting'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.example.hpos"
|
applicationId "in.sminnovations.hpostesting"
|
||||||
minSdk 21
|
minSdk 21
|
||||||
targetSdk 33
|
targetSdk 33
|
||||||
versionCode 2
|
versionCode 2
|
||||||
@@ -26,11 +30,11 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_17
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_17
|
||||||
}
|
}
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '1.8'
|
jvmTarget = '17'
|
||||||
}
|
}
|
||||||
dataBinding {
|
dataBinding {
|
||||||
enabled = true
|
enabled = true
|
||||||
@@ -48,19 +52,21 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
implementation 'androidx.core:core-ktx:1.9.0'
|
implementation 'androidx.core:core-ktx:1.10.1'
|
||||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||||
implementation 'com.google.android.material:material:1.7.0'
|
implementation 'com.google.android.material:material:1.9.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'
|
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'
|
||||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.2'
|
|
||||||
implementation 'androidx.navigation:navigation-ui-ktx:2.5.2'
|
|
||||||
|
|
||||||
// Firebase
|
//firebase
|
||||||
implementation 'com.google.firebase:firebase-firestore-ktx:24.4.1'
|
implementation platform('com.google.firebase:firebase-bom:32.1.0')
|
||||||
implementation 'com.google.firebase:firebase-storage-ktx:20.1.0'
|
implementation 'com.google.firebase:firebase-firestore-ktx'
|
||||||
|
implementation 'com.google.firebase:firebase-auth-ktx'
|
||||||
|
implementation 'com.google.firebase:firebase-storage-ktx'
|
||||||
|
implementation 'com.firebaseui:firebase-ui-firestore:8.0.2'
|
||||||
|
implementation 'com.google.android.gms:play-services-auth:20.5.0'
|
||||||
implementation 'com.google.android.gms:play-services-location:21.0.1'
|
implementation 'com.google.android.gms:play-services-location:21.0.1'
|
||||||
// implementation 'androidx.core:core-ktx:+'
|
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
|
||||||
|
|
||||||
// Testing
|
// Testing
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
@@ -68,11 +74,11 @@ dependencies {
|
|||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
|
|
||||||
|
|
||||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
|
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
|
||||||
implementation 'com.opencsv:opencsv:4.6'
|
implementation 'com.opencsv:opencsv:4.6'
|
||||||
implementation 'com.github.mik3y:usb-serial-for-android:3.4.6'
|
implementation 'com.github.mik3y:usb-serial-for-android:3.4.6'
|
||||||
|
|
||||||
implementation "androidx.fragment:fragment-ktx:1.5.5"
|
implementation "androidx.fragment:fragment-ktx:1.6.0"
|
||||||
|
|
||||||
// CSV read, write
|
// CSV read, write
|
||||||
implementation 'com.opencsv:opencsv:4.6'
|
implementation 'com.opencsv:opencsv:4.6'
|
||||||
@@ -83,7 +89,26 @@ dependencies {
|
|||||||
// Google ML Kit usign play services
|
// Google ML Kit usign play services
|
||||||
implementation 'com.google.android.gms:play-services-code-scanner:16.0.0'
|
implementation 'com.google.android.gms:play-services-code-scanner:16.0.0'
|
||||||
|
|
||||||
}
|
//Room
|
||||||
//repositories {
|
implementation "androidx.room:room-ktx:2.6.0-alpha01"
|
||||||
// mavenCentral()
|
implementation "androidx.room:room-runtime:2.6.0-alpha01"
|
||||||
//}
|
kapt ("androidx.room:room-compiler:2.6.0-alpha01")
|
||||||
|
|
||||||
|
//image
|
||||||
|
implementation 'com.github.bumptech.glide:glide:4.13.2'
|
||||||
|
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
|
||||||
|
|
||||||
|
// Navigation Component
|
||||||
|
implementation "androidx.navigation:navigation-fragment-ktx:2.7.0-beta01"
|
||||||
|
implementation "androidx.navigation:navigation-ui-ktx:2.7.0-beta01"
|
||||||
|
|
||||||
|
//Dagger - Hilt
|
||||||
|
implementation "com.google.dagger:hilt-android:2.46"
|
||||||
|
kapt "com.google.dagger:hilt-android-compiler:2.46"
|
||||||
|
kapt "androidx.hilt:hilt-compiler:1.0.0"
|
||||||
|
|
||||||
|
// Retrofit + GSON
|
||||||
|
implementation "com.squareup.retrofit2:retrofit:2.9.0"
|
||||||
|
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos
|
package com.example.hpostesting
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<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">
|
||||||
package="com.example.hpos">
|
|
||||||
|
|
||||||
<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" />
|
||||||
@@ -16,7 +15,7 @@
|
|||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".MyApplication"
|
android:name="com.example.hpostesting.HPOSTestingApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
@@ -24,26 +23,27 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/hpos_icon_round"
|
android:roundIcon="@mipmap/hpos_icon_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.HPOS"
|
android:theme="@style/Theme.HPOSTesting"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
<activity
|
<activity
|
||||||
android:name=".presentation.KitScanActivity"
|
android:name="com.example.hpostesting.presentation.KitScanActivity"
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
android:exported="false" />
|
android:exported="false"
|
||||||
|
android:theme="@style/Theme.HPOS.NoActionBar"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".presentation.dashboard.DashboardActivity"
|
android:name="com.example.hpostesting.presentation.dashboard.DashboardActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:label="@string/title_activity_dashboard"
|
android:label="@string/title_activity_dashboard"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:theme="@style/Theme.HPOS.NoActionBar" />
|
android:theme="@style/Theme.HPOS.NoActionBar" />
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".presentation.testRight.UsbService"
|
android:name="com.example.hpostesting.presentation.testRight.UsbService"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".presentation.SplashActivity"
|
android:name="com.example.hpostesting.presentation.SplashActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
android:theme="@style/AppTheme.NoActionBar">
|
android:theme="@style/AppTheme.NoActionBar">
|
||||||
@@ -54,12 +54,13 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".presentation.testRight.TestRightActivity"
|
android:name="com.example.hpostesting.presentation.testRight.TestRightActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:parentActivityName=".presentation.MainActivity"
|
android:parentActivityName="com.example.hpostesting.presentation.MainActivity"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
android:windowSoftInputMode="adjustPan">
|
android:windowSoftInputMode="adjustPan"
|
||||||
|
android:theme="@style/Theme.HPOS.NoActionBar">
|
||||||
|
|
||||||
<!-- <intent-filter> -->
|
<!-- <intent-filter> -->
|
||||||
<!-- <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> -->
|
<!-- <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> -->
|
||||||
@@ -71,9 +72,10 @@
|
|||||||
<!-- android:resource="@xml/device_filter" /> -->
|
<!-- android:resource="@xml/device_filter" /> -->
|
||||||
</activity> <!-- android:theme="@style/Theme.HPOS.ActionBar" -->
|
</activity> <!-- android:theme="@style/Theme.HPOS.ActionBar" -->
|
||||||
<activity
|
<activity
|
||||||
android:name=".presentation.MainActivity"
|
android:name="com.example.hpostesting.presentation.MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:screenOrientation="portrait">
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
@@ -88,9 +90,6 @@
|
|||||||
android:stateNotNeeded="true"
|
android:stateNotNeeded="true"
|
||||||
tools:replace="android:screenOrientation" />
|
tools:replace="android:screenOrientation" />
|
||||||
|
|
||||||
<meta-data
|
|
||||||
android:name="preloaded_fonts"
|
|
||||||
android:resource="@array/preloaded_fonts" />
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package com.example.hpos
|
|
||||||
|
|
||||||
import android.app.Application
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.SupervisorJob
|
|
||||||
|
|
||||||
class MyApplication : Application() {
|
|
||||||
|
|
||||||
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
|
||||||
|
|
||||||
// private val sampleDetails = PatientDetails("Change it later");
|
|
||||||
// fun getSampleDetails() : PatientDetails = sampleDetails
|
|
||||||
// fun setSampleDetails(sample: SampleDetails) {sampleDetails = sample}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. firestore Database cache limit - full
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
package com.example.hpos.data.model;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
|
|
||||||
public class AadharCard {
|
|
||||||
private String uuid;
|
|
||||||
private String name;
|
|
||||||
private String dateOfBirth;
|
|
||||||
private String gender;
|
|
||||||
private String careOf;
|
|
||||||
private String district;
|
|
||||||
private String landmark;
|
|
||||||
private String house;
|
|
||||||
private String location;
|
|
||||||
private String pinCode;
|
|
||||||
private String postOffice;
|
|
||||||
private String state;
|
|
||||||
private String street;
|
|
||||||
private String subDistrict;
|
|
||||||
private String vtc;
|
|
||||||
private Bitmap image;
|
|
||||||
private String email;
|
|
||||||
private String mobile;
|
|
||||||
private String signature;
|
|
||||||
|
|
||||||
public void setUuid(String aUuid){ name = aUuid; }
|
|
||||||
public void setName(String aName){ name = aName; }
|
|
||||||
public void setDateOfBirth(String aDateOfBirth){
|
|
||||||
dateOfBirth = aDateOfBirth;
|
|
||||||
}
|
|
||||||
public void setGender(String aGender){
|
|
||||||
gender = aGender;
|
|
||||||
}
|
|
||||||
public void setCareOf(String aCareOf){
|
|
||||||
careOf = aCareOf;
|
|
||||||
}
|
|
||||||
public void setDistrict(String aDistrict){
|
|
||||||
district = aDistrict;
|
|
||||||
}
|
|
||||||
public void setLandmark(String aLandmark){
|
|
||||||
landmark = aLandmark;
|
|
||||||
}
|
|
||||||
public void setHouse(String aHouse){
|
|
||||||
house = aHouse;
|
|
||||||
}
|
|
||||||
public void setLocation(String aLocation){ location = aLocation; }
|
|
||||||
public void setPinCode(String aPinCode){
|
|
||||||
pinCode = aPinCode;
|
|
||||||
}
|
|
||||||
public void setPostOffice(String aPostOffice){
|
|
||||||
postOffice = aPostOffice;
|
|
||||||
}
|
|
||||||
public void setState(String aState){
|
|
||||||
state = aState;
|
|
||||||
}
|
|
||||||
public void setStreet(String aStreet){
|
|
||||||
street = aStreet;
|
|
||||||
}
|
|
||||||
public void setSubDistrict(String aSubDistrict){
|
|
||||||
subDistrict = aSubDistrict;
|
|
||||||
}
|
|
||||||
public void setVtc(String aVtc){
|
|
||||||
vtc = aVtc;
|
|
||||||
}
|
|
||||||
public void setImage(Bitmap aImage){
|
|
||||||
image = aImage;
|
|
||||||
}
|
|
||||||
public void setEmail(String aEmail){
|
|
||||||
email = aEmail;
|
|
||||||
}
|
|
||||||
public void setMobile(String aMobile){
|
|
||||||
mobile = aMobile;
|
|
||||||
}
|
|
||||||
public void setSignature(String aSignature){
|
|
||||||
signature = aSignature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AadharCard(){
|
|
||||||
uuid = "";
|
|
||||||
name = "";
|
|
||||||
dateOfBirth = "";
|
|
||||||
gender = "";
|
|
||||||
careOf = "";
|
|
||||||
district = "";
|
|
||||||
landmark = "";
|
|
||||||
house = "";
|
|
||||||
location = "";
|
|
||||||
pinCode = "";
|
|
||||||
postOffice = "";
|
|
||||||
state = "";
|
|
||||||
street = "";
|
|
||||||
subDistrict = "";
|
|
||||||
vtc = "";
|
|
||||||
email = "";
|
|
||||||
mobile = "";
|
|
||||||
signature = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUuid() {
|
|
||||||
return uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDateOfBirth() {
|
|
||||||
return dateOfBirth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGender() {
|
|
||||||
return gender;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCareOf() {
|
|
||||||
return careOf;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDistrict() {
|
|
||||||
return district;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLandmark() {
|
|
||||||
return landmark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHouse() {
|
|
||||||
return house;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPinCode() {
|
|
||||||
return pinCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPostOffice() {
|
|
||||||
return postOffice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStreet() {
|
|
||||||
return street;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSubDistrict() {
|
|
||||||
return subDistrict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVtc() {
|
|
||||||
return vtc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bitmap getImage() {
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEmail() {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMobile() {
|
|
||||||
return mobile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSignature() {
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
package com.example.hpos.data.repository
|
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import com.example.hpos.data.model.Response
|
|
||||||
import com.example.hpos.data.model.PendingUploads
|
|
||||||
import com.example.hpos.data.model.patient.PatientDetails
|
|
||||||
import com.example.hpos.data.model.test.TestDetails
|
|
||||||
import com.google.firebase.firestore.FirebaseFirestore
|
|
||||||
import com.google.firebase.firestore.Query
|
|
||||||
import com.google.firebase.firestore.ktx.firestore
|
|
||||||
import com.google.firebase.ktx.Firebase
|
|
||||||
import com.google.firebase.storage.ktx.storage
|
|
||||||
import kotlinx.coroutines.tasks.await
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class DatabaseRepository : Repository {
|
|
||||||
|
|
||||||
private val db: FirebaseFirestore = Firebase.firestore
|
|
||||||
private val storage = Firebase.storage
|
|
||||||
|
|
||||||
suspend fun addPatientToDatabase(data: PatientDetails) : Response<String> {
|
|
||||||
return try {
|
|
||||||
db.collection("patientData")
|
|
||||||
.document(data.id)
|
|
||||||
.set(data)
|
|
||||||
.await()
|
|
||||||
|
|
||||||
Response.Success(data.id)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Response.Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getAllPatientsFromDatabase(): Response<List<PatientDetails>> {
|
|
||||||
return try {
|
|
||||||
val querySnapshot = db.collection("patientData").get().await()
|
|
||||||
|
|
||||||
val patientList = mutableListOf<PatientDetails>()
|
|
||||||
for (doc in querySnapshot.documents){
|
|
||||||
val patient = doc.toObject(PatientDetails::class.java)
|
|
||||||
patient?.let {
|
|
||||||
patientList.add(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Response.Success(patientList)
|
|
||||||
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Response.Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun addTestToDatabase(data: TestDetails) : Response<String> {
|
|
||||||
return try {
|
|
||||||
db.collection("testData")
|
|
||||||
.document(data.testID)
|
|
||||||
.set(data)
|
|
||||||
.await()
|
|
||||||
|
|
||||||
Response.Success(data.testID)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Response.Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getAllTestsFromDatabase(): List<TestDetails> {
|
|
||||||
val testList = mutableListOf<TestDetails>()
|
|
||||||
return try {
|
|
||||||
val querySnapshot = db.collection("testData").orderBy("registeredTime", Query.Direction.DESCENDING).get().await()
|
|
||||||
|
|
||||||
for (doc in querySnapshot.documents){
|
|
||||||
val patient = doc.toObject(TestDetails::class.java)
|
|
||||||
patient?.let {
|
|
||||||
testList.add(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Response.Success(testList)
|
|
||||||
testList
|
|
||||||
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
testList
|
|
||||||
// Response.Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun uploadFileToStorage(patientID: String, filePath: String): Response<Boolean> {
|
|
||||||
try {
|
|
||||||
|
|
||||||
val file = Uri.fromFile(File(filePath))
|
|
||||||
val riversRef = storage.reference.child("$patientID/${file.lastPathSegment}")
|
|
||||||
riversRef.putFile(file).await()
|
|
||||||
return Response.Success(true)
|
|
||||||
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
return Response.Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun addToPendingQueue(pendingUploads: PendingUploads): Response<Boolean> {
|
|
||||||
return try {
|
|
||||||
db.collection("pendingUploads")
|
|
||||||
.document(pendingUploads.pendingId)
|
|
||||||
.set(pendingUploads)
|
|
||||||
.await()
|
|
||||||
|
|
||||||
Response.Success(true)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
Response.Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getAllFromPendingQueue(): List<PendingUploads> {
|
|
||||||
val pendingList = mutableListOf<PendingUploads>()
|
|
||||||
return try {
|
|
||||||
val querySnapshot = db.collection("pendingUploads").orderBy("timeAdded").get().await()
|
|
||||||
|
|
||||||
for (doc in querySnapshot.documents){
|
|
||||||
val pendingFile = doc.toObject(PendingUploads::class.java)
|
|
||||||
pendingFile?.let {
|
|
||||||
pendingList.add(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pendingList
|
|
||||||
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
pendingList
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun removeFromPendingQueue(fileName: String): Response<Boolean> {
|
|
||||||
return try {
|
|
||||||
db.collection("pendingUploads")
|
|
||||||
.document(fileName)
|
|
||||||
.delete()
|
|
||||||
.await()
|
|
||||||
|
|
||||||
Response.Success(true)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
Response.Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package com.example.hpos.domain.AadhaarScanner;
|
|
||||||
/**
|
|
||||||
* QrCodeException wraps all the exceptions which occurs while scanning and decoding secure Aadharcard
|
|
||||||
* Qr Code
|
|
||||||
* @author Raj Deol
|
|
||||||
*/
|
|
||||||
public class QrCodeException extends Exception {
|
|
||||||
|
|
||||||
public QrCodeException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public QrCodeException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public QrCodeException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,304 +0,0 @@
|
|||||||
package com.example.hpos.domain.AadhaarScanner;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.example.hpos.data.model.AadharCard;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to decode scanned QRcode
|
|
||||||
*/
|
|
||||||
public class SecureQrCode {
|
|
||||||
protected Context mContext;
|
|
||||||
protected static final byte SEPARATOR_BYTE = (byte)255;
|
|
||||||
protected static final int REFERENCE_ID_INDEX = 1,
|
|
||||||
NAME_INDEX = 2,
|
|
||||||
DATE_OF_BIRTH_INDEX = 3,
|
|
||||||
GENDER_INDEX = 4,
|
|
||||||
CARE_OF_INDEX = 5,
|
|
||||||
DISTRICT_INDEX = 6,
|
|
||||||
LANDMARK_INDEX = 7,
|
|
||||||
HOUSE_INDEX = 8,
|
|
||||||
LOCATION_INDEX = 9,
|
|
||||||
PIN_CODE_INDEX = 10,
|
|
||||||
POST_OFFICE_INDEX = 11,
|
|
||||||
STATE_INDEX = 12,
|
|
||||||
STREET_INDEX = 13,
|
|
||||||
SUB_DISTRICT_INDEX = 14,
|
|
||||||
VTC_INDEX = 15;
|
|
||||||
protected int emailMobilePresent, imageStartIndex, imageEndIndex;
|
|
||||||
protected ArrayList<String> decodedData;
|
|
||||||
protected String signature,email,mobile;
|
|
||||||
protected AadharCard scannedAadharCard;
|
|
||||||
|
|
||||||
public SecureQrCode(Context activity, String scanData) throws QrCodeException{
|
|
||||||
mContext = activity;
|
|
||||||
scannedAadharCard = new AadharCard();
|
|
||||||
|
|
||||||
// 1. Convert Base10 to BigInt
|
|
||||||
final BigInteger bigIntScanData = new BigInteger(scanData,10);
|
|
||||||
|
|
||||||
// 2. Convert BigInt to Byte Array
|
|
||||||
final byte byteScanData[] = bigIntScanData.toByteArray();
|
|
||||||
|
|
||||||
// 3. Decompress Byte Array
|
|
||||||
final byte[] decompByteScanData = decompressData(byteScanData);
|
|
||||||
|
|
||||||
// 4. Split the byte array using delimiter
|
|
||||||
List<byte[]> parts = separateData(decompByteScanData);
|
|
||||||
// Throw error if there are no parts
|
|
||||||
if(parts.size() == 0){
|
|
||||||
throw new QrCodeException("Invalid QR Code Data, no parts found after splitting by delimiter");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. decode extracted data to string
|
|
||||||
decodeData(parts);
|
|
||||||
|
|
||||||
// 6. Extract Signature
|
|
||||||
decodeSignature(decompByteScanData);
|
|
||||||
|
|
||||||
// 7. Email and Mobile number
|
|
||||||
decodeMobileEmail(decompByteScanData);
|
|
||||||
|
|
||||||
// 8. Extract Image
|
|
||||||
decodeImage(decompByteScanData);
|
|
||||||
Log.d("Rajdeol","Data Decoded");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decompress the byte array, compression used is GZIP
|
|
||||||
* @param byteScanData compressed byte array
|
|
||||||
* @return uncompressed byte array
|
|
||||||
* @throws QrCodeException
|
|
||||||
*/
|
|
||||||
protected byte[] decompressData(byte[] byteScanData) throws QrCodeException {
|
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(byteScanData.length);
|
|
||||||
ByteArrayInputStream bin = new ByteArrayInputStream(byteScanData);
|
|
||||||
GZIPInputStream gis = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
gis = new GZIPInputStream(bin);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e("Exception", "Decompressing QRcode, Opening byte stream failed: " + e.toString());
|
|
||||||
throw new QrCodeException("Error in opening Gzip byte stream while decompressing QRcode",e);
|
|
||||||
}
|
|
||||||
|
|
||||||
int size = 0;
|
|
||||||
byte[] buf = new byte[1024];
|
|
||||||
while (size >= 0) {
|
|
||||||
try {
|
|
||||||
size = gis.read(buf,0,buf.length);
|
|
||||||
if(size > 0){
|
|
||||||
bos.write(buf,0,size);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e("Exception", "Decompressing QRcode, writing byte stream failed: " + e.toString());
|
|
||||||
throw new QrCodeException("Error in writing byte stream while decompressing QRcode",e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
gis.close();
|
|
||||||
bin.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e("Exception", "Decompressing QRcode, closing byte stream failed: " + e.toString());
|
|
||||||
throw new QrCodeException("Error in closing byte stream while decompressing QRcode",e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bos.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to split byte array with delimiter
|
|
||||||
* @param source source byte array
|
|
||||||
* @return list of separated byte arrays
|
|
||||||
*/
|
|
||||||
protected List<byte[]> separateData(byte[] source) {
|
|
||||||
List<byte[]> separatedParts = new LinkedList<>();
|
|
||||||
int begin = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < source.length; i++) {
|
|
||||||
if(source[i] == SEPARATOR_BYTE){
|
|
||||||
// skip if first or last byte is separator
|
|
||||||
if(i != 0 && i != (source.length -1)){
|
|
||||||
separatedParts.add(Arrays.copyOfRange(source, begin, i));
|
|
||||||
}
|
|
||||||
begin = i + 1;
|
|
||||||
// check if we have got all the parts of text data
|
|
||||||
if(separatedParts.size() == (VTC_INDEX + 1)){
|
|
||||||
// this is required to extract image data
|
|
||||||
imageStartIndex = begin;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return separatedParts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* function to decode string values
|
|
||||||
* @param encodedData
|
|
||||||
* @throws QrCodeException
|
|
||||||
*/
|
|
||||||
protected void decodeData(List<byte[]> encodedData) throws QrCodeException{
|
|
||||||
Iterator<byte[]> i = encodedData.iterator();
|
|
||||||
decodedData = new ArrayList<String>();
|
|
||||||
while(i.hasNext()){
|
|
||||||
try {
|
|
||||||
decodedData.add(new String(i.next(), "ISO-8859-1"));
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
Log.e("Exception", "Decoding QRcode, ISO-8859-1 not supported: " + e.toString());
|
|
||||||
throw new QrCodeException("Decoding QRcode, ISO-8859-1 not supported",e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// set the value of email/mobile present flag
|
|
||||||
emailMobilePresent = Integer.parseInt(decodedData.get(0));
|
|
||||||
|
|
||||||
// populate decoded data
|
|
||||||
scannedAadharCard.setName(decodedData.get(2));
|
|
||||||
scannedAadharCard.setDateOfBirth(decodedData.get(3));
|
|
||||||
scannedAadharCard.setGender(decodedData.get(4));
|
|
||||||
scannedAadharCard.setCareOf(decodedData.get(5));
|
|
||||||
scannedAadharCard.setDistrict(decodedData.get(6));
|
|
||||||
scannedAadharCard.setLandmark(decodedData.get(7));
|
|
||||||
scannedAadharCard.setHouse(decodedData.get(8));
|
|
||||||
scannedAadharCard.setLocation(decodedData.get(9));
|
|
||||||
scannedAadharCard.setPinCode(decodedData.get(10));
|
|
||||||
scannedAadharCard.setPostOffice(decodedData.get(11));
|
|
||||||
scannedAadharCard.setState(decodedData.get(12));
|
|
||||||
scannedAadharCard.setStreet(decodedData.get(13));
|
|
||||||
scannedAadharCard.setSubDistrict(decodedData.get(14));
|
|
||||||
scannedAadharCard.setVtc(decodedData.get(15));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ref : https://uidai.gov.in/2-uncategorised/11320-aadhaar-paperless-offline-e-kyc-3.html
|
|
||||||
* Hashing logic for Email ID :
|
|
||||||
* Sha256(Sha256(Email+SharePhrase))*number of times last digit of Aadhaar number
|
|
||||||
* (Ref ID field contains last 4 digits).
|
|
||||||
*
|
|
||||||
* Example :
|
|
||||||
* Email: abc@gm.com
|
|
||||||
* Aadhaar Number:XXXX XXXX 3632
|
|
||||||
* Passcode : Lock@487
|
|
||||||
* Hash : Sha256(Sha256(abc@gm.comLock@487))*2
|
|
||||||
* In case of Aadhaar number ends with Zero we will hashed one time.
|
|
||||||
* **********************************************************************
|
|
||||||
* **********************************************************************
|
|
||||||
* Hashing logic for Mobile Number :
|
|
||||||
* Sha256(Sha256(Mobile+SharePhrase))*number of times last digit of Aadhaar number
|
|
||||||
* (Ref ID field contains last 4 digits).
|
|
||||||
*
|
|
||||||
* Example :
|
|
||||||
* Mobile: 1234567890
|
|
||||||
* Aadhaar Number:XXXX XXXX 3632
|
|
||||||
* Passcode : Lock@487
|
|
||||||
* Hash: Sha256(Sha256(1234567890Lock@487))*2
|
|
||||||
* In case of Aadhaar number ends with Zero we will hashed one time.
|
|
||||||
* @param decompressedData
|
|
||||||
* @throws QrCodeException
|
|
||||||
*/
|
|
||||||
|
|
||||||
protected void decodeMobileEmail(byte[] decompressedData) throws QrCodeException{
|
|
||||||
int mobileStartIndex = 0,mobileEndIndex = 0,emailStartIndex = 0,emailEndIndex = 0;
|
|
||||||
switch (emailMobilePresent){
|
|
||||||
case 3:
|
|
||||||
// both email mobile present
|
|
||||||
mobileStartIndex = decompressedData.length - 289; // length -1 -256 -32
|
|
||||||
mobileEndIndex = decompressedData.length - 257; // length -1 -256
|
|
||||||
emailStartIndex = decompressedData.length - 322;// length -1 -256 -32 -1 -32
|
|
||||||
emailEndIndex = decompressedData.length - 290;// length -1 -256 -32 -1
|
|
||||||
|
|
||||||
mobile = bytesToHex (Arrays.copyOfRange(decompressedData,mobileStartIndex,mobileEndIndex+1));
|
|
||||||
email = bytesToHex (Arrays.copyOfRange(decompressedData,emailStartIndex,emailEndIndex+1));
|
|
||||||
// set image end index, it will be used to extract image data
|
|
||||||
imageEndIndex = decompressedData.length - 323;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
// only mobile
|
|
||||||
email = "";
|
|
||||||
mobileStartIndex = decompressedData.length - 289; // length -1 -256 -32
|
|
||||||
mobileEndIndex = decompressedData.length - 257; // length -1 -256
|
|
||||||
|
|
||||||
mobile = bytesToHex (Arrays.copyOfRange(decompressedData,mobileStartIndex,mobileEndIndex+1));
|
|
||||||
// set image end index, it will be used to extract image data
|
|
||||||
imageEndIndex = decompressedData.length - 290;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
// only email
|
|
||||||
mobile = "";
|
|
||||||
emailStartIndex = decompressedData.length - 289; // length -1 -256 -32
|
|
||||||
emailEndIndex = decompressedData.length - 257; // length -1 -256
|
|
||||||
|
|
||||||
email = bytesToHex (Arrays.copyOfRange(decompressedData,emailStartIndex,emailEndIndex+1));
|
|
||||||
// set image end index, it will be used to extract image data
|
|
||||||
imageEndIndex = decompressedData.length - 290;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// no mobile or email
|
|
||||||
mobile = "";
|
|
||||||
email = "";
|
|
||||||
// set image end index, it will be used to extract image data
|
|
||||||
imageEndIndex = decompressedData.length - 257;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void decodeImage(byte[] decompressedData) throws QrCodeException{
|
|
||||||
// image start and end indexes are calculated in functions : separateData and decodeMobileEmail
|
|
||||||
byte[] imageBytes = Arrays.copyOfRange(decompressedData,imageStartIndex,imageEndIndex+1);
|
|
||||||
|
|
||||||
// Bitmap bmp = new JP2Decoder(imageBytes).decode();
|
|
||||||
// scannedAadharCard.setImage(bmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void decodeSignature(byte[] decompressedData) throws QrCodeException{
|
|
||||||
// extract 256 bytes from the end of the byte array
|
|
||||||
int startIndex = decompressedData.length - 257,
|
|
||||||
noOfBytes = 256;
|
|
||||||
try {
|
|
||||||
signature = new String (decompressedData,startIndex,noOfBytes,"ISO-8859-1");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
Log.e("Exception", "Decoding Signature of QRcode, ISO-8859-1 not supported: " + e.toString());
|
|
||||||
throw new QrCodeException("Decoding Signature of QRcode, ISO-8859-1 not supported",e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public AadharCard getScannedAadharCard(){
|
|
||||||
return scannedAadharCard;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert byte array to hex string
|
|
||||||
* @param bytes
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String bytesToHex(byte[] bytes) {
|
|
||||||
final char[] hexArray = "0123456789ABCDEF".toCharArray();
|
|
||||||
|
|
||||||
char[] hexChars = new char[bytes.length * 2];
|
|
||||||
for ( int j = 0; j < bytes.length; j++ ) {
|
|
||||||
int v = bytes[j] & 0xFF;
|
|
||||||
hexChars[j * 2] = hexArray[v >>> 4];
|
|
||||||
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
|
||||||
}
|
|
||||||
return new String(hexChars);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
package com.example.hpos.presentation
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.IntentFilter
|
|
||||||
import android.hardware.usb.UsbManager
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.Menu
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.core.view.get
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import com.example.hpos.R
|
|
||||||
import com.example.hpos.data.DataHolder
|
|
||||||
import com.example.hpos.data.constant.Constants
|
|
||||||
import com.example.hpos.data.model.test.TestType
|
|
||||||
import com.example.hpos.databinding.ActivityMainBinding
|
|
||||||
import com.example.hpos.util.MyViewModelFactory
|
|
||||||
import com.hoho.android.usbserial.driver.UsbSerialProber
|
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
|
||||||
|
|
||||||
private lateinit var binding: ActivityMainBinding
|
|
||||||
private lateinit var viewModel: MainViewModel
|
|
||||||
|
|
||||||
private var myMenu: Menu? = null
|
|
||||||
|
|
||||||
private val TAG = "MainActivity"
|
|
||||||
|
|
||||||
private var mUsbReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
|
||||||
override fun onReceive(context: Context?, intent: Intent) {
|
|
||||||
val action = intent.action
|
|
||||||
if (UsbManager.ACTION_USB_DEVICE_DETACHED == action) {
|
|
||||||
DataHolder.usbConnected.value = false
|
|
||||||
// Toast.makeText(context, "Detached", Toast.LENGTH_SHORT).show()
|
|
||||||
} else if (UsbManager.ACTION_USB_DEVICE_ATTACHED == action) {
|
|
||||||
DataHolder.usbConnected.value = true
|
|
||||||
// Toast.makeText(context, "Attached", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
|
||||||
viewModel = ViewModelProvider(
|
|
||||||
this,
|
|
||||||
MyViewModelFactory()
|
|
||||||
)[MainViewModel::class.java]
|
|
||||||
|
|
||||||
setSupportActionBar(binding.myToolbar)
|
|
||||||
// supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
|
||||||
|
|
||||||
setupListeners()
|
|
||||||
|
|
||||||
val filter = IntentFilter()
|
|
||||||
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
|
|
||||||
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
|
|
||||||
registerReceiver(mUsbReceiver, filter)
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkAndUpdateUsbConnection() {
|
|
||||||
val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(getSystemService(Context.USB_SERVICE) as UsbManager)
|
|
||||||
if (availableDrivers.isNotEmpty() && availableDrivers[0].device.productId == Constants.DEVICE_PRODUCT_ID && availableDrivers[0].device.vendorId == Constants.DEVICE_VENDOR_ID){
|
|
||||||
Log.d(TAG, "Device matched -> product = ${availableDrivers[0].device.productId}, vendor = ${availableDrivers[0].device.vendorId}")
|
|
||||||
DataHolder.usbConnected.value = true
|
|
||||||
} else if (availableDrivers.isNotEmpty()) {
|
|
||||||
Log.d(TAG, "Device NOT matched -> product = ${availableDrivers[0].device.productId}, vendor = ${availableDrivers[0].device.vendorId}")
|
|
||||||
Toast.makeText(this, "Device Not Compatible", Toast.LENGTH_SHORT).show()
|
|
||||||
DataHolder.usbConnected.value = false
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Device NOT Connected")
|
|
||||||
DataHolder.usbConnected.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupListeners() {
|
|
||||||
|
|
||||||
binding.cvItem1.setOnClickListener {
|
|
||||||
DataHolder.selectedTestType = TestType.SICKLECERT
|
|
||||||
|
|
||||||
// val i = Intent(applicationContext, TestRightActivity::class.java)
|
|
||||||
// startActivity(i)
|
|
||||||
val i = Intent(applicationContext, KitScanActivity::class.java)
|
|
||||||
startActivity(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.cvItem2.setOnClickListener {
|
|
||||||
DataHolder.selectedTestType = TestType.SICKLEFIND
|
|
||||||
// val i = Intent(applicationContext, TestRightActivity::class.java)
|
|
||||||
// startActivity(i)
|
|
||||||
val i = Intent(applicationContext, KitScanActivity::class.java)
|
|
||||||
startActivity(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
DataHolder.usbConnected.observe(this){
|
|
||||||
// Log.d(TAG, "usbConnected observer called with value -> $it")
|
|
||||||
if (it){
|
|
||||||
myMenu?.get(0)?.icon = ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24)
|
|
||||||
} else {
|
|
||||||
// Log.d(TAG, "into no block -> $it")
|
|
||||||
myMenu?.get(0)?.icon = ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// binding.cvItem3.setOnClickListener {
|
|
||||||
// val i = Intent(applicationContext, TestRightActivity::class.java)
|
|
||||||
// startActivity(i)
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
|
||||||
menuInflater.inflate(R.menu.my_menu, menu)
|
|
||||||
myMenu = menu
|
|
||||||
// Todo: Uncomment this
|
|
||||||
checkAndUpdateUsbConnection()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
package com.example.hpos.presentation
|
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.RadioButton
|
|
||||||
import android.widget.RadioGroup
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import com.example.hpos.R
|
|
||||||
import com.example.hpos.data.model.test.Status
|
|
||||||
import com.example.hpos.data.model.test.TestDetails
|
|
||||||
import com.example.hpos.presentation.dashboard.ItemClickListener
|
|
||||||
|
|
||||||
|
|
||||||
class RVAdapter : RecyclerView.Adapter<RVAdapter.ViewHolder>() {
|
|
||||||
|
|
||||||
// private lateinit var binding: TableItemBinding
|
|
||||||
private val dataset = ArrayList<TestDetails>()
|
|
||||||
|
|
||||||
var itemClickListener: ItemClickListener? = null
|
|
||||||
companion object {var selectedPosition = -1}
|
|
||||||
|
|
||||||
// private var lastChecked: CheckBox? = null
|
|
||||||
// private var lastCheckedPos = 0
|
|
||||||
|
|
||||||
// This keeps track of the currently selected position
|
|
||||||
// var selectedPosition by Delegates.observable(-1) { property, oldPos, newPos ->
|
|
||||||
// if (newPos in dataset.indices) {
|
|
||||||
// notifyItemChanged(oldPos)
|
|
||||||
// notifyItemChanged(newPos)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
|
||||||
val tvId: TextView
|
|
||||||
val tvName: TextView
|
|
||||||
val tvStatus: TextView
|
|
||||||
val radioButton: RadioButton
|
|
||||||
val radioGroup: RadioGroup
|
|
||||||
|
|
||||||
init {
|
|
||||||
tvId = view.findViewById(R.id.tv_id)
|
|
||||||
tvName = view.findViewById(R.id.tv_name)
|
|
||||||
tvStatus = view.findViewById(R.id.tv_status)
|
|
||||||
radioButton = view.findViewById(R.id.radioButton)
|
|
||||||
radioGroup = view.findViewById(R.id.radio_group)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
|
||||||
val view = LayoutInflater.from(parent.context)
|
|
||||||
.inflate(R.layout.table_item, parent, false)
|
|
||||||
|
|
||||||
return ViewHolder(view)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
||||||
Log.d("RVAdapter", "onBindViewHolder called() : pos = ${position}")
|
|
||||||
val idString = "ID: " + dataset[position].patientID
|
|
||||||
holder.tvId.text = idString
|
|
||||||
holder.tvName.text = dataset[position].patientName
|
|
||||||
holder.tvStatus.text = dataset[position].testStatus.toString()
|
|
||||||
|
|
||||||
holder.radioGroup.clearCheck()
|
|
||||||
if (dataset[position].testStatus == Status.PENDING) {
|
|
||||||
holder.radioButton.isChecked = (position == selectedPosition)
|
|
||||||
} else {
|
|
||||||
holder.radioButton.isEnabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.radioButton.setOnCheckedChangeListener { compoundButton, b ->
|
|
||||||
Log.d("RVAdapter", "setOnCheckedChangeListener called() : pos = ${position}")
|
|
||||||
// check condition
|
|
||||||
if (b) {
|
|
||||||
Log.d("RVAdapter", "setOnCheckedChangeListener called() -> b true : pos = ${position}")
|
|
||||||
// When checked update selected position
|
|
||||||
selectedPosition = holder.adapterPosition
|
|
||||||
itemClickListener!!.onClick(position)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
|
||||||
return dataset.size
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateDataSet(newDataSet: ArrayList<TestDetails>) {
|
|
||||||
dataset.clear()
|
|
||||||
dataset.addAll(newDataSet)
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// inner class ViewHolder(itemView: TableItemBinding) : RecyclerView.ViewHolder(itemView.root) {
|
|
||||||
// fun bind(item : TestDetails){
|
|
||||||
// binding.apply {
|
|
||||||
// tvId.text = item.patientID
|
|
||||||
// tvName.text = item.patientName
|
|
||||||
// tvStatus.text = item.testStatus.toString()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
|
||||||
// val inflater =LayoutInflater.from(parent.context)
|
|
||||||
// binding = TableItemBinding.inflate(inflater,parent,false)
|
|
||||||
// return ViewHolder(binding)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
||||||
// holder.bind(dataset[position])
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun getItemCount(): Int {
|
|
||||||
// return dataset.size
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fun updateDataSet(newDataSet: ArrayList<TestDetails>) {
|
|
||||||
// dataset.clear()
|
|
||||||
// dataset.addAll(newDataSet)
|
|
||||||
// notifyDataSetChanged()
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,255 +0,0 @@
|
|||||||
package com.example.hpos.presentation
|
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.os.Environment
|
|
||||||
import android.provider.Settings
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import com.example.hpos.MyApplication
|
|
||||||
import com.example.hpos.data.DataHolder
|
|
||||||
import com.example.hpos.data.FileUploader
|
|
||||||
import com.example.hpos.databinding.ActivitySplashBinding
|
|
||||||
import com.example.hpos.presentation.dashboard.DashboardActivity
|
|
||||||
import com.example.hpos.util.MyUtils
|
|
||||||
import com.google.firebase.firestore.FirebaseFirestoreSettings
|
|
||||||
import com.google.firebase.firestore.ktx.firestore
|
|
||||||
import com.google.firebase.ktx.Firebase
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Splash Activity
|
|
||||||
* Used for preprocessing of data, permissions
|
|
||||||
*/
|
|
||||||
class SplashActivity : AppCompatActivity() {
|
|
||||||
|
|
||||||
private val MY_CAMERA_REQUEST_CODE: Int = 100
|
|
||||||
private lateinit var binding: ActivitySplashBinding
|
|
||||||
var permissionStorage = false
|
|
||||||
var permissionLocation = false
|
|
||||||
var permissionLocation2 = false
|
|
||||||
var permissionCamera = false
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
binding = ActivitySplashBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
|
||||||
|
|
||||||
setupFirestoreCache()
|
|
||||||
|
|
||||||
checkForStoragePermissions()
|
|
||||||
checkForLocationPermission()
|
|
||||||
checkForLocationPermission2()
|
|
||||||
// Keep this in last permission check, as checking all given or not after this
|
|
||||||
checkForCameraPermission()
|
|
||||||
|
|
||||||
// Log.d("surya_permission", "passed first")
|
|
||||||
checkAllPermissionsGiven()
|
|
||||||
|
|
||||||
setupStaticConstants()
|
|
||||||
|
|
||||||
startWorker()
|
|
||||||
|
|
||||||
// GlobalScope.launch(Dispatchers.IO) {
|
|
||||||
// FileUploader().uploadFiles(listOf())
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startWorker() {
|
|
||||||
if (MyUtils.isInternetConnected()) {
|
|
||||||
(applicationContext as MyApplication).applicationScope.launch(Dispatchers.IO) {
|
|
||||||
FileUploader().start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupStaticConstants() {
|
|
||||||
DataHolder.mobileUniqueId = Settings.Secure.getString(applicationContext.contentResolver, Settings.Secure.ANDROID_ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupFirestoreCache() {
|
|
||||||
val settings = FirebaseFirestoreSettings.Builder()
|
|
||||||
.setCacheSizeBytes(FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED)
|
|
||||||
.build()
|
|
||||||
Firebase.firestore.firestoreSettings = settings
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkAllPermissionsGiven() {
|
|
||||||
// Log.d("surya_permission", "inside checkAllPermissionsGiven")
|
|
||||||
if (permissionStorage && permissionCamera && permissionLocation && permissionLocation2)
|
|
||||||
moveToLandingPage()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkForStoragePermissions() {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
||||||
getPermissionsAboveAndroidR()
|
|
||||||
} else {
|
|
||||||
getPermissionsBelowAndroidR()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.R)
|
|
||||||
private fun getPermissionsAboveAndroidR() {
|
|
||||||
// Checking if permission is already granted or not.
|
|
||||||
if (!Environment.isExternalStorageManager()) {
|
|
||||||
val storagePermissionResultLauncher =
|
|
||||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
|
||||||
if (Environment.isExternalStorageManager()) {
|
|
||||||
DataHolder.isStoragePermissionGranted = true
|
|
||||||
// moveToLandingPage()
|
|
||||||
permissionStorage = true
|
|
||||||
} else {
|
|
||||||
DataHolder.isStoragePermissionGranted = false
|
|
||||||
Toast.makeText(
|
|
||||||
this,
|
|
||||||
"You must grant permission to storage to use the app",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val intent = Intent()
|
|
||||||
intent.action = Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
|
|
||||||
intent.data = Uri.fromParts("package", this.packageName, null)
|
|
||||||
storagePermissionResultLauncher.launch(intent)
|
|
||||||
} else {
|
|
||||||
DataHolder.isStoragePermissionGranted = true
|
|
||||||
// moveToLandingPage()
|
|
||||||
permissionStorage = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getPermissionsBelowAndroidR() {
|
|
||||||
val requestPermissionLauncher =
|
|
||||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
|
|
||||||
if (isGranted) {
|
|
||||||
DataHolder.isStoragePermissionGranted = true
|
|
||||||
// moveToLandingPage()
|
|
||||||
permissionStorage = true
|
|
||||||
} else {
|
|
||||||
DataHolder.isStoragePermissionGranted = false
|
|
||||||
Toast.makeText(
|
|
||||||
this,
|
|
||||||
"You must grant permission to storage to use the app",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ContextCompat.checkSelfPermission(
|
|
||||||
this,
|
|
||||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
|
||||||
) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(
|
|
||||||
this,
|
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
|
||||||
) != PackageManager.PERMISSION_GRANTED
|
|
||||||
) {
|
|
||||||
requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
|
||||||
} else {
|
|
||||||
DataHolder.isStoragePermissionGranted = true
|
|
||||||
// moveToLandingPage()
|
|
||||||
permissionStorage = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkForCameraPermission() {
|
|
||||||
if (ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.CAMERA)
|
|
||||||
== PackageManager.PERMISSION_DENIED
|
|
||||||
) {
|
|
||||||
val requestPermissionLauncher =
|
|
||||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
|
|
||||||
if (isGranted) {
|
|
||||||
permissionCamera = true
|
|
||||||
checkAllPermissionsGiven()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
this,
|
|
||||||
"You must grant permission to Camera to use the app",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requestPermissionLauncher.launch(Manifest.permission.CAMERA)
|
|
||||||
} else {
|
|
||||||
permissionCamera = true
|
|
||||||
checkAllPermissionsGiven()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkForLocationPermission() {
|
|
||||||
if (ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.ACCESS_COARSE_LOCATION)
|
|
||||||
== PackageManager.PERMISSION_DENIED
|
|
||||||
) {
|
|
||||||
val requestPermissionLauncher =
|
|
||||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
|
|
||||||
if (isGranted) {
|
|
||||||
permissionLocation = true
|
|
||||||
checkAllPermissionsGiven()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
this,
|
|
||||||
"You must grant permission to Location to use the app",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requestPermissionLauncher.launch(Manifest.permission.ACCESS_COARSE_LOCATION)
|
|
||||||
} else {
|
|
||||||
permissionLocation = true
|
|
||||||
checkAllPermissionsGiven()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkForLocationPermission2() {
|
|
||||||
if (ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.ACCESS_FINE_LOCATION)
|
|
||||||
== PackageManager.PERMISSION_DENIED
|
|
||||||
) {
|
|
||||||
val requestPermissionLauncher =
|
|
||||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
|
|
||||||
if (isGranted) {
|
|
||||||
permissionLocation2 = true
|
|
||||||
checkAllPermissionsGiven()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
this,
|
|
||||||
"You must grant permission to Location to use the app",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requestPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
|
|
||||||
} else {
|
|
||||||
permissionLocation2 = true
|
|
||||||
checkAllPermissionsGiven()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun moveToLandingPage() {
|
|
||||||
createAppFolder()
|
|
||||||
// val i = Intent(applicationContext, MainActivity::class.java)
|
|
||||||
val i = Intent(applicationContext, DashboardActivity::class.java)
|
|
||||||
startActivity(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createAppFolder() {
|
|
||||||
val folderPath = MyUtils.createAppFolder(applicationContext)
|
|
||||||
if (folderPath != null) {
|
|
||||||
DataHolder.isAppFolderCreated = true
|
|
||||||
DataHolder.appFolderPath = folderPath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
package com.example.hpos.presentation.dashboard
|
|
||||||
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import com.example.hpos.BuildConfig
|
|
||||||
import com.example.hpos.data.DataHolder
|
|
||||||
import com.example.hpos.data.repository.DatabaseRepository
|
|
||||||
import com.example.hpos.data.model.Response
|
|
||||||
import com.example.hpos.data.model.AadharCard
|
|
||||||
import com.example.hpos.data.model.Location
|
|
||||||
import com.example.hpos.data.model.patient.PatientDetails
|
|
||||||
import com.example.hpos.data.model.test.Status
|
|
||||||
import com.example.hpos.data.model.test.TestDetails
|
|
||||||
import com.example.hpos.util.MyUtils
|
|
||||||
import com.example.hpos.util.MyUtils.fetchYOBFromDOB
|
|
||||||
import com.example.hpos.util.MyUtils.mapToGender
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import java.util.Calendar
|
|
||||||
|
|
||||||
//class DashboardViewModel(val repository: DatabaseRepository) : ViewModel() {
|
|
||||||
class DashboardViewModel() : ViewModel() {
|
|
||||||
|
|
||||||
private val TAG = "DashboardViewModel"
|
|
||||||
lateinit var aadharCard: AadharCard
|
|
||||||
lateinit var patientDetails: PatientDetails
|
|
||||||
lateinit var testDetails: TestDetails
|
|
||||||
var deviceLocation = Location(null, null)
|
|
||||||
|
|
||||||
val repository = DatabaseRepository()
|
|
||||||
|
|
||||||
val dataUploadStatus = MutableLiveData<Response<String>>()
|
|
||||||
// val allTestDetails = MutableLiveData<Response<List<TestDetails>>>()
|
|
||||||
val allTestDetails = MutableLiveData<List<TestDetails>>()
|
|
||||||
|
|
||||||
var temp = 1
|
|
||||||
|
|
||||||
|
|
||||||
fun initializePatientDetails(patient: PatientDetails) {
|
|
||||||
patientDetails = patient
|
|
||||||
}
|
|
||||||
|
|
||||||
fun mapAadhaarDataToPatient() {
|
|
||||||
if (patientDetails.name.isNullOrEmpty())
|
|
||||||
patientDetails.name = aadharCard.name
|
|
||||||
if (patientDetails.yob == null)
|
|
||||||
patientDetails.yob = aadharCard.dateOfBirth.fetchYOBFromDOB()
|
|
||||||
if (patientDetails.gender == null)
|
|
||||||
patientDetails.gender = aadharCard.gender.mapToGender()
|
|
||||||
if (patientDetails.mobile.isNullOrEmpty())
|
|
||||||
patientDetails.mobile = aadharCard.mobile
|
|
||||||
if (patientDetails.careOf.isNullOrEmpty())
|
|
||||||
patientDetails.careOf = aadharCard.careOf
|
|
||||||
|
|
||||||
if (patientDetails.address == null) {
|
|
||||||
patientDetails.address = PatientDetails.Address()
|
|
||||||
patientDetails.address?.house = aadharCard.house
|
|
||||||
patientDetails.address?.city = aadharCard.location
|
|
||||||
patientDetails.address?.postOffice = aadharCard.postOffice
|
|
||||||
patientDetails.address?.district = aadharCard.district
|
|
||||||
patientDetails.address?.state = aadharCard.state
|
|
||||||
patientDetails.address?.pinCode = aadharCard.pinCode.toInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun createTest() {
|
|
||||||
val mTestId = MyUtils.generateTestIdForPatient(patientDetails.id)
|
|
||||||
|
|
||||||
testDetails = TestDetails(
|
|
||||||
testID = mTestId,
|
|
||||||
testStatus = Status.PENDING,
|
|
||||||
patientID = patientDetails.id,
|
|
||||||
patientName = patientDetails.name!!,
|
|
||||||
patientAge = patientDetails.yob,
|
|
||||||
resultRatio = null,
|
|
||||||
result = null,
|
|
||||||
reportPath = null,
|
|
||||||
csvPath = null,
|
|
||||||
logPath = null,
|
|
||||||
deviceId = null,
|
|
||||||
mobileId = DataHolder.mobileUniqueId!!,
|
|
||||||
kitSerial = null,
|
|
||||||
location = deviceLocation,
|
|
||||||
appVersion = BuildConfig.VERSION_CODE.toString(),
|
|
||||||
registeredTime = Calendar.getInstance().time,
|
|
||||||
uploadTime = Calendar.getInstance().time
|
|
||||||
)
|
|
||||||
|
|
||||||
pushTestDetailsToDb()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------- Cloud Actions ------------------------------------------
|
|
||||||
|
|
||||||
fun pushPatientDetailsToDb() {
|
|
||||||
patientDetails.uploadDate = Calendar.getInstance().time
|
|
||||||
|
|
||||||
viewModelScope.launch {
|
|
||||||
val response = repository.addPatientToDatabase(patientDetails)
|
|
||||||
dataUploadStatus.value = response
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun pushTestDetailsToDb() {
|
|
||||||
testDetails.uploadTime = Calendar.getInstance().time
|
|
||||||
|
|
||||||
viewModelScope.launch {
|
|
||||||
val response = repository.addTestToDatabase(testDetails)
|
|
||||||
dataUploadStatus.value = response
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fetchAllTestData() {
|
|
||||||
viewModelScope.launch {
|
|
||||||
val response = repository.getAllTestsFromDatabase()
|
|
||||||
allTestDetails.postValue(response)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
package com.example.hpos.presentation.dashboard
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.activityViewModels
|
|
||||||
import androidx.navigation.fragment.findNavController
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
|
|
||||||
import com.example.hpos.R
|
|
||||||
import com.example.hpos.data.DataHolder
|
|
||||||
import com.example.hpos.data.model.patient.PatientDetails
|
|
||||||
import com.example.hpos.databinding.FragmentHomeBinding
|
|
||||||
import com.example.hpos.presentation.RVAdapter
|
|
||||||
import com.example.hpos.presentation.RecyclerViewAdapter
|
|
||||||
|
|
||||||
class HomeFragment : Fragment() {
|
|
||||||
|
|
||||||
val TAG = "HomeFragment"
|
|
||||||
private var _binding: FragmentHomeBinding? = null
|
|
||||||
private val binding get() = _binding!!
|
|
||||||
private val viewModel: DashboardViewModel by activityViewModels()
|
|
||||||
// private val viewModel: DashboardViewModel by activityViewModels{ MyViewModelFactory() }
|
|
||||||
|
|
||||||
// private lateinit var rvAdapter: RVAdapter
|
|
||||||
private lateinit var rvAdapter: RecyclerViewAdapter
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
try {
|
|
||||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
|
||||||
|
|
||||||
DataHolder.selectedTest = null
|
|
||||||
rvAdapter = RecyclerViewAdapter()
|
|
||||||
val itemClickListener = object : ItemClickListener {
|
|
||||||
override fun onClick(pos: Int) {
|
|
||||||
Log.d(TAG, "onclick called in ItemClickListener")
|
|
||||||
DataHolder.selectedTest = viewModel.allTestDetails.value?.get(pos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rvAdapter.itemClickListener = itemClickListener
|
|
||||||
|
|
||||||
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
|
||||||
binding.recyclerView.adapter = rvAdapter
|
|
||||||
|
|
||||||
// Toast.makeText(requireActivity(), viewModel.temp, Toast.LENGTH_SHORT).show()
|
|
||||||
// viewModel.temp++
|
|
||||||
// Log.d(TAG, "viewmodel temp = ${viewModel.temp}")
|
|
||||||
|
|
||||||
return binding.root
|
|
||||||
} catch (e: Exception){
|
|
||||||
e.printStackTrace()
|
|
||||||
Log.e(TAG, "onCreateView", e);
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
setupObservers()
|
|
||||||
viewModel.fetchAllTestData()
|
|
||||||
|
|
||||||
binding.btnAdd.setOnClickListener {
|
|
||||||
viewModel.initializePatientDetails(PatientDetails())
|
|
||||||
findNavController().navigate(R.id.action_nav_home_to_registerOneScanAbhaFragment)
|
|
||||||
}
|
|
||||||
binding.btnTest.setOnClickListener {
|
|
||||||
if (DataHolder.selectedTest != null) {
|
|
||||||
findNavController().navigate(R.id.action_nav_home_to_mainActivity)
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
"Select One Record to start testing",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupObservers() {
|
|
||||||
viewModel.allTestDetails.observe(viewLifecycleOwner) {
|
|
||||||
rvAdapter.updateDataSet(ArrayList(it))
|
|
||||||
// when(it) {
|
|
||||||
// is Response.Success -> {
|
|
||||||
// rvAdapter.updateDataSet(ArrayList(it.data))
|
|
||||||
// }
|
|
||||||
// is Response.Error -> {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
package com.example.hpos.presentation.dashboard.register
|
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.activityViewModels
|
|
||||||
import androidx.navigation.fragment.findNavController
|
|
||||||
import com.example.hpos.R
|
|
||||||
import com.example.hpos.data.constant.Constants
|
|
||||||
import com.example.hpos.databinding.FragmentRegisterOneCreateAbhaBinding
|
|
||||||
import com.example.hpos.presentation.dashboard.DashboardViewModel
|
|
||||||
|
|
||||||
|
|
||||||
class RegisterOneCreateAbha : Fragment() {
|
|
||||||
|
|
||||||
private val TAG = "RegisterOneCreateAbha"
|
|
||||||
private lateinit var binding: FragmentRegisterOneCreateAbhaBinding
|
|
||||||
private val viewModel: DashboardViewModel by activityViewModels()
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
binding = FragmentRegisterOneCreateAbhaBinding.inflate(inflater, container, false)
|
|
||||||
return binding.root
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
binding.btnRedirect.setOnClickListener {
|
|
||||||
redirectApp()
|
|
||||||
}
|
|
||||||
binding.tvSkip.setOnClickListener {
|
|
||||||
// Taking to aadhaar page if ABHA is skipped
|
|
||||||
findNavController().navigate(R.id.action_registerOneCreateAbha_to_registerTwoAadhaarFragment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun redirectApp() {
|
|
||||||
val launchIntent: Intent? = requireActivity().packageManager
|
|
||||||
.getLaunchIntentForPackage(Constants.ABHA_APP_PACKAGE)
|
|
||||||
|
|
||||||
if (launchIntent != null) {
|
|
||||||
startActivity(launchIntent)
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=${Constants.ABHA_APP_PACKAGE}")))
|
|
||||||
} catch (e: ActivityNotFoundException) {
|
|
||||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=${Constants.ABHA_APP_PACKAGE}")))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// private fun appInstalledOrNot(uri: String): Boolean {
|
|
||||||
// val pm: PackageManager = requireActivity().packageManager
|
|
||||||
// try {
|
|
||||||
// pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
|
|
||||||
// return true
|
|
||||||
// } catch (e: PackageManager.NameNotFoundException) {
|
|
||||||
// }
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
package com.example.hpos.presentation.dashboard.register
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.FragmentManager
|
|
||||||
import androidx.fragment.app.activityViewModels
|
|
||||||
import androidx.navigation.fragment.findNavController
|
|
||||||
import com.example.hpos.R
|
|
||||||
import com.example.hpos.data.model.patient.PatientDetails
|
|
||||||
import com.example.hpos.databinding.FragmentRegisterOneScanAbhaBinding
|
|
||||||
import com.example.hpos.presentation.dashboard.DashboardViewModel
|
|
||||||
import com.example.hpos.util.MyUtils.fetchYOBFromDOB
|
|
||||||
import com.example.hpos.util.MyUtils.mapToGender
|
|
||||||
import com.google.mlkit.vision.barcode.common.Barcode
|
|
||||||
import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions
|
|
||||||
import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
|
|
||||||
import com.journeyapps.barcodescanner.ScanContract
|
|
||||||
import com.journeyapps.barcodescanner.ScanIntentResult
|
|
||||||
import com.journeyapps.barcodescanner.ScanOptions
|
|
||||||
import org.json.JSONObject
|
|
||||||
|
|
||||||
|
|
||||||
class RegisterOneScanAbhaFragment : Fragment() {
|
|
||||||
|
|
||||||
private val TAG = "RegisterOneScanAbha"
|
|
||||||
private lateinit var binding: FragmentRegisterOneScanAbhaBinding
|
|
||||||
private val viewModel: DashboardViewModel by activityViewModels()
|
|
||||||
|
|
||||||
private val barcodeLauncher = registerForActivityResult(
|
|
||||||
ScanContract()
|
|
||||||
) { result: ScanIntentResult ->
|
|
||||||
if (result.contents == null) {
|
|
||||||
Toast.makeText(requireContext(), "Cancelled: Unable to scan, Try Again!!", Toast.LENGTH_LONG).show()
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, result.contents)
|
|
||||||
processScannedData(result.contents)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
binding = FragmentRegisterOneScanAbhaBinding.inflate(inflater, container, false)
|
|
||||||
return binding.root
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
// Toast.makeText(requireContext(), viewModel.temp, Toast.LENGTH_SHORT).show()
|
|
||||||
viewModel.temp++
|
|
||||||
Log.d(TAG, "viewmodel temp = ${viewModel.temp}")
|
|
||||||
|
|
||||||
binding.btnScanNow.setOnClickListener {
|
|
||||||
startScanningNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.btnGo.setOnClickListener {
|
|
||||||
val abhaID = validateAndReturnId()
|
|
||||||
if (abhaID == null) {
|
|
||||||
Toast.makeText(requireContext(), "Invalid ID Entered", Toast.LENGTH_SHORT).show()
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.id = abhaID
|
|
||||||
viewModel.patientDetails.isIdABHA = true
|
|
||||||
|
|
||||||
// Scan aadhaar card to get more details
|
|
||||||
moveToRegisterTwo()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.btnClickHere.setOnClickListener {
|
|
||||||
findNavController().navigate(R.id.action_registerOneScanAbhaFragment_to_registerOneCreateAbha)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun validateAndReturnId(): String? {
|
|
||||||
if (binding.nameEditText.text.isNullOrEmpty() || binding.nameEditText.text?.length != 14){
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return binding.nameEditText.text.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startScanningNow() {
|
|
||||||
val options = ScanOptions()
|
|
||||||
options.setDesiredBarcodeFormats(ScanOptions.QR_CODE)
|
|
||||||
options.setPrompt("Scan a barcode")
|
|
||||||
options.setCameraId(0) // Use a specific camera of the device
|
|
||||||
|
|
||||||
options.setBeepEnabled(true)
|
|
||||||
options.setBarcodeImageEnabled(true)
|
|
||||||
|
|
||||||
options.setPrompt("Start Scanning")
|
|
||||||
options.setOrientationLocked(false)
|
|
||||||
// options.setTimeout(10000) // in ms
|
|
||||||
|
|
||||||
barcodeLauncher.launch(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun processScannedData(contents: String) {
|
|
||||||
try {
|
|
||||||
val obj = JSONObject(contents)
|
|
||||||
// Log.d(TAG, obj.get("hidn").toString())
|
|
||||||
// Log.d(TAG, obj.get("name").toString())
|
|
||||||
// Log.d(TAG, obj.get("address").toString())
|
|
||||||
|
|
||||||
// Details mapping
|
|
||||||
viewModel.patientDetails.id = obj.get("hidn").toString().replace("-", "")
|
|
||||||
viewModel.patientDetails.isIdABHA = true
|
|
||||||
viewModel.patientDetails.name = obj.get("name").toString()
|
|
||||||
viewModel.patientDetails.gender = obj.get("gender").toString().mapToGender()
|
|
||||||
viewModel.patientDetails.yob = obj.get("dob").toString().fetchYOBFromDOB()
|
|
||||||
viewModel.patientDetails.mobile = obj.get("mobile").toString()
|
|
||||||
|
|
||||||
// Address mapping
|
|
||||||
viewModel.patientDetails.address = PatientDetails.Address()
|
|
||||||
viewModel.patientDetails.address!!.state = obj.get("state name").toString()
|
|
||||||
viewModel.patientDetails.address!!.district = obj.get("district_name").toString()
|
|
||||||
viewModel.patientDetails.address!!.house = obj.get("address").toString()
|
|
||||||
|
|
||||||
moveToRegisterThree()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e(TAG, "Unable to parse json")
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun moveToRegisterThree() {
|
|
||||||
findNavController().navigate(R.id.action_registerOneScanAbhaFragment_to_registerThreeEnterPatientDetails)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun moveToRegisterTwo() {
|
|
||||||
findNavController().navigate(R.id.action_registerOneScanAbhaFragment_to_registerTwoAadhaarFragment)
|
|
||||||
}
|
|
||||||
|
|
||||||
// fun String.mapToGender(): PatientDetails.Gender {
|
|
||||||
// if (this.lowercase() == "m"|| this.lowercase() == "male") {
|
|
||||||
// return PatientDetails.Gender.MALE
|
|
||||||
// } else if (this.lowercase() == "f"|| this.lowercase() == "female") {
|
|
||||||
// return PatientDetails.Gender.FEMALE
|
|
||||||
// } else {
|
|
||||||
// return PatientDetails.Gender.OTHER
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
private fun startScanningNow2() {
|
|
||||||
val options = GmsBarcodeScannerOptions.Builder()
|
|
||||||
.setBarcodeFormats(Barcode.FORMAT_QR_CODE)
|
|
||||||
.build()
|
|
||||||
val scanner = GmsBarcodeScanning.getClient(requireActivity(), options)
|
|
||||||
scanner.startScan()
|
|
||||||
.addOnSuccessListener { barcode ->
|
|
||||||
Log.d(TAG, barcode.rawValue!!)
|
|
||||||
}
|
|
||||||
.addOnCanceledListener {
|
|
||||||
// Task canceled
|
|
||||||
Log.d(TAG, "cancelled")
|
|
||||||
}
|
|
||||||
.addOnFailureListener { e ->
|
|
||||||
Log.d(TAG, "failed")
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,314 +0,0 @@
|
|||||||
package com.example.hpos.presentation.dashboard.register
|
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.location.Location
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.core.app.ActivityCompat
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.activityViewModels
|
|
||||||
import androidx.navigation.fragment.findNavController
|
|
||||||
import com.example.hpos.R
|
|
||||||
import com.example.hpos.data.model.Response
|
|
||||||
import com.example.hpos.data.model.patient.PatientDetails
|
|
||||||
import com.example.hpos.databinding.FragmentRegisterThreeEnterPatientDetailsBinding
|
|
||||||
import com.example.hpos.presentation.dashboard.DashboardViewModel
|
|
||||||
import com.example.hpos.util.MyUtils.mapToCategory
|
|
||||||
import com.example.hpos.util.MyUtils.mapToGender
|
|
||||||
import com.example.hpos.util.MyUtils.mapYesNoStringToBool
|
|
||||||
import com.google.android.gms.location.FusedLocationProviderClient
|
|
||||||
import com.google.android.gms.location.LocationCallback
|
|
||||||
import com.google.android.gms.location.LocationRequest
|
|
||||||
import com.google.android.gms.location.LocationResult
|
|
||||||
import com.google.android.gms.location.LocationServices
|
|
||||||
import java.util.Calendar
|
|
||||||
|
|
||||||
|
|
||||||
class RegisterThreeEnterPatientDetails : Fragment() {
|
|
||||||
|
|
||||||
private val TAG = "RegisterThreeEnterPat"
|
|
||||||
private lateinit var binding: FragmentRegisterThreeEnterPatientDetailsBinding
|
|
||||||
private val viewModel: DashboardViewModel by activityViewModels()
|
|
||||||
|
|
||||||
private lateinit var fusedLocationClient: FusedLocationProviderClient
|
|
||||||
private lateinit var locationCallback: LocationCallback
|
|
||||||
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
|
|
||||||
fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireActivity())
|
|
||||||
locationCallback = object : LocationCallback() {
|
|
||||||
override fun onLocationResult(locationResult: LocationResult) {
|
|
||||||
locationResult.lastLocation?.let { location ->
|
|
||||||
viewModel.deviceLocation = com.example.hpos.data.model.Location(location.latitude, location.longitude)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getLocation()
|
|
||||||
|
|
||||||
binding =
|
|
||||||
FragmentRegisterThreeEnterPatientDetailsBinding.inflate(inflater, container, false)
|
|
||||||
return binding.root
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
prefillTexts()
|
|
||||||
|
|
||||||
setupObservers()
|
|
||||||
|
|
||||||
binding.btnSubmit.setOnClickListener {
|
|
||||||
val mPatient = validateAndReturnPatientData()
|
|
||||||
if (mPatient != null) {
|
|
||||||
viewModel.patientDetails = mPatient
|
|
||||||
viewModel.pushPatientDetailsToDb()
|
|
||||||
viewModel.createTest()
|
|
||||||
moveToNextPage()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(requireContext(), "Fields can't be empty", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupObservers() {
|
|
||||||
viewModel.dataUploadStatus.observe(viewLifecycleOwner) {
|
|
||||||
when (it) {
|
|
||||||
is Response.Success -> {
|
|
||||||
Log.d(TAG, "Patient details pushed to DB successfully")
|
|
||||||
|
|
||||||
// Directly pushing because of limitation of offline
|
|
||||||
// Toast.makeText(
|
|
||||||
// requireContext(),
|
|
||||||
// "Patient Details Added successfully",
|
|
||||||
// Toast.LENGTH_SHORT
|
|
||||||
// ).show()
|
|
||||||
//
|
|
||||||
// viewModel.createTest(requireContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
is Response.Error -> {
|
|
||||||
it.exception.printStackTrace()
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
"Failed to add Patient Details, please try again.",
|
|
||||||
Toast.LENGTH_LONG
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun moveToNextPage() {
|
|
||||||
findNavController().navigate(R.id.action_registerThreeEnterPatientDetails_to_nav_home)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun prefillTexts() {
|
|
||||||
viewModel.patientDetails.name?.let { binding.etName.setText(it) }
|
|
||||||
viewModel.patientDetails.yob?.let { binding.etYob.setText(it.toString()) }
|
|
||||||
viewModel.patientDetails.gender?.let { binding.etGenderBlock.setText(it.toString(), false) }
|
|
||||||
viewModel.patientDetails.mobile?.let { binding.etMobile.setText(it) }
|
|
||||||
viewModel.patientDetails.address?.house?.let { binding.etHouse.setText(it) }
|
|
||||||
viewModel.patientDetails.address?.district?.let { binding.etDistrict.setText(it) }
|
|
||||||
viewModel.patientDetails.address?.state?.let { binding.etState.setText(it) }
|
|
||||||
viewModel.patientDetails.address?.pinCode?.let { binding.etPincode.setText(it.toString()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun validateAndReturnPatientData(): PatientDetails? {
|
|
||||||
if (viewModel.patientDetails.id.isEmpty()) {
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
"Unable to get \"ABHA ID\" or \"AADHAAR NO\", please try again",
|
|
||||||
Toast.LENGTH_LONG
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viewModel.patientDetails.address == null) {
|
|
||||||
viewModel.patientDetails.address = PatientDetails.Address()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding.etName.text.isNullOrEmpty()) {
|
|
||||||
binding.etName.error = getString(R.string.name_error)
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.name = binding.etName.text.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding.etYob.text.isNullOrEmpty()) {
|
|
||||||
binding.etYob.error = getString(R.string.yob_error)
|
|
||||||
return null
|
|
||||||
} else if (binding.etYob.text.toString().toInt() <= 1900 || binding.etYob.text.toString()
|
|
||||||
.toInt() > 2023
|
|
||||||
) {
|
|
||||||
binding.etYob.error = getString(R.string.yob_error_2)
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.yob = binding.etYob.text.toString().toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding.etGenderBlock.text.isNullOrEmpty()) {
|
|
||||||
binding.etGenderBlock.error = getString(R.string.gender_error)
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.gender = binding.etGenderBlock.text.toString().mapToGender()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding.etMobile.text.isNullOrEmpty()) {
|
|
||||||
binding.etMobile.error = getString(R.string.mobile_error)
|
|
||||||
return null
|
|
||||||
} else if (binding.etMobile.text.toString().length != 10) {
|
|
||||||
binding.etMobile.error = getString(R.string.mobile_error)
|
|
||||||
return null
|
|
||||||
}else {
|
|
||||||
viewModel.patientDetails.mobile = binding.etMobile.text.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding.etCareof.text.isNullOrEmpty()) {
|
|
||||||
binding.etCareof.error = getString(R.string.this_error)
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.careOf = binding.etCareof.text.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding.etIsMarried.text.isNullOrEmpty()) {
|
|
||||||
binding.etIsMarried.error = getString(R.string.this_error)
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.isMarried =
|
|
||||||
binding.etIsMarried.text.toString().mapYesNoStringToBool()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding.etCategory.text.isNullOrEmpty()) {
|
|
||||||
binding.etCategory.error = getString(R.string.this_error)
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.category = binding.etCategory.text.toString().mapToCategory()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding.etHouse.text.isNullOrEmpty()) {
|
|
||||||
binding.etHouse.error = getString(R.string.this_error)
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.address?.house = binding.etHouse.text.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding.etCity.text.isNullOrEmpty()) {
|
|
||||||
binding.etCity.error = getString(R.string.this_error)
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.address?.city = binding.etCity.text.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding.etState.text.isNullOrEmpty()) {
|
|
||||||
binding.etState.error = getString(R.string.this_error)
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.address?.state = binding.etState.text.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding.etPincode.text.isNullOrEmpty() || binding.etPincode.text?.length != 6) {
|
|
||||||
binding.etPincode.error = getString(R.string.this_error)
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.address?.pinCode = binding.etPincode.text.toString().toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binding.etBloodGroup.text.isNullOrEmpty()) {
|
|
||||||
binding.etBloodGroup.error = getString(R.string.this_error)
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.bloodGroup = binding.etBloodGroup.text.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.patientDetails.isUnderMedication = binding.cbItem1.isChecked
|
|
||||||
viewModel.patientDetails.isUnderTransfusion = binding.cbItem2.isChecked
|
|
||||||
|
|
||||||
viewModel.patientDetails.registerDate = Calendar.getInstance().time
|
|
||||||
return viewModel.patientDetails
|
|
||||||
}
|
|
||||||
|
|
||||||
// private fun getLocation() {
|
|
||||||
// locationManager = requireActivity().getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
|
||||||
// if ((ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
|
|
||||||
// ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), locationPermissionCode)
|
|
||||||
// }
|
|
||||||
// locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5f, this)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private fun getLocation() {
|
|
||||||
// fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireActivity())
|
|
||||||
// locationCallback = object : LocationCallback() {
|
|
||||||
// override fun onLocationResult(locationResult: LocationResult) {
|
|
||||||
// locationResult.lastLocation?.let { location ->
|
|
||||||
// val latitude = location.latitude
|
|
||||||
// val longitude = location.longitude
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
private fun requestLocationUpdates() {
|
|
||||||
val locationRequest = LocationRequest.create().apply {
|
|
||||||
interval = 10000 // Interval for receiving location updates (in milliseconds)
|
|
||||||
fastestInterval = 5000 // Fastest interval for location updates (in milliseconds)
|
|
||||||
priority = LocationRequest.PRIORITY_HIGH_ACCURACY // Location accuracy priority
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ActivityCompat.checkSelfPermission(
|
|
||||||
requireContext(),
|
|
||||||
Manifest.permission.ACCESS_COARSE_LOCATION
|
|
||||||
) != PackageManager.PERMISSION_GRANTED
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getLocation() {
|
|
||||||
if (ActivityCompat.checkSelfPermission(
|
|
||||||
requireContext(),
|
|
||||||
Manifest.permission.ACCESS_COARSE_LOCATION
|
|
||||||
) != PackageManager.PERMISSION_GRANTED
|
|
||||||
) {
|
|
||||||
// Handle location permission request if needed
|
|
||||||
Toast.makeText(requireContext(), "Please enable location services", Toast.LENGTH_SHORT).show()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fusedLocationClient.lastLocation
|
|
||||||
.addOnSuccessListener { location: Location? ->
|
|
||||||
location?.let {
|
|
||||||
viewModel.deviceLocation = com.example.hpos.data.model.Location(it.latitude, it.longitude)
|
|
||||||
} ?: run {
|
|
||||||
requestLocationUpdates()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.addOnFailureListener { exception: Exception ->
|
|
||||||
exception.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun stopLocationUpdates() {
|
|
||||||
fusedLocationClient.removeLocationUpdates(locationCallback)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
super.onResume()
|
|
||||||
getLocation()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPause() {
|
|
||||||
super.onPause()
|
|
||||||
stopLocationUpdates()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
package com.example.hpos.presentation.dashboard.register
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.activityViewModels
|
|
||||||
import androidx.navigation.fragment.findNavController
|
|
||||||
import com.example.hpos.R
|
|
||||||
import com.example.hpos.databinding.FragmentRegisterTwoAadhaarBinding
|
|
||||||
import com.example.hpos.domain.AadhaarScanner.QrCodeException
|
|
||||||
import com.example.hpos.domain.AadhaarScanner.SecureQrCode
|
|
||||||
import com.example.hpos.presentation.dashboard.DashboardViewModel
|
|
||||||
import com.journeyapps.barcodescanner.ScanContract
|
|
||||||
import com.journeyapps.barcodescanner.ScanIntentResult
|
|
||||||
import com.journeyapps.barcodescanner.ScanOptions
|
|
||||||
|
|
||||||
class RegisterTwoAadhaarFragment : Fragment() {
|
|
||||||
|
|
||||||
private val TAG = "RegisterTwoAadhaarFrag"
|
|
||||||
private lateinit var binding: FragmentRegisterTwoAadhaarBinding
|
|
||||||
private val viewModel: DashboardViewModel by activityViewModels()
|
|
||||||
|
|
||||||
private val barcodeLauncher = registerForActivityResult(
|
|
||||||
ScanContract()
|
|
||||||
) { result: ScanIntentResult ->
|
|
||||||
if (result.contents == null) {
|
|
||||||
Toast.makeText(requireContext(), "Cancelled: Unable to scan, Try Again!!", Toast.LENGTH_LONG).show()
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, result.contents)
|
|
||||||
processScannedData(result.contents)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
binding = FragmentRegisterTwoAadhaarBinding.inflate(inflater, container, false)
|
|
||||||
return binding.root
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
binding.btnScanNow.setOnClickListener {
|
|
||||||
startScanningNow()
|
|
||||||
}
|
|
||||||
binding.btnGo.setOnClickListener {
|
|
||||||
val aadhaarId = validateAndReturnId()
|
|
||||||
if (aadhaarId == null) {
|
|
||||||
binding.etAbhaId.error = getString(R.string.please_enter_aadhaar)
|
|
||||||
Toast.makeText(requireContext(), "Invalid ID Entered", Toast.LENGTH_SHORT).show()
|
|
||||||
} else {
|
|
||||||
viewModel.patientDetails.id = aadhaarId
|
|
||||||
viewModel.patientDetails.isIdABHA = false
|
|
||||||
|
|
||||||
checkForIdThenMove()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
binding.etAbhaId.setOnClickListener { binding.etAbhaId.isErrorEnabled = false }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun validateAndReturnId(): String? {
|
|
||||||
if (binding.nameEditText.text.isNullOrEmpty() || binding.nameEditText.text?.length != 12){
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return binding.nameEditText.text.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startScanningNow() {
|
|
||||||
val options = ScanOptions()
|
|
||||||
options.setDesiredBarcodeFormats(ScanOptions.QR_CODE)
|
|
||||||
options.setPrompt("Scan a barcode")
|
|
||||||
options.setCameraId(0) // Use a specific camera of the device
|
|
||||||
|
|
||||||
options.setBeepEnabled(true)
|
|
||||||
options.setBarcodeImageEnabled(true)
|
|
||||||
|
|
||||||
options.setPrompt("Start Scanning")
|
|
||||||
options.setOrientationLocked(false)
|
|
||||||
// options.setTimeout(10000) // in ms
|
|
||||||
|
|
||||||
barcodeLauncher.launch(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun processScannedData(scanData: String) {
|
|
||||||
try {
|
|
||||||
val decodedData = SecureQrCode(requireActivity(), scanData)
|
|
||||||
viewModel.aadharCard = decodedData.scannedAadharCard
|
|
||||||
|
|
||||||
Toast.makeText(requireContext(), "Scanned Aadhar Card Successfully", Toast.LENGTH_SHORT).show()
|
|
||||||
Log.d(TAG, viewModel.aadharCard.toString())
|
|
||||||
|
|
||||||
viewModel.mapAadhaarDataToPatient()
|
|
||||||
|
|
||||||
checkForIdThenMove()
|
|
||||||
|
|
||||||
} catch (e: QrCodeException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
Toast.makeText(requireContext(), "Unable to Fetch data, please scan again or enter manually!!", Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkForIdThenMove() {
|
|
||||||
Log.d(TAG, "Inside: checkForIdThenMove()")
|
|
||||||
Log.d(TAG, "ID is ${viewModel.patientDetails.id}")
|
|
||||||
|
|
||||||
if (viewModel.patientDetails.id.isNullOrEmpty()){
|
|
||||||
binding.etAbhaId.error = getString(R.string.please_enter_aadhaar)
|
|
||||||
binding.btnScanNow.alpha = 0.2f
|
|
||||||
binding.btnScanNow.isEnabled = false
|
|
||||||
} else {
|
|
||||||
moveToRegisterThree()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun moveToRegisterThree() {
|
|
||||||
findNavController().navigate(R.id.action_registerTwoAadhaarFragment_to_registerThreeEnterPatientDetails)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package com.example.hpos.util
|
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import com.example.hpos.data.repository.DatabaseRepository
|
|
||||||
import com.example.hpos.data.repository.LocalFileRepository
|
|
||||||
import com.example.hpos.data.datasource.LocalFileDataSource
|
|
||||||
import com.example.hpos.domain.SaveRawData
|
|
||||||
import com.example.hpos.domain.SaveRawDataTest
|
|
||||||
import com.example.hpos.presentation.MainViewModel
|
|
||||||
import com.example.hpos.presentation.dashboard.DashboardViewModel
|
|
||||||
import com.example.hpos.presentation.testRight.TestRightViewModel
|
|
||||||
|
|
||||||
class MyViewModelFactory : ViewModelProvider.Factory {
|
|
||||||
|
|
||||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
|
||||||
if (modelClass.isAssignableFrom(MainViewModel::class.java))
|
|
||||||
return MainViewModel() as T
|
|
||||||
else if (modelClass.isAssignableFrom(TestRightViewModel::class.java)) {
|
|
||||||
val repository = LocalFileRepository(LocalFileDataSource())
|
|
||||||
return TestRightViewModel(SaveRawData(repository), SaveRawDataTest(repository), DatabaseRepository()) as T
|
|
||||||
} else if (modelClass.isAssignableFrom(DashboardViewModel::class.java)) {
|
|
||||||
// val repository = LocalFileRepository(LocalFileDataSource())
|
|
||||||
// return DashboardViewModel(DatabaseRepository()) as T
|
|
||||||
return DashboardViewModel() as T
|
|
||||||
} else
|
|
||||||
throw IllegalArgumentException("Unknown ViewModel class");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.example.hpostesting
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.SupervisorJob
|
||||||
|
|
||||||
|
@HiltAndroidApp
|
||||||
|
class HPOSTestingApplication: Application() {
|
||||||
|
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.example.hpos.data
|
package com.example.hpostesting.data
|
||||||
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import com.example.hpos.data.model.test.TestDetails
|
import com.example.hpostesting.data.model.patient.UserData
|
||||||
import com.example.hpos.data.model.test.TestRightDeviceConstants
|
import com.example.hpostesting.data.model.test.TestRightDeviceConstants
|
||||||
import com.example.hpos.data.model.test.TestType
|
import com.example.hpostesting.data.model.test.TestType
|
||||||
|
|
||||||
object DataHolder {
|
object DataHolder {
|
||||||
|
|
||||||
@@ -28,7 +28,9 @@ object DataHolder {
|
|||||||
/* (For reference/baseline) Contains pixel no. -> Intensity of light falling on that pixel */
|
/* (For reference/baseline) Contains pixel no. -> Intensity of light falling on that pixel */
|
||||||
val intensityReferenceArray = ArrayList<Double>()
|
val intensityReferenceArray = ArrayList<Double>()
|
||||||
|
|
||||||
var selectedTest: TestDetails? = null
|
var selectedTest: UserData? = null
|
||||||
|
|
||||||
|
var location: UserData.Location? = null
|
||||||
|
|
||||||
var testExp: Boolean = true
|
var testExp: Boolean = true
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
package com.example.hpos.data
|
package com.example.hpostesting.data
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.example.hpos.data.model.Response
|
import com.example.hpostesting.data.model.Response
|
||||||
import com.example.hpos.data.repository.DatabaseRepository
|
import com.example.hpostesting.data.repository.DatabaseRepository
|
||||||
import com.example.hpos.util.MyUtils
|
import com.example.hpostesting.util.MyUtils
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.lang.Thread.sleep
|
|
||||||
|
|
||||||
class FileUploader {
|
class FileUploader {
|
||||||
|
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package com.example.hpostesting.data
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.ConnectivityManager
|
||||||
|
import android.net.Network
|
||||||
|
import android.net.NetworkCapabilities
|
||||||
|
import android.net.NetworkRequest
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
|
||||||
|
class NetworkStatusLiveData(context: Context) : LiveData<Boolean>() {
|
||||||
|
|
||||||
|
private val connectivityManager: ConnectivityManager =
|
||||||
|
context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||||
|
|
||||||
|
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
|
||||||
|
override fun onAvailable(network: Network) {
|
||||||
|
postValue(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLost(network: Network) {
|
||||||
|
postValue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
override fun onActive() {
|
||||||
|
super.onActive()
|
||||||
|
postValue(isNetworkAvailable())
|
||||||
|
registerNetworkCallback()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onInactive() {
|
||||||
|
super.onInactive()
|
||||||
|
unregisterNetworkCallback()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerNetworkCallback() {
|
||||||
|
val networkRequest = NetworkRequest.Builder()
|
||||||
|
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
|
||||||
|
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
||||||
|
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun unregisterNetworkCallback() {
|
||||||
|
connectivityManager.unregisterNetworkCallback(networkCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
private fun isNetworkAvailable(): Boolean {
|
||||||
|
val network = connectivityManager.activeNetwork
|
||||||
|
val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
|
||||||
|
return networkCapabilities != null &&
|
||||||
|
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
|
||||||
|
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data
|
package com.example.hpostesting.data
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.constant
|
package com.example.hpostesting.data.constant
|
||||||
|
|
||||||
object Constants {
|
object Constants {
|
||||||
const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION"
|
const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.constant
|
package com.example.hpostesting.data.constant
|
||||||
|
|
||||||
enum class TestRightCommands(val command: String) {
|
enum class TestRightCommands(val command: String) {
|
||||||
led2Set50("led2 50\r"),
|
led2Set50("led2 50\r"),
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.example.hpostesting.data.dao
|
||||||
|
|
||||||
|
import androidx.room.TypeConverter
|
||||||
|
import com.example.hpostesting.data.model.patient.UserData
|
||||||
|
import com.google.gson.Gson
|
||||||
|
|
||||||
|
class Converters {
|
||||||
|
private val gson = Gson()
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun fromString(value: String?): UserData.Location? {
|
||||||
|
return if (value != null) {
|
||||||
|
gson.fromJson(value, UserData.Location::class.java)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun toString(location: UserData.Location?): String? {
|
||||||
|
return if (location != null) {
|
||||||
|
gson.toJson(location)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.example.hpostesting.data.dao
|
||||||
|
|
||||||
|
import androidx.room.Database
|
||||||
|
import androidx.room.RoomDatabase
|
||||||
|
import androidx.room.TypeConverters
|
||||||
|
import com.example.hpostesting.data.model.patient.UserData
|
||||||
|
|
||||||
|
@Database(entities = [UserData::class], version = 1, exportSchema = false)
|
||||||
|
@TypeConverters(Converters::class)
|
||||||
|
abstract class MyDatabase : RoomDatabase() {
|
||||||
|
abstract fun userDao(): UserDao
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.example.hpostesting.data.dao
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import com.example.hpostesting.data.model.patient.UserData
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface UserDao {
|
||||||
|
@Query("SELECT * from user_table")
|
||||||
|
fun getAll(): LiveData<List<UserData>>
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
suspend fun insertAll(userData: UserData)
|
||||||
|
|
||||||
|
@Query("SELECT * FROM user_table WHERE _id = :id")
|
||||||
|
suspend fun getUserByID(id: String): UserData
|
||||||
|
|
||||||
|
@Query("DELETE FROM user_table WHERE _id = :id")
|
||||||
|
suspend fun deleteById(id: String)
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.datasource
|
package com.example.hpostesting.data.datasource
|
||||||
|
|
||||||
import com.opencsv.CSVWriter
|
import com.opencsv.CSVWriter
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.example.hpostesting.data.model
|
||||||
|
|
||||||
|
|
||||||
|
class AadharCard {
|
||||||
|
var name = ""
|
||||||
|
var dateOfBirth = ""
|
||||||
|
var gender = ""
|
||||||
|
var careOf = ""
|
||||||
|
var district = ""
|
||||||
|
var landmark = ""
|
||||||
|
var house = ""
|
||||||
|
var location = ""
|
||||||
|
var pinCode = ""
|
||||||
|
var postOffice = ""
|
||||||
|
var state = ""
|
||||||
|
var street = ""
|
||||||
|
var subDistrict = ""
|
||||||
|
var vtc = ""
|
||||||
|
var mobile = ""
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.model
|
package com.example.hpostesting.data.model
|
||||||
|
|
||||||
data class CalculationVariableForTest(
|
data class CalculationVariableForTest(
|
||||||
var pixelNo: Int,
|
var pixelNo: Int,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.model
|
package com.example.hpostesting.data.model
|
||||||
|
|
||||||
data class ErrorMessage (
|
data class ErrorMessage (
|
||||||
val message: String,
|
val message: String,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.model
|
package com.example.hpostesting.data.model
|
||||||
|
|
||||||
data class Location(
|
data class Location(
|
||||||
var latitude: Double?,
|
var latitude: Double?,
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.example.hpos.data.model
|
package com.example.hpostesting.data.model
|
||||||
|
|
||||||
import com.example.hpos.data.model.test.TestRightResultType
|
import com.example.hpostesting.data.model.test.TestRightResultType
|
||||||
|
|
||||||
data class PatientData(
|
data class PatientData(
|
||||||
val name: String,
|
val name: String,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.model
|
package com.example.hpostesting.data.model
|
||||||
|
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.model
|
package com.example.hpostesting.data.model
|
||||||
|
|
||||||
sealed class Response<out R> {
|
sealed class Response<out R> {
|
||||||
data class Success<out T>(val data: T) : Response<T>()
|
data class Success<out T>(val data: T) : Response<T>()
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.model.patient
|
package com.example.hpostesting.data.model.patient
|
||||||
|
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.example.hpostesting.data.model.patient
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import com.example.hpostesting.data.model.test.TestRightResultType
|
||||||
|
|
||||||
|
@Entity(tableName = "user_table")
|
||||||
|
data class UserData(
|
||||||
|
@PrimaryKey
|
||||||
|
var _id: String = "",
|
||||||
|
var AbhaId: String = "",
|
||||||
|
var AadharId: String = "",
|
||||||
|
var name: String = "",
|
||||||
|
var birthYear: String = "",
|
||||||
|
var gender: String = "",
|
||||||
|
var phoneNumber: String = "",
|
||||||
|
var careOf: String = "",
|
||||||
|
var maritalStatus: String = "",
|
||||||
|
var caste: String = "",
|
||||||
|
var subCaste: String = "",
|
||||||
|
var house: String = "",
|
||||||
|
var city: String = "",
|
||||||
|
var district: String = "",
|
||||||
|
var state: String = "",
|
||||||
|
var pinCode: String = "",
|
||||||
|
var bloodGroup: String = "",
|
||||||
|
var isUnderMedication: Boolean? = false,
|
||||||
|
var isUnderTransfusion: Boolean? = false,
|
||||||
|
var sickleCellHistory: String? = "",
|
||||||
|
var userImage: String = "",
|
||||||
|
var location: Location? = null,
|
||||||
|
var uploadTime: String? = "",
|
||||||
|
var testTime: String? = "",
|
||||||
|
var testStatus: Boolean? = false,
|
||||||
|
var mobileId: String = "",
|
||||||
|
var deviceId: String = "",
|
||||||
|
var kitSerial: String = "",
|
||||||
|
var csvPath: String = "",
|
||||||
|
var reportPath: String = "",
|
||||||
|
var result: TestRightResultType? = null,
|
||||||
|
var resultRatio: Double? = null,
|
||||||
|
){
|
||||||
|
enum class Gender {
|
||||||
|
MALE,
|
||||||
|
FEMALE,
|
||||||
|
OTHER
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Location(
|
||||||
|
var latitude: Double? = null,
|
||||||
|
var longitude: Double? = null
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.example.hpos.data.model.test
|
package com.example.hpostesting.data.model.test
|
||||||
|
|
||||||
import com.example.hpos.data.model.Location
|
import com.example.hpostesting.data.model.Location
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
data class TestDetails(
|
data class TestDetails(
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.model.test
|
package com.example.hpostesting.data.model.test
|
||||||
|
|
||||||
data class TestInfo(
|
data class TestInfo(
|
||||||
val value: String,
|
val value: String,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.model.test
|
package com.example.hpostesting.data.model.test
|
||||||
|
|
||||||
data class TestRightCalculationData(
|
data class TestRightCalculationData(
|
||||||
var absorbanceOne: Double?,
|
var absorbanceOne: Double?,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.model.test
|
package com.example.hpostesting.data.model.test
|
||||||
|
|
||||||
data class TestRightDeviceConstants(
|
data class TestRightDeviceConstants(
|
||||||
var a: String,
|
var a: String,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.model.test
|
package com.example.hpostesting.data.model.test
|
||||||
|
|
||||||
enum class TestRightResultType {
|
enum class TestRightResultType {
|
||||||
NORMAL,
|
NORMAL,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.model.test
|
package com.example.hpostesting.data.model.test
|
||||||
|
|
||||||
enum class TestType {
|
enum class TestType {
|
||||||
SICKLECERT,
|
SICKLECERT,
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package com.example.hpostesting.data.repository
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import com.example.hpostesting.data.model.PendingUploads
|
||||||
|
import com.example.hpostesting.data.model.Response
|
||||||
|
import com.example.hpostesting.data.model.patient.UserData
|
||||||
|
import com.google.firebase.firestore.FirebaseFirestore
|
||||||
|
import com.google.firebase.firestore.ktx.firestore
|
||||||
|
import com.google.firebase.ktx.Firebase
|
||||||
|
import com.google.firebase.storage.ktx.storage
|
||||||
|
import kotlinx.coroutines.tasks.await
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class DatabaseRepository : Repository {
|
||||||
|
|
||||||
|
private val db: FirebaseFirestore = Firebase.firestore
|
||||||
|
private val storage = Firebase.storage
|
||||||
|
|
||||||
|
suspend fun addTestToDatabase(data: UserData): Response<String> {
|
||||||
|
return try {
|
||||||
|
val userdata = db.collection("patientData").whereEqualTo("_id", data._id).get().await()
|
||||||
|
if (userdata.documents.isNotEmpty()) {
|
||||||
|
userdata.documents.forEach {
|
||||||
|
db.collection("patientData").document(it.id).update("testStatus", true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
db.collection("testData").add(data).await()
|
||||||
|
Response.Success(data._id)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Response.Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun uploadFileToStorage(patientID: String, filePath: String): Response<Boolean> {
|
||||||
|
try {
|
||||||
|
|
||||||
|
val file = Uri.fromFile(File(filePath))
|
||||||
|
val riversRef = storage.reference.child("$patientID/${file.lastPathSegment}")
|
||||||
|
riversRef.putFile(file).await()
|
||||||
|
return Response.Success(true)
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
return Response.Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun addToPendingQueue(pendingUploads: PendingUploads): Response<Boolean> {
|
||||||
|
return try {
|
||||||
|
db.collection("pendingUploads").document(pendingUploads.pendingId).set(pendingUploads)
|
||||||
|
.await()
|
||||||
|
|
||||||
|
Response.Success(true)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
Response.Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getAllFromPendingQueue(): List<PendingUploads> {
|
||||||
|
val pendingList = mutableListOf<PendingUploads>()
|
||||||
|
return try {
|
||||||
|
val querySnapshot = db.collection("pendingUploads").orderBy("timeAdded").get().await()
|
||||||
|
|
||||||
|
for (doc in querySnapshot.documents) {
|
||||||
|
val pendingFile = doc.toObject(PendingUploads::class.java)
|
||||||
|
pendingFile?.let {
|
||||||
|
pendingList.add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pendingList
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
pendingList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun removeFromPendingQueue(fileName: String): Response<Boolean> {
|
||||||
|
return try {
|
||||||
|
db.collection("pendingUploads").document(fileName).delete().await()
|
||||||
|
|
||||||
|
Response.Success(true)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
Response.Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.example.hpos.data.repository
|
package com.example.hpostesting.data.repository
|
||||||
|
|
||||||
import com.example.hpos.data.datasource.LocalFileDataSource
|
import com.example.hpostesting.data.datasource.LocalFileDataSource
|
||||||
|
|
||||||
class LocalFileRepository(private val localFileDataSource: LocalFileDataSource) {
|
class LocalFileRepository(private val localFileDataSource: LocalFileDataSource) {
|
||||||
fun saveCsvToDisk(filepath: String, contents: ArrayList<Array<String>>) =
|
fun saveCsvToDisk(filepath: String, contents: ArrayList<Array<String>>) =
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.data.repository
|
package com.example.hpostesting.data.repository
|
||||||
|
|
||||||
interface Repository {
|
interface Repository {
|
||||||
// suspend fun addToDatabase(data: PatientDetails)
|
// suspend fun addToDatabase(data: PatientDetails)
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.example.hpos.domain
|
package com.example.hpostesting.domain
|
||||||
|
|
||||||
import com.example.hpos.data.constant.Constants
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpos.data.model.test.TestRightCalculationData
|
import com.example.hpostesting.data.model.test.TestRightCalculationData
|
||||||
import com.example.hpos.data.model.test.TestRightResultType
|
import com.example.hpostesting.data.model.test.TestRightResultType
|
||||||
|
|
||||||
class ResultCalculationWithAvgImpl : TestRightResultCalculation {
|
class ResultCalculationWithAvgImpl : TestRightResultCalculation {
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.example.hpos.domain
|
package com.example.hpostesting.domain
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.example.hpos.data.constant.Constants
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpos.data.model.test.TestRightResultType
|
import com.example.hpostesting.data.model.test.TestRightResultType
|
||||||
import kotlin.math.log10
|
import kotlin.math.log10
|
||||||
|
|
||||||
class ResultCalculationWithFirstImpl {
|
class ResultCalculationWithFirstImpl {
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.example.hpos.domain
|
package com.example.hpostesting.domain
|
||||||
|
|
||||||
import com.example.hpos.data.constant.Constants
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpos.data.model.test.TestRightCalculationData
|
import com.example.hpostesting.data.model.test.TestRightCalculationData
|
||||||
import com.example.hpos.data.model.test.TestRightResultType
|
import com.example.hpostesting.data.model.test.TestRightResultType
|
||||||
|
|
||||||
class ResultCalculationWithMaxImpl : TestRightResultCalculation {
|
class ResultCalculationWithMaxImpl : TestRightResultCalculation {
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.example.hpos.domain
|
package com.example.hpostesting.domain
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.example.hpos.data.repository.LocalFileRepository
|
import com.example.hpostesting.data.repository.LocalFileRepository
|
||||||
import com.example.hpos.data.constant.Constants
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpos.data.model.test.TestDetails
|
import com.example.hpostesting.data.model.patient.UserData
|
||||||
import com.example.hpos.data.model.test.TestRightCalculationData
|
import com.example.hpostesting.data.model.test.TestRightCalculationData
|
||||||
import java.util.Collections.sort
|
import java.util.Collections.sort
|
||||||
|
|
||||||
class SaveRawData(private val localFileRepository: LocalFileRepository) {
|
class SaveRawData(private val localFileRepository: LocalFileRepository) {
|
||||||
@@ -98,7 +98,7 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) {
|
|||||||
folderPath: String,
|
folderPath: String,
|
||||||
fileName: String,
|
fileName: String,
|
||||||
calculationData: TestRightCalculationData,
|
calculationData: TestRightCalculationData,
|
||||||
testDetails: TestDetails?
|
testDetails: UserData?
|
||||||
) {
|
) {
|
||||||
// val fileObj = File(folderPath, fileName)
|
// val fileObj = File(folderPath, fileName)
|
||||||
// val writer = FileWriter(fileObj)
|
// val writer = FileWriter(fileObj)
|
||||||
@@ -116,11 +116,11 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) {
|
|||||||
|
|
||||||
private fun getLogStringFromObjWithPatientData(
|
private fun getLogStringFromObjWithPatientData(
|
||||||
calculationData: TestRightCalculationData,
|
calculationData: TestRightCalculationData,
|
||||||
testDetails: TestDetails?
|
testDetails: UserData?
|
||||||
): String {
|
): String {
|
||||||
var outputString = "Test calculation logs ==>\n"
|
var outputString = "Test calculation logs ==>\n"
|
||||||
outputString += "Name = ${testDetails?.patientName}\n"
|
outputString += "Name = ${testDetails?.name}\n"
|
||||||
outputString += "ID = ${testDetails?.patientID}\n"
|
outputString += "ID = ${testDetails?._id}\n"
|
||||||
// outputString += "Gender = ${patientData.gender}\n"
|
// outputString += "Gender = ${patientData.gender}\n"
|
||||||
outputString += "Absorbance one = ${
|
outputString += "Absorbance one = ${
|
||||||
String.format(
|
String.format(
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.example.hpos.domain
|
package com.example.hpostesting.domain
|
||||||
|
|
||||||
import com.example.hpos.data.repository.LocalFileRepository
|
import com.example.hpostesting.data.repository.LocalFileRepository
|
||||||
import com.example.hpos.data.model.CalculationVariableForTest
|
import com.example.hpostesting.data.model.CalculationVariableForTest
|
||||||
|
|
||||||
class SaveRawDataTest(private val localFileRepository: LocalFileRepository) {
|
class SaveRawDataTest(private val localFileRepository: LocalFileRepository) {
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.example.hpos.domain
|
package com.example.hpostesting.domain
|
||||||
|
|
||||||
import com.example.hpos.data.constant.Constants
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpos.data.model.test.TestRightCalculationData
|
import com.example.hpostesting.data.model.test.TestRightCalculationData
|
||||||
import com.example.hpos.data.model.test.TestRightResultType
|
import com.example.hpostesting.data.model.test.TestRightResultType
|
||||||
|
|
||||||
class SickleFindResultCaluculationWithMaxImpl : TestRightResultCalculation{
|
class SickleFindResultCaluculationWithMaxImpl : TestRightResultCalculation{
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.example.hpos.domain
|
package com.example.hpostesting.domain
|
||||||
|
|
||||||
import com.example.hpos.data.model.test.TestRightCalculationData
|
import com.example.hpostesting.data.model.test.TestRightCalculationData
|
||||||
|
|
||||||
interface TestRightResultCalculation {
|
interface TestRightResultCalculation {
|
||||||
fun getResults(
|
fun getResults(
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.example.hpostesting.domain.di
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.room.Room
|
||||||
|
import com.example.hpostesting.data.dao.MyDatabase
|
||||||
|
import com.example.hpostesting.data.dao.UserDao
|
||||||
|
import com.example.hpostesting.data.datasource.LocalFileDataSource
|
||||||
|
import com.example.hpostesting.data.repository.DatabaseRepository
|
||||||
|
import com.example.hpostesting.data.repository.LocalFileRepository
|
||||||
|
import com.example.hpostesting.domain.SaveRawData
|
||||||
|
import com.example.hpostesting.domain.SaveRawDataTest
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
object AppModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideMyDatabase(@ApplicationContext context: Context): MyDatabase {
|
||||||
|
return Room.databaseBuilder(
|
||||||
|
context, MyDatabase::class.java, "my_database"
|
||||||
|
).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideMyDao(myDatabase: MyDatabase): UserDao {
|
||||||
|
return myDatabase.userDao()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideContext(application: Application): Context {
|
||||||
|
return application.applicationContext
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideSaveRawData(): SaveRawData {
|
||||||
|
val repository = LocalFileRepository(LocalFileDataSource())
|
||||||
|
return SaveRawData(repository)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideSaveRawDataTest(): SaveRawDataTest {
|
||||||
|
val repository = LocalFileRepository(LocalFileDataSource())
|
||||||
|
return SaveRawDataTest(repository)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideDatabaseRepository(): DatabaseRepository {
|
||||||
|
return DatabaseRepository()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
package com.example.hpos.presentation
|
package com.example.hpostesting.presentation
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.hpos.R
|
import com.example.hpostesting.data.DataHolder
|
||||||
import com.example.hpos.data.DataHolder
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpos.data.constant.Constants
|
import com.example.hpostesting.presentation.dashboard.DashboardActivity
|
||||||
import com.example.hpos.databinding.ActivityKitScanBinding
|
import com.example.hpostesting.presentation.testRight.TestRightActivity
|
||||||
import com.example.hpos.presentation.dashboard.DashboardActivity
|
|
||||||
import com.example.hpos.presentation.testRight.TestRightActivity
|
|
||||||
import com.journeyapps.barcodescanner.ScanContract
|
import com.journeyapps.barcodescanner.ScanContract
|
||||||
import com.journeyapps.barcodescanner.ScanIntentResult
|
import com.journeyapps.barcodescanner.ScanIntentResult
|
||||||
import com.journeyapps.barcodescanner.ScanOptions
|
import com.journeyapps.barcodescanner.ScanOptions
|
||||||
|
import `in`.sminnovations.hpostesting.R
|
||||||
|
import `in`.sminnovations.hpostesting.databinding.ActivityKitScanBinding
|
||||||
|
|
||||||
class KitScanActivity : AppCompatActivity() {
|
class KitScanActivity : AppCompatActivity() {
|
||||||
|
|
||||||
@@ -51,6 +51,7 @@ class KitScanActivity : AppCompatActivity() {
|
|||||||
startScanningNow()
|
startScanningNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
binding.btnGo.setOnClickListener {
|
binding.btnGo.setOnClickListener {
|
||||||
val serialNumber = binding.nameEditText.text.toString().trim()
|
val serialNumber = binding.nameEditText.text.toString().trim()
|
||||||
if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid(serialNumber)) {
|
if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid(serialNumber)) {
|
||||||
@@ -92,7 +93,7 @@ class KitScanActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkDataNotNull(): Boolean {
|
private fun checkDataNotNull(): Boolean {
|
||||||
return if (DataHolder.selectedTest == null) {
|
return if (DataHolder.selectedTest?._id == null) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
"Please Select patient before starting test",
|
"Please Select patient before starting test",
|
||||||
@@ -0,0 +1,255 @@
|
|||||||
|
package com.example.hpostesting.presentation
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.hardware.usb.UsbManager
|
||||||
|
import android.location.Location
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.Menu
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.view.get
|
||||||
|
import com.example.hpostesting.data.DataHolder
|
||||||
|
import com.example.hpostesting.data.constant.Constants
|
||||||
|
import com.example.hpostesting.data.model.patient.UserData
|
||||||
|
import com.example.hpostesting.data.model.test.TestType
|
||||||
|
import com.google.android.gms.location.FusedLocationProviderClient
|
||||||
|
import com.google.android.gms.location.LocationCallback
|
||||||
|
import com.google.android.gms.location.LocationRequest
|
||||||
|
import com.google.android.gms.location.LocationResult
|
||||||
|
import com.google.android.gms.location.LocationServices
|
||||||
|
import com.hoho.android.usbserial.driver.UsbSerialProber
|
||||||
|
import `in`.sminnovations.hpostesting.R
|
||||||
|
import `in`.sminnovations.hpostesting.databinding.ActivityMainBinding
|
||||||
|
|
||||||
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var binding: ActivityMainBinding
|
||||||
|
|
||||||
|
private var myMenu: Menu? = null
|
||||||
|
|
||||||
|
private val TAG = "MainActivity"
|
||||||
|
|
||||||
|
private lateinit var fusedLocationClient: FusedLocationProviderClient
|
||||||
|
private lateinit var locationCallback: LocationCallback
|
||||||
|
|
||||||
|
private var mUsbReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context?, intent: Intent) {
|
||||||
|
val action = intent.action
|
||||||
|
if (UsbManager.ACTION_USB_DEVICE_DETACHED == action) {
|
||||||
|
DataHolder.usbConnected.value = false
|
||||||
|
} else if (UsbManager.ACTION_USB_DEVICE_ATTACHED == action) {
|
||||||
|
DataHolder.usbConnected.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
setSupportActionBar(binding.myToolbar)
|
||||||
|
|
||||||
|
setupListeners()
|
||||||
|
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
|
||||||
|
getLocation()
|
||||||
|
locationCallback = object : LocationCallback() {
|
||||||
|
override fun onLocationResult(locationResult: LocationResult) {
|
||||||
|
locationResult.lastLocation?.let { location ->
|
||||||
|
DataHolder.location = UserData.Location(location.latitude, location.longitude)
|
||||||
|
Log.i("Location", DataHolder.location.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val filter = IntentFilter().apply {
|
||||||
|
addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
|
||||||
|
addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
|
||||||
|
}
|
||||||
|
registerReceiver(mUsbReceiver, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkAndUpdateUsbConnection() {
|
||||||
|
val availableDrivers = UsbSerialProber.getDefaultProber()
|
||||||
|
.findAllDrivers(getSystemService(Context.USB_SERVICE) as UsbManager)
|
||||||
|
if (availableDrivers.isNotEmpty() && availableDrivers[0].device.productId == Constants.DEVICE_PRODUCT_ID && availableDrivers[0].device.vendorId == Constants.DEVICE_VENDOR_ID) {
|
||||||
|
Log.d(TAG, "Device matched -> product = ${availableDrivers[0].device.productId}, vendor = ${availableDrivers[0].device.vendorId}")
|
||||||
|
DataHolder.usbConnected.value = true
|
||||||
|
} else if (availableDrivers.isNotEmpty()) {
|
||||||
|
Log.d(TAG, "Device NOT matched -> product = ${availableDrivers[0].device.productId}, vendor = ${availableDrivers[0].device.vendorId}")
|
||||||
|
Toast.makeText(this, "Device Not Compatible", Toast.LENGTH_SHORT).show()
|
||||||
|
DataHolder.usbConnected.value = false
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Device NOT Connected")
|
||||||
|
DataHolder.usbConnected.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupListeners() {
|
||||||
|
binding.cvItem1.setOnClickListener {
|
||||||
|
DataHolder.selectedTestType = TestType.SICKLECERT
|
||||||
|
val i = Intent(applicationContext, KitScanActivity::class.java)
|
||||||
|
startActivity(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.cvItem2.setOnClickListener {
|
||||||
|
DataHolder.selectedTestType = TestType.SICKLEFIND
|
||||||
|
val i = Intent(applicationContext, KitScanActivity::class.java)
|
||||||
|
startActivity(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
DataHolder.usbConnected.observe(this) {
|
||||||
|
if (it) {
|
||||||
|
myMenu?.get(0)?.icon = ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_24)
|
||||||
|
} else {
|
||||||
|
myMenu?.get(0)?.icon = ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
|
menuInflater.inflate(R.menu.my_menu, menu)
|
||||||
|
myMenu = menu
|
||||||
|
checkAndUpdateUsbConnection()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requestCoarseLocationPermission() {
|
||||||
|
val coarseLocationPermission = Manifest.permission.ACCESS_COARSE_LOCATION
|
||||||
|
val coarseLocationPermissionRequestCode = 101
|
||||||
|
|
||||||
|
if (ContextCompat.checkSelfPermission(
|
||||||
|
this,
|
||||||
|
coarseLocationPermission
|
||||||
|
) != PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
ActivityCompat.requestPermissions(
|
||||||
|
this,
|
||||||
|
arrayOf(coarseLocationPermission),
|
||||||
|
coarseLocationPermissionRequestCode
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
getLocation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requestFineLocationPermission() {
|
||||||
|
val fineLocationPermission = Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
|
val fineLocationPermissionRequestCode = 102
|
||||||
|
|
||||||
|
if (ContextCompat.checkSelfPermission(
|
||||||
|
this,
|
||||||
|
fineLocationPermission
|
||||||
|
) != PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
ActivityCompat.requestPermissions(
|
||||||
|
this,
|
||||||
|
arrayOf(fineLocationPermission),
|
||||||
|
fineLocationPermissionRequestCode
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
getLocation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLocation() {
|
||||||
|
val coarseLocationPermission = Manifest.permission.ACCESS_COARSE_LOCATION
|
||||||
|
val fineLocationPermission = Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
|
|
||||||
|
if (ActivityCompat.checkSelfPermission(
|
||||||
|
this,
|
||||||
|
coarseLocationPermission
|
||||||
|
) != PackageManager.PERMISSION_GRANTED &&
|
||||||
|
ActivityCompat.checkSelfPermission(
|
||||||
|
this,
|
||||||
|
fineLocationPermission
|
||||||
|
) != PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
// Handle location permission request if needed
|
||||||
|
Toast.makeText(this, "Please enable location services", Toast.LENGTH_SHORT).show()
|
||||||
|
requestCoarseLocationPermission()
|
||||||
|
requestFineLocationPermission()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fusedLocationClient.lastLocation
|
||||||
|
.addOnSuccessListener { location: Location? ->
|
||||||
|
location?.let {
|
||||||
|
DataHolder.location = UserData.Location(location.latitude, location.longitude)
|
||||||
|
Log.i("Location", DataHolder.location.toString())
|
||||||
|
} ?: run {
|
||||||
|
requestLocationUpdates()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.addOnFailureListener { exception: Exception ->
|
||||||
|
exception.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requestLocationUpdates() {
|
||||||
|
val locationRequest = LocationRequest.create().apply {
|
||||||
|
interval = 10000 // Interval for receiving location updates (in milliseconds)
|
||||||
|
fastestInterval = 5000 // Fastest interval for location updates (in milliseconds)
|
||||||
|
priority = LocationRequest.PRIORITY_HIGH_ACCURACY // Location accuracy priority
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ActivityCompat.checkSelfPermission(
|
||||||
|
this,
|
||||||
|
Manifest.permission.ACCESS_COARSE_LOCATION
|
||||||
|
) != PackageManager.PERMISSION_GRANTED &&
|
||||||
|
ActivityCompat.checkSelfPermission(
|
||||||
|
this,
|
||||||
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
|
) != PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stopLocationUpdates() {
|
||||||
|
fusedLocationClient.removeLocationUpdates(locationCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
stopLocationUpdates()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRequestPermissionsResult(
|
||||||
|
requestCode: Int,
|
||||||
|
permissions: Array<String>,
|
||||||
|
grantResults: IntArray
|
||||||
|
) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
|
when (requestCode) {
|
||||||
|
101 -> {
|
||||||
|
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// Coarse location permission granted
|
||||||
|
requestFineLocationPermission()
|
||||||
|
} else {
|
||||||
|
// Coarse location permission denied
|
||||||
|
Toast.makeText(this, "Coarse location permission denied", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
102 -> {
|
||||||
|
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// Fine location permission granted
|
||||||
|
getLocation()
|
||||||
|
} else {
|
||||||
|
// Fine location permission denied
|
||||||
|
Toast.makeText(this, "Fine location permission denied", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation
|
package com.example.hpostesting.presentation
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
package com.example.hpostesting.presentation
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Environment
|
||||||
|
import android.provider.Settings
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.example.hpostesting.data.DataHolder
|
||||||
|
import com.example.hpostesting.presentation.dashboard.DashboardActivity
|
||||||
|
import com.example.hpostesting.util.MyUtils
|
||||||
|
import com.google.firebase.firestore.FirebaseFirestoreSettings
|
||||||
|
import com.google.firebase.firestore.ktx.firestore
|
||||||
|
import com.google.firebase.ktx.Firebase
|
||||||
|
import `in`.sminnovations.hpostesting.databinding.ActivitySplashBinding
|
||||||
|
|
||||||
|
class SplashActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var binding: ActivitySplashBinding
|
||||||
|
|
||||||
|
private val requiredPermissions = listOf(
|
||||||
|
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||||
|
Manifest.permission.CAMERA,
|
||||||
|
Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||||
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
|
)
|
||||||
|
|
||||||
|
private var allPermissionsGranted = false
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = ActivitySplashBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
setupFirestoreCache()
|
||||||
|
setupStaticConstants()
|
||||||
|
|
||||||
|
requestPermissions()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupStaticConstants() {
|
||||||
|
DataHolder.mobileUniqueId =
|
||||||
|
Settings.Secure.getString(applicationContext.contentResolver, Settings.Secure.ANDROID_ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupFirestoreCache() {
|
||||||
|
val settings = FirebaseFirestoreSettings.Builder()
|
||||||
|
.setCacheSizeBytes(FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED)
|
||||||
|
.build()
|
||||||
|
Firebase.firestore.firestoreSettings = settings
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requestPermissions() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
requestPermissionsAboveAndroidR()
|
||||||
|
} else {
|
||||||
|
requestPermissionsBelowAndroidR()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.R)
|
||||||
|
private fun requestPermissionsAboveAndroidR() {
|
||||||
|
if (Environment.isExternalStorageManager()) {
|
||||||
|
handlePermissionsResult(true)
|
||||||
|
} else {
|
||||||
|
val requestPermissionLauncher =
|
||||||
|
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||||
|
if (Environment.isExternalStorageManager()) {
|
||||||
|
handlePermissionsResult(true)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(
|
||||||
|
this,
|
||||||
|
"You must grant permission to access all files to use the app",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
|
||||||
|
requestPermissionLauncher.launch(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requestPermissionsBelowAndroidR() {
|
||||||
|
val permissionsToRequest = requiredPermissions
|
||||||
|
.filterNot { permission ->
|
||||||
|
ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
|
||||||
|
}
|
||||||
|
.toTypedArray()
|
||||||
|
|
||||||
|
if (permissionsToRequest.isNotEmpty()) {
|
||||||
|
requestPermissionLauncher.launch(permissionsToRequest)
|
||||||
|
} else {
|
||||||
|
checkLocationAndCameraPermissions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkLocationAndCameraPermissions() {
|
||||||
|
val fineLocationPermission = Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
|
val coarseLocationPermission = Manifest.permission.ACCESS_COARSE_LOCATION
|
||||||
|
val cameraPermission = Manifest.permission.CAMERA
|
||||||
|
val locationPermissionsGranted =
|
||||||
|
ContextCompat.checkSelfPermission(this, fineLocationPermission) == PackageManager.PERMISSION_GRANTED &&
|
||||||
|
ContextCompat.checkSelfPermission(this, coarseLocationPermission) == PackageManager.PERMISSION_GRANTED
|
||||||
|
val cameraPermissionGranted = ContextCompat.checkSelfPermission(this, cameraPermission) == PackageManager.PERMISSION_GRANTED
|
||||||
|
|
||||||
|
if (locationPermissionsGranted && cameraPermissionGranted) {
|
||||||
|
handlePermissionsResult(true)
|
||||||
|
} else {
|
||||||
|
val permissionsToRequest = mutableListOf<String>()
|
||||||
|
if (!locationPermissionsGranted) {
|
||||||
|
permissionsToRequest.add(fineLocationPermission)
|
||||||
|
permissionsToRequest.add(coarseLocationPermission)
|
||||||
|
}
|
||||||
|
if (!cameraPermissionGranted) {
|
||||||
|
permissionsToRequest.add(cameraPermission)
|
||||||
|
}
|
||||||
|
|
||||||
|
requestPermissionLauncher.launch(permissionsToRequest.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val requestPermissionLauncher =
|
||||||
|
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
|
||||||
|
val grantedPermissions = permissions.entries.filter { it.value }.map { it.key }
|
||||||
|
handlePermissionsResult(grantedPermissions.size == requiredPermissions.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handlePermissionsResult(allGranted: Boolean) {
|
||||||
|
allPermissionsGranted = allGranted
|
||||||
|
if (allGranted) {
|
||||||
|
moveToLandingPage()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "All permissions are required to use the app.", Toast.LENGTH_SHORT).show()
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun moveToLandingPage() {
|
||||||
|
createAppFolder()
|
||||||
|
val intent = Intent(applicationContext, DashboardActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createAppFolder() {
|
||||||
|
val folderPath = MyUtils.createAppFolder(applicationContext)
|
||||||
|
if (folderPath != null) {
|
||||||
|
DataHolder.isAppFolderCreated = true
|
||||||
|
DataHolder.appFolderPath = folderPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation
|
package com.example.hpostesting.presentation
|
||||||
|
|
||||||
interface UsbServiceListener {
|
interface UsbServiceListener {
|
||||||
fun onUsbRead(data: ByteArray?)
|
fun onUsbRead(data: ByteArray?)
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.example.hpostesting.presentation.adapter
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.navigation.findNavController
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.example.hpostesting.data.DataHolder
|
||||||
|
import com.example.hpostesting.data.model.patient.UserData
|
||||||
|
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
|
||||||
|
import com.firebase.ui.firestore.FirestoreRecyclerOptions
|
||||||
|
import `in`.sminnovations.hpostesting.R
|
||||||
|
import `in`.sminnovations.hpostesting.databinding.UserItemViewBinding
|
||||||
|
|
||||||
|
class UserListAdapter(options: FirestoreRecyclerOptions<UserData>, private val view: View) :
|
||||||
|
FirestoreRecyclerAdapter<UserData, UserListAdapter.OrderItemViewHolder>(options) {
|
||||||
|
|
||||||
|
class OrderItemViewHolder(val binding: UserItemViewBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root)
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OrderItemViewHolder {
|
||||||
|
return OrderItemViewHolder(
|
||||||
|
UserItemViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
override fun onBindViewHolder(holder: OrderItemViewHolder, position: Int, model: UserData) {
|
||||||
|
holder.binding.apply {
|
||||||
|
userName.text = model.name
|
||||||
|
userId.text = model._id
|
||||||
|
Glide.with(view).load(model.userImage).into(userImage)
|
||||||
|
if (model.testStatus != null) {
|
||||||
|
if (model.testStatus!!) {
|
||||||
|
userCard.setCardBackgroundColor(view.resources.getColor(R.color.gray))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
userCard.setOnClickListener {
|
||||||
|
if (model.testStatus != null) {
|
||||||
|
if (model.testStatus!!) {
|
||||||
|
Toast.makeText(
|
||||||
|
view.context,
|
||||||
|
"Test has been already conducted for this user",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
} else {
|
||||||
|
DataHolder.selectedTest = model
|
||||||
|
view.findNavController().navigate(R.id.action_nav_home_to_mainActivity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,27 +1,24 @@
|
|||||||
package com.example.hpos.presentation.dashboard
|
package com.example.hpostesting.presentation.dashboard
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
import androidx.drawerlayout.widget.DrawerLayout
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import androidx.navigation.ui.AppBarConfiguration
|
import androidx.navigation.ui.AppBarConfiguration
|
||||||
import androidx.navigation.ui.navigateUp
|
import androidx.navigation.ui.navigateUp
|
||||||
import androidx.navigation.ui.setupActionBarWithNavController
|
import androidx.navigation.ui.setupActionBarWithNavController
|
||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.navigation.ui.setupWithNavController
|
||||||
import com.example.hpos.R
|
|
||||||
import com.example.hpos.databinding.ActivityDashboardBinding
|
|
||||||
import com.example.hpos.util.MyUtils
|
|
||||||
import com.example.hpos.util.MyViewModelFactory
|
|
||||||
import com.google.android.material.navigation.NavigationView
|
import com.google.android.material.navigation.NavigationView
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import `in`.sminnovations.hpostesting.R
|
||||||
|
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
class DashboardActivity : AppCompatActivity() {
|
class DashboardActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
private lateinit var appBarConfiguration: AppBarConfiguration
|
||||||
private lateinit var binding: ActivityDashboardBinding
|
private lateinit var binding: ActivityDashboardBinding
|
||||||
private lateinit var viewModel: DashboardViewModel
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -43,10 +40,6 @@ class DashboardActivity : AppCompatActivity() {
|
|||||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||||
navView.setupWithNavController(navController)
|
navView.setupWithNavController(navController)
|
||||||
|
|
||||||
viewModel = ViewModelProvider(
|
|
||||||
this,
|
|
||||||
MyViewModelFactory()
|
|
||||||
)[DashboardViewModel::class.java]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.dashboard
|
package com.example.hpostesting.presentation.dashboard
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@@ -6,8 +6,8 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import com.example.hpos.databinding.FragmentGalleryBinding
|
import com.example.hpostesting.presentation.dashboard.ui.gallery.GalleryViewModel
|
||||||
import com.example.hpos.presentation.dashboard.ui.gallery.GalleryViewModel
|
import `in`.sminnovations.hpostesting.databinding.FragmentGalleryBinding
|
||||||
|
|
||||||
class GalleryFragment : Fragment() {
|
class GalleryFragment : Fragment() {
|
||||||
|
|
||||||
@@ -0,0 +1,199 @@
|
|||||||
|
package com.example.hpostesting.presentation.dashboard
|
||||||
|
|
||||||
|
import android.app.AlertDialog
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.example.hpostesting.data.DataHolder
|
||||||
|
import com.example.hpostesting.data.model.patient.UserData
|
||||||
|
import com.example.hpostesting.presentation.adapter.UserListAdapter
|
||||||
|
import com.example.hpostesting.presentation.testRight.TestRightViewModel
|
||||||
|
import com.firebase.ui.firestore.FirestoreRecyclerOptions
|
||||||
|
import com.google.firebase.firestore.ktx.firestore
|
||||||
|
import com.google.firebase.ktx.Firebase
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import `in`.sminnovations.hpostesting.R
|
||||||
|
import `in`.sminnovations.hpostesting.databinding.FragmentHomeBinding
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class HomeFragment : Fragment() {
|
||||||
|
|
||||||
|
private var _binding: FragmentHomeBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
private val viewModel: TestRightViewModel by activityViewModels()
|
||||||
|
private lateinit var rvAdapter: UserListAdapter
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
||||||
|
DataHolder.selectedTest = null
|
||||||
|
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
viewModel.allUserData.observe(viewLifecycleOwner) { userData ->
|
||||||
|
deleteIncompleteRegistrations(userData)
|
||||||
|
}
|
||||||
|
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isConnected ->
|
||||||
|
if (isConnected) {
|
||||||
|
binding.internetAvailableCL.visibility = View.VISIBLE
|
||||||
|
binding.internetNotAvailableCL.visibility = View.GONE
|
||||||
|
loadUserData()
|
||||||
|
setSearch()
|
||||||
|
checkForLocalDBData()
|
||||||
|
} else {
|
||||||
|
binding.internetAvailableCL.visibility = View.GONE
|
||||||
|
binding.internetNotAvailableCL.visibility = View.VISIBLE
|
||||||
|
setUserId()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.uploadData.setOnClickListener {
|
||||||
|
showUploadDialog(requireContext())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setUserId() {
|
||||||
|
binding.btnSubmit.setOnClickListener {
|
||||||
|
val userId = binding.userId.text.toString()
|
||||||
|
if (userId.length >= 18) {
|
||||||
|
val userData = UserData(_id = userId)
|
||||||
|
DataHolder.selectedTest = userData
|
||||||
|
findNavController().navigate(R.id.action_nav_home_to_mainActivity)
|
||||||
|
} else {
|
||||||
|
val errorMessage = getString(R.string.user_id_error_message)
|
||||||
|
Toast.makeText(requireContext(), errorMessage, Toast.LENGTH_SHORT).show()
|
||||||
|
binding.userId.error = errorMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadUserData() {
|
||||||
|
val query = Firebase.firestore.collection("patientData")
|
||||||
|
val recyclerViewOptions =
|
||||||
|
FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java)
|
||||||
|
.build()
|
||||||
|
rvAdapter = UserListAdapter(recyclerViewOptions, binding.root)
|
||||||
|
binding.rvOrder.adapter = rvAdapter
|
||||||
|
rvAdapter.startListening()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getData(search: String?, field: String) {
|
||||||
|
val capitalizedSearch =
|
||||||
|
search?.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
|
||||||
|
Log.i("Capital", capitalizedSearch.toString())
|
||||||
|
|
||||||
|
val query = Firebase.firestore.collection("patientData")
|
||||||
|
.orderBy(field)
|
||||||
|
.whereArrayContainsAny(field, listOf(capitalizedSearch))
|
||||||
|
|
||||||
|
val recyclerViewOptions =
|
||||||
|
FirestoreRecyclerOptions.Builder<UserData>().setQuery(query, UserData::class.java)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
rvAdapter = UserListAdapter(recyclerViewOptions, binding.root)
|
||||||
|
binding.rvOrder.adapter = rvAdapter
|
||||||
|
rvAdapter.startListening()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setSearch() {
|
||||||
|
binding.searchProduct.setOnQueryTextListener(object :
|
||||||
|
androidx.appcompat.widget.SearchView.OnQueryTextListener {
|
||||||
|
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||||
|
return if (!query.isNullOrEmpty()) {
|
||||||
|
val field = when {
|
||||||
|
binding.userIdRadioButton.isChecked -> "_id"
|
||||||
|
binding.abhaIdRadioButton.isChecked -> "abhaId"
|
||||||
|
binding.aadharIdRadioButton.isChecked -> "aadharId"
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
field?.let { getData(query, it) }
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
loadUserData()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onQueryTextChange(query: String?): Boolean {
|
||||||
|
return if (!query.isNullOrEmpty()) {
|
||||||
|
val field = when {
|
||||||
|
binding.userIdRadioButton.isChecked -> "_id"
|
||||||
|
binding.abhaIdRadioButton.isChecked -> "abhaId"
|
||||||
|
binding.aadharIdRadioButton.isChecked -> "aadharId"
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
field?.let { getData(query, it) }
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
loadUserData()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkForLocalDBData() {
|
||||||
|
viewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
|
||||||
|
val uploadDataVisibility = if (userDataList.isEmpty()) View.GONE else View.VISIBLE
|
||||||
|
binding.uploadData.visibility = uploadDataVisibility
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showUploadDialog(context: Context) {
|
||||||
|
val builder = AlertDialog.Builder(context)
|
||||||
|
builder.setTitle(R.string.upload_db_registration_title)
|
||||||
|
builder.setMessage(R.string.upload_db_registration_message)
|
||||||
|
|
||||||
|
builder.setPositiveButton(R.string.upload) { dialog, _ ->
|
||||||
|
uploadLocalDBData(dialog)
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.setNegativeButton(R.string.cancel) { dialog, _ ->
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
val dialog = builder.create()
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun uploadLocalDBData(dialog: DialogInterface) {
|
||||||
|
viewModel.allUserData.observe(viewLifecycleOwner) { userDataList ->
|
||||||
|
if (userDataList.isEmpty()) {
|
||||||
|
dialog.dismiss()
|
||||||
|
} else {
|
||||||
|
userDataList.forEach { userData ->
|
||||||
|
viewModel.bulkUploadResultToDatabase(userData)
|
||||||
|
viewModel.deleteById(userData._id)
|
||||||
|
}
|
||||||
|
dialog.dismiss()
|
||||||
|
Toast.makeText(requireContext(), R.string.upload_success_message, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deleteIncompleteRegistrations(userDataList: List<UserData>) {
|
||||||
|
userDataList.forEach { userData ->
|
||||||
|
if (userData._id.isEmpty()) {
|
||||||
|
viewModel.deleteById(userData._id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.dashboard
|
package com.example.hpostesting.presentation.dashboard
|
||||||
|
|
||||||
interface ItemClickListener {
|
interface ItemClickListener {
|
||||||
fun onClick(pos: Int)
|
fun onClick(pos: Int)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.dashboard
|
package com.example.hpostesting.presentation.dashboard
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@@ -6,8 +6,8 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import com.example.hpos.databinding.FragmentSlideshowBinding
|
import com.example.hpostesting.presentation.dashboard.ui.slideshow.SlideshowViewModel
|
||||||
import com.example.hpos.presentation.dashboard.ui.slideshow.SlideshowViewModel
|
import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding
|
||||||
|
|
||||||
class SlideshowFragment : Fragment() {
|
class SlideshowFragment : Fragment() {
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.dashboard.ui.gallery
|
package com.example.hpostesting.presentation.dashboard.ui.gallery
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.dashboard.ui.home
|
package com.example.hpostesting.presentation.dashboard.ui.home
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.dashboard.ui.slideshow
|
package com.example.hpostesting.presentation.dashboard.ui.slideshow
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.testRight
|
package com.example.hpostesting.presentation.testRight
|
||||||
|
|
||||||
class InputData {
|
class InputData {
|
||||||
val inputRead = "0,1.69989422e-06,1.60642711e-01,3.85754470e+02,0,0,1,0,FFF-EEEE-PPPP-WW-YY-NNNN\nOK [0]"
|
val inputRead = "0,1.69989422e-06,1.60642711e-01,3.85754470e+02,0,0,1,0,FFF-EEEE-PPPP-WW-YY-NNNN\nOK [0]"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.testRight
|
package com.example.hpostesting.presentation.testRight
|
||||||
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
@@ -15,23 +15,24 @@ import android.os.IBinder
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.get
|
import androidx.core.view.get
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import com.example.hpostesting.data.DataHolder
|
||||||
import com.example.hpos.R
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpos.data.DataHolder
|
|
||||||
import com.example.hpos.data.constant.Constants
|
|
||||||
import com.example.hpos.databinding.ActivityTestRightBinding
|
|
||||||
import com.example.hpos.util.MyViewModelFactory
|
|
||||||
import com.hoho.android.usbserial.driver.UsbSerialDriver
|
import com.hoho.android.usbserial.driver.UsbSerialDriver
|
||||||
import com.hoho.android.usbserial.driver.UsbSerialProber
|
import com.hoho.android.usbserial.driver.UsbSerialProber
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import `in`.sminnovations.hpostesting.R
|
||||||
|
import `in`.sminnovations.hpostesting.databinding.ActivityTestRightBinding
|
||||||
|
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
class TestRightActivity : AppCompatActivity() {
|
class TestRightActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var binding: ActivityTestRightBinding
|
private lateinit var binding: ActivityTestRightBinding
|
||||||
private lateinit var viewModel: TestRightViewModel
|
private val viewModel by viewModels<TestRightViewModel>()
|
||||||
private var myMenu: Menu? = null
|
private var myMenu: Menu? = null
|
||||||
|
|
||||||
private lateinit var mDriver: UsbSerialDriver
|
private lateinit var mDriver: UsbSerialDriver
|
||||||
@@ -78,10 +79,6 @@ class TestRightActivity : AppCompatActivity() {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityTestRightBinding.inflate(layoutInflater)
|
binding = ActivityTestRightBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
viewModel = ViewModelProvider(
|
|
||||||
this,
|
|
||||||
MyViewModelFactory()
|
|
||||||
)[TestRightViewModel::class.java]
|
|
||||||
|
|
||||||
setSupportActionBar(binding.myToolbar)
|
setSupportActionBar(binding.myToolbar)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.testRight
|
package com.example.hpostesting.presentation.testRight
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
@@ -10,17 +10,19 @@ import android.view.ViewGroup
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import com.example.hpos.R
|
import com.example.hpostesting.data.DataHolder
|
||||||
import com.example.hpos.data.DataHolder
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpos.data.constant.Constants
|
import com.example.hpostesting.data.constant.TestRightCommands
|
||||||
import com.example.hpos.data.constant.TestRightCommands
|
import com.example.hpostesting.data.model.ErrorMessage
|
||||||
import com.example.hpos.data.model.ErrorMessage
|
import com.example.hpostesting.presentation.UsbServiceListener
|
||||||
import com.example.hpos.databinding.FragmentTestRightExpReferenceBinding
|
import com.example.hpostesting.presentation.utils.MyDialogListener
|
||||||
import com.example.hpos.presentation.UsbServiceListener
|
import com.example.hpostesting.presentation.utils.UIUtils
|
||||||
import com.example.hpos.presentation.utils.MyDialogListener
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.example.hpos.presentation.utils.UIUtils
|
import `in`.sminnovations.hpostesting.R
|
||||||
|
import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpReferenceBinding
|
||||||
|
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
class TestRightExpReference : Fragment() {
|
class TestRightExpReference : Fragment() {
|
||||||
|
|
||||||
private lateinit var binding: FragmentTestRightExpReferenceBinding
|
private lateinit var binding: FragmentTestRightExpReferenceBinding
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.testRight
|
package com.example.hpostesting.presentation.testRight
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -10,19 +10,20 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import com.example.hpos.R
|
import com.example.hpostesting.data.DataHolder
|
||||||
import com.example.hpos.data.DataHolder
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpos.data.PreferenceUtility
|
import com.example.hpostesting.data.constant.TestRightCommands
|
||||||
import com.example.hpos.data.constant.Constants
|
import com.example.hpostesting.data.model.ErrorMessage
|
||||||
import com.example.hpos.data.constant.TestRightCommands
|
import com.example.hpostesting.data.model.test.TestType
|
||||||
import com.example.hpos.data.model.ErrorMessage
|
import com.example.hpostesting.presentation.MainActivity
|
||||||
import com.example.hpos.data.model.test.TestType
|
import com.example.hpostesting.presentation.UsbServiceListener
|
||||||
import com.example.hpos.databinding.FragmentTestRightExpSampleBinding
|
import com.example.hpostesting.presentation.utils.MyDialogListener
|
||||||
import com.example.hpos.presentation.MainActivity
|
import com.example.hpostesting.presentation.utils.UIUtils
|
||||||
import com.example.hpos.presentation.UsbServiceListener
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.example.hpos.presentation.utils.MyDialogListener
|
import `in`.sminnovations.hpostesting.R
|
||||||
import com.example.hpos.presentation.utils.UIUtils
|
import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpSampleBinding
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
class TestRightExpSample : Fragment() {
|
class TestRightExpSample : Fragment() {
|
||||||
|
|
||||||
private lateinit var binding: FragmentTestRightExpSampleBinding
|
private lateinit var binding: FragmentTestRightExpSampleBinding
|
||||||
@@ -256,11 +257,9 @@ class TestRightExpSample : Fragment() {
|
|||||||
|
|
||||||
// val fileNameCsv = prefixCsv + id + fileExtensionCsv
|
// val fileNameCsv = prefixCsv + id + fileExtensionCsv
|
||||||
|
|
||||||
|
|
||||||
// NEW ------------------------------
|
// NEW ------------------------------
|
||||||
viewModel.saveCsv(requireContext().applicationContext, viewModel.getCSVFileName())
|
viewModel.saveCsv(requireContext().applicationContext, viewModel.getCSVFileName())
|
||||||
viewModel.saveCsvForTesting(requireContext().applicationContext, viewModel.getDetailedCSVFileName())
|
// viewModel.saveCsvForTesting(requireContext().applicationContext, viewModel.getDetailedCSVFileName())
|
||||||
|
|
||||||
viewModel.saveLogWithPatient(requireContext().applicationContext, viewModel.getLogFileName())
|
viewModel.saveLogWithPatient(requireContext().applicationContext, viewModel.getLogFileName())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.testRight
|
package com.example.hpostesting.presentation.testRight
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -9,32 +9,35 @@ import android.view.ViewGroup
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import com.example.hpos.R
|
import com.example.hpostesting.data.DataHolder
|
||||||
import com.example.hpos.data.DataHolder
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpos.data.PreferenceUtility
|
import com.example.hpostesting.data.model.test.TestRightResultType
|
||||||
import com.example.hpos.data.constant.Constants
|
import com.example.hpostesting.data.model.test.TestType
|
||||||
import com.example.hpos.data.model.test.TestRightResultType
|
import com.example.hpostesting.presentation.dashboard.DashboardActivity
|
||||||
import com.example.hpos.data.model.test.TestType
|
import com.example.hpostesting.util.MyUtils.calculateAgeFromYOB
|
||||||
import com.example.hpos.databinding.FragmentTestRightResultsBinding
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.example.hpos.presentation.dashboard.DashboardActivity
|
import `in`.sminnovations.hpostesting.R
|
||||||
import com.example.hpos.util.MyUtils
|
import `in`.sminnovations.hpostesting.databinding.FragmentTestRightResultsBinding
|
||||||
import com.example.hpos.util.MyUtils.calculateAgeFromYOB
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
class TestRightResults : Fragment() {
|
class TestRightResults : Fragment() {
|
||||||
|
|
||||||
private lateinit var binding: FragmentTestRightResultsBinding
|
private lateinit var binding: FragmentTestRightResultsBinding
|
||||||
private val viewModel: TestRightViewModel by activityViewModels()
|
private val viewModel: TestRightViewModel by activityViewModels()
|
||||||
|
|
||||||
private val TAG = "TestRightResults"
|
private val TAG = "TestRightResults"
|
||||||
|
private var isOnline = false
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
): View {
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
binding = FragmentTestRightResultsBinding.inflate(inflater, container, false)
|
binding = FragmentTestRightResultsBinding.inflate(inflater, container, false)
|
||||||
|
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
|
||||||
|
isOnline = isNetworkAvailable
|
||||||
|
}
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,14 +46,13 @@ class TestRightResults : Fragment() {
|
|||||||
setupListeners()
|
setupListeners()
|
||||||
updateResults()
|
updateResults()
|
||||||
|
|
||||||
viewModel.addResultTestToDb()
|
viewModel.fireBaseUpload.observe(viewLifecycleOwner) {
|
||||||
|
if (it == "Success") {
|
||||||
// This is to add files to the pending queue
|
Toast.makeText(
|
||||||
viewModel.addFilesToQueue(requireContext())
|
requireContext(), "Test Results Upload Successfully", Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
// Uploading to cloud storage and deleting the from the pending queue when uploaded
|
}
|
||||||
if (MyUtils.isInternetConnected()) {
|
binding.progressBar.visibility = View.GONE
|
||||||
viewModel.addFilesToCloud(requireContext())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -68,35 +70,49 @@ class TestRightResults : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateResults() {
|
private fun updateResults() {
|
||||||
binding.tvName.text = getString(R.string.name_in_textview, viewModel.testDetails?.patientName)
|
if (viewModel.testDetails?.name == "" && viewModel.testDetails?.birthYear == "") {
|
||||||
binding.tvAge.text =
|
binding.tvName.visibility = View.GONE
|
||||||
getString(R.string.age_in_textview, viewModel.testDetails?.patientAge?.calculateAgeFromYOB().toString())
|
binding.tvAge.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
binding.tvName.text = getString(R.string.name_in_textview, viewModel.testDetails?.name)
|
||||||
|
binding.tvAge.text = getString(
|
||||||
|
R.string.age_in_textview,
|
||||||
|
viewModel.testDetails?.birthYear?.toInt()?.calculateAgeFromYOB().toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
binding.tvId.text = getString(R.string.patient_id_in_tv, viewModel.testDetails?.patientID)
|
binding.tvId.text = getString(R.string.patient_id_in_tv, viewModel.testDetails?._id)
|
||||||
|
|
||||||
|
|
||||||
if (DataHolder.selectedTestType == TestType.SICKLECERT){
|
if (DataHolder.selectedTestType == TestType.SICKLECERT) {
|
||||||
when (viewModel.testDetails?.result) {
|
when (viewModel.testDetails?.result) {
|
||||||
TestRightResultType.NORMAL -> {
|
TestRightResultType.NORMAL -> {
|
||||||
binding.resultNormal.visibility = View.VISIBLE
|
binding.resultNormal.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
TestRightResultType.SICKLECELLDISEASE -> {
|
TestRightResultType.SICKLECELLDISEASE -> {
|
||||||
binding.resultDisease.visibility = View.VISIBLE
|
binding.resultDisease.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
TestRightResultType.SICKLECELLTRAIT -> {
|
TestRightResultType.SICKLECELLTRAIT -> {
|
||||||
binding.resultTrait.visibility = View.VISIBLE
|
binding.resultTrait.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
TestRightResultType.POSITIVEBORDERLINE -> {
|
TestRightResultType.POSITIVEBORDERLINE -> {
|
||||||
binding.resultPositiveBorderline.visibility = View.VISIBLE
|
binding.resultPositiveBorderline.visibility = View.VISIBLE
|
||||||
binding.tvRecommended.visibility = View.VISIBLE
|
binding.tvRecommended.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
TestRightResultType.NEGATIVEBORDERLINE -> {
|
TestRightResultType.NEGATIVEBORDERLINE -> {
|
||||||
binding.resultNegativeBorderline.visibility = View.VISIBLE
|
binding.resultNegativeBorderline.visibility = View.VISIBLE
|
||||||
binding.tvRecommended.visibility = View.VISIBLE
|
binding.tvRecommended.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
// binding.resultUndefined.visibility = View.VISIBLE
|
// binding.resultUndefined.visibility = View.VISIBLE
|
||||||
Toast.makeText(requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG).show()
|
Toast.makeText(
|
||||||
|
requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
moveToSamplePage()
|
moveToSamplePage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,20 +122,31 @@ class TestRightResults : Fragment() {
|
|||||||
binding.resultDisease.visibility = View.VISIBLE
|
binding.resultDisease.visibility = View.VISIBLE
|
||||||
binding.resultDisease.text = "Positive"
|
binding.resultDisease.text = "Positive"
|
||||||
}
|
}
|
||||||
|
|
||||||
TestRightResultType.NORMAL -> {
|
TestRightResultType.NORMAL -> {
|
||||||
binding.resultNormal.visibility = View.VISIBLE
|
binding.resultNormal.visibility = View.VISIBLE
|
||||||
binding.resultNormal.text = "Negative"
|
binding.resultNormal.text = "Negative"
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
Toast.makeText(requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG).show()
|
Toast.makeText(
|
||||||
|
requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
moveToSamplePage()
|
moveToSamplePage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if (viewModel.patientDetails.age < 5) {
|
if (isOnline) {
|
||||||
// binding.tvRecommended.visibility = View.VISIBLE
|
viewModel.uploadResultToDatabase(requireContext(), true)
|
||||||
// binding.tvRecommended.text = getString(R.string.recommended_age)
|
binding.progressBar.visibility = View.VISIBLE
|
||||||
// }
|
} else {
|
||||||
|
viewModel.uploadResultToDatabase(requireContext(), false)
|
||||||
|
Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
"Internet not available, Test Data added to Local DB",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -127,8 +154,7 @@ class TestRightResults : Fragment() {
|
|||||||
if (DataHolder.sampleReadCounter > Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE) {
|
if (DataHolder.sampleReadCounter > Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE) {
|
||||||
DataHolder.sampleReadCounter = 0
|
DataHolder.sampleReadCounter = 0
|
||||||
DataHolder.isReferenceTaken = false
|
DataHolder.isReferenceTaken = false
|
||||||
parentFragmentManager.beginTransaction()
|
parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightExpReference())
|
||||||
.replace(R.id.fl_main, TestRightExpReference())
|
|
||||||
.commit()
|
.commit()
|
||||||
} else {
|
} else {
|
||||||
parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightExpSample())
|
parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightExpSample())
|
||||||
@@ -144,55 +170,6 @@ class TestRightResults : Fragment() {
|
|||||||
|
|
||||||
viewModel.saveLog(requireContext().applicationContext, fileName)
|
viewModel.saveLog(requireContext().applicationContext, fileName)
|
||||||
|
|
||||||
// if (!DataHolder.isAppFolderCreated) {
|
|
||||||
// val folderPath = MyUtils.createAppFolder(requireContext().applicationContext)
|
|
||||||
// if (folderPath != null) {
|
|
||||||
// DataHolder.isAppFolderCreated = true
|
|
||||||
// DataHolder.appFolderPath = folderPath
|
|
||||||
// viewModel.saveLog(DataHolder.appFolderPath, fileName)
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// viewModel.saveLog(DataHolder.appFolderPath, fileName)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// private fun saveCsv() {
|
|
||||||
// Log.d(TAG, "saveCsv() called")
|
|
||||||
//
|
|
||||||
// val sdfDate = SimpleDateFormat("ddMMyyyy HHmmss")
|
|
||||||
// val fileName: String = sdfDate.format(Date()) + ".csv"
|
|
||||||
//
|
|
||||||
// if (!DataHolder.isAppFolderCreated) {
|
|
||||||
// val folderPath = MyUtils.createAppFolder(requireContext().applicationContext)
|
|
||||||
// if (folderPath != null) {
|
|
||||||
// DataHolder.isAppFolderCreated = true
|
|
||||||
// DataHolder.appFolderPath = folderPath
|
|
||||||
// viewModel.saveCsv(DataHolder.appFolderPath, fileName)
|
|
||||||
//
|
|
||||||
// viewModel.saveCsvForTesting(DataHolder.appFolderPath, "testing$fileName")
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// viewModel.saveCsv(DataHolder.appFolderPath, fileName)
|
|
||||||
//
|
|
||||||
// viewModel.saveCsvForTesting(DataHolder.appFolderPath, "testing$fileName")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
private fun saveCsv() {
|
|
||||||
Log.d(TAG, "saveCsv() called")
|
|
||||||
|
|
||||||
// val sdfDate = SimpleDateFormat("ddMMyyyy HHmmss")
|
|
||||||
// val fileName: String = sdfDate.format(Date()) + ".csv"
|
|
||||||
|
|
||||||
val prefix = "HPOSSC_${DataHolder.deviceSerialNumber}_"
|
|
||||||
val fileExtension = ".csv"
|
|
||||||
|
|
||||||
val fileName = PreferenceUtility.generateId(requireContext(), prefix) + fileExtension
|
|
||||||
|
|
||||||
|
|
||||||
viewModel.saveCsv(requireContext().applicationContext, fileName)
|
|
||||||
viewModel.saveCsvForTesting(requireContext().applicationContext, "testing$fileName")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,56 +1,67 @@
|
|||||||
package com.example.hpos.presentation.testRight
|
package com.example.hpostesting.presentation.testRight
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.example.hpos.data.DataHolder
|
import com.example.hpostesting.data.DataHolder
|
||||||
import com.example.hpos.data.repository.DatabaseRepository
|
import com.example.hpostesting.data.NetworkStatusLiveData
|
||||||
import com.example.hpos.data.model.Response
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpos.data.constant.Constants
|
import com.example.hpostesting.data.dao.UserDao
|
||||||
import com.example.hpos.data.model.CalculationVariableForTest
|
import com.example.hpostesting.data.model.CalculationVariableForTest
|
||||||
import com.example.hpos.data.model.ErrorMessage
|
import com.example.hpostesting.data.model.ErrorMessage
|
||||||
import com.example.hpos.data.model.PendingUploads
|
import com.example.hpostesting.data.model.Response
|
||||||
import com.example.hpos.data.model.test.Status
|
import com.example.hpostesting.data.model.patient.UserData
|
||||||
import com.example.hpos.data.model.test.TestRightCalculationData
|
import com.example.hpostesting.data.model.test.TestRightCalculationData
|
||||||
import com.example.hpos.data.model.test.TestRightDeviceConstants
|
import com.example.hpostesting.data.model.test.TestRightDeviceConstants
|
||||||
import com.example.hpos.data.model.test.TestType
|
import com.example.hpostesting.data.model.test.TestType
|
||||||
import com.example.hpos.domain.ResultCalculationWithMaxImpl
|
import com.example.hpostesting.data.repository.DatabaseRepository
|
||||||
import com.example.hpos.domain.SaveRawData
|
import com.example.hpostesting.domain.ResultCalculationWithMaxImpl
|
||||||
import com.example.hpos.domain.SaveRawDataTest
|
import com.example.hpostesting.domain.SaveRawData
|
||||||
import com.example.hpos.domain.SickleFindResultCaluculationWithMaxImpl
|
import com.example.hpostesting.domain.SaveRawDataTest
|
||||||
import com.example.hpos.domain.TestRightResultCalculation
|
import com.example.hpostesting.domain.SickleFindResultCaluculationWithMaxImpl
|
||||||
import com.example.hpos.util.MyUtils
|
import com.example.hpostesting.domain.TestRightResultCalculation
|
||||||
import kotlinx.coroutines.Dispatchers
|
import com.example.hpostesting.util.MyUtils
|
||||||
import kotlinx.coroutines.GlobalScope
|
import com.google.firebase.storage.FirebaseStorage
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.tasks.await
|
||||||
|
import java.io.File
|
||||||
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 javax.inject.Inject
|
||||||
import kotlin.math.log10
|
import kotlin.math.log10
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
class TestRightViewModel(
|
@HiltViewModel
|
||||||
|
class TestRightViewModel @Inject constructor(
|
||||||
private val saveRawData: SaveRawData,
|
private val saveRawData: SaveRawData,
|
||||||
private val saveRawDataTest: SaveRawDataTest,
|
private val saveRawDataTest: SaveRawDataTest,
|
||||||
private val repository: DatabaseRepository
|
private val repository: DatabaseRepository,
|
||||||
|
private val userDao: UserDao,
|
||||||
|
context: Context
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val TAG = "TestRightViewModel"
|
|
||||||
|
|
||||||
var isServiceConnected = false
|
var isServiceConnected = false
|
||||||
val progressBar = MutableLiveData(false)
|
val progressBar = MutableLiveData(false)
|
||||||
|
|
||||||
// val errorTriggered = MutableLiveData<String>("")
|
|
||||||
val errorTriggered = MutableLiveData<ErrorMessage>()
|
val errorTriggered = MutableLiveData<ErrorMessage>()
|
||||||
var numberOfSampleRun = 0
|
var numberOfSampleRun = 0
|
||||||
|
|
||||||
// lateinit var patientDetails: PatientData
|
val fireBaseUpload = MutableLiveData<String>()
|
||||||
|
|
||||||
val testDetails = DataHolder.selectedTest
|
val testDetails = DataHolder.selectedTest
|
||||||
|
|
||||||
// var deviceConstant: TestRightDeviceConstants? = null
|
private val _networkStatusLiveData = NetworkStatusLiveData(context)
|
||||||
|
val networkStatusLiveData: LiveData<Boolean>
|
||||||
|
get() = _networkStatusLiveData
|
||||||
|
|
||||||
|
val allUserData = userDao.getAll()
|
||||||
|
|
||||||
private lateinit var calculationData: TestRightCalculationData
|
private lateinit var calculationData: TestRightCalculationData
|
||||||
|
|
||||||
/* (For exp sample) Contains pixel no. -> Intensity of light falling on that pixel */
|
/* (For exp sample) Contains pixel no. -> Intensity of light falling on that pixel */
|
||||||
@@ -79,8 +90,7 @@ class TestRightViewModel(
|
|||||||
// "Error 201: In processing the data from device"
|
// "Error 201: In processing the data from device"
|
||||||
errorTriggered.postValue(
|
errorTriggered.postValue(
|
||||||
ErrorMessage(
|
ErrorMessage(
|
||||||
"Error 201: In processing the data from device",
|
"Error 201: In processing the data from device", Constants.ERROR_NORMAL
|
||||||
Constants.ERROR_NORMAL
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -89,8 +99,7 @@ class TestRightViewModel(
|
|||||||
// "Error 202: Unable to fetch data from device."
|
// "Error 202: Unable to fetch data from device."
|
||||||
errorTriggered.postValue(
|
errorTriggered.postValue(
|
||||||
ErrorMessage(
|
ErrorMessage(
|
||||||
"Error 202: Unable to fetch data from device.",
|
"Error 202: Unable to fetch data from device.", Constants.ERROR_NORMAL
|
||||||
Constants.ERROR_NORMAL
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -103,13 +112,9 @@ class TestRightViewModel(
|
|||||||
if (DataHolder.deviceConstant != null) {
|
if (DataHolder.deviceConstant != null) {
|
||||||
for (x in 1..Constants.TEST_RIGHT_TOTAL_PIXEL) {
|
for (x in 1..Constants.TEST_RIGHT_TOTAL_PIXEL) {
|
||||||
// val index = x - 1
|
// val index = x - 1
|
||||||
val wavelength: Double =
|
val wavelength: Double = (DataHolder.deviceConstant!!.a.toDouble() * (x.toDouble()
|
||||||
(DataHolder.deviceConstant!!.a.toDouble() * (x.toDouble()
|
.pow((3).toDouble()))) + (DataHolder.deviceConstant!!.b.toDouble() * (x.toDouble()
|
||||||
.pow((3).toDouble()))) +
|
.pow((2).toDouble()))) + (DataHolder.deviceConstant!!.c.toDouble() * x) + (DataHolder.deviceConstant!!.d.toDouble())
|
||||||
(DataHolder.deviceConstant!!.b.toDouble() * (x.toDouble()
|
|
||||||
.pow((2).toDouble()))) +
|
|
||||||
(DataHolder.deviceConstant!!.c.toDouble() * x) +
|
|
||||||
(DataHolder.deviceConstant!!.d.toDouble())
|
|
||||||
|
|
||||||
DataHolder.wavelengthToPixelArray.add(wavelength)
|
DataHolder.wavelengthToPixelArray.add(wavelength)
|
||||||
}
|
}
|
||||||
@@ -118,8 +123,7 @@ class TestRightViewModel(
|
|||||||
// "Error 203: Unable to fetch data from device."
|
// "Error 203: Unable to fetch data from device."
|
||||||
errorTriggered.postValue(
|
errorTriggered.postValue(
|
||||||
ErrorMessage(
|
ErrorMessage(
|
||||||
"Error 203: Unable to fetch data from device.",
|
"Error 203: Unable to fetch data from device.", Constants.ERROR_NORMAL
|
||||||
Constants.ERROR_NORMAL
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -136,22 +140,17 @@ class TestRightViewModel(
|
|||||||
val listOfString = fullString.split("\n")
|
val listOfString = fullString.split("\n")
|
||||||
|
|
||||||
for (line in listOfString) {
|
for (line in listOfString) {
|
||||||
if ("Buf" in line) {
|
if ("Buf" in line) {/* Removing trailing spaces and "Buf" from the string then taking lhs & rhs of ':' */
|
||||||
/* Removing trailing spaces and "Buf" from the string then taking lhs & rhs of ':' */
|
val numbers = line.trim().substring(3).split(":")
|
||||||
val numbers = line.trim()
|
|
||||||
.substring(3).split(":")
|
|
||||||
if (numbers.size >= 2) {
|
if (numbers.size >= 2) {
|
||||||
|
|
||||||
if (isReference)
|
if (isReference) DataHolder.intensityReferenceArray.add(numbers[1].toDouble())
|
||||||
DataHolder.intensityReferenceArray.add(numbers[1].toDouble())
|
else intensitySampleArray.add(numbers[1].toDouble())
|
||||||
else
|
|
||||||
intensitySampleArray.add(numbers[1].toDouble())
|
|
||||||
} else {
|
} else {
|
||||||
// "Error 204: Unable to fetch data from device."
|
// "Error 204: Unable to fetch data from device."
|
||||||
errorTriggered.postValue(
|
errorTriggered.postValue(
|
||||||
ErrorMessage(
|
ErrorMessage(
|
||||||
"Error 204: Unable to fetch data from device.",
|
"Error 204: Unable to fetch data from device.", Constants.ERROR_NORMAL
|
||||||
Constants.ERROR_NORMAL
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -265,7 +264,7 @@ class TestRightViewModel(
|
|||||||
|
|
||||||
testDetails?.result = calculationData.result
|
testDetails?.result = calculationData.result
|
||||||
testDetails?.resultRatio = calculationData.ratioValue
|
testDetails?.resultRatio = calculationData.ratioValue
|
||||||
testDetails?.testStatus = Status.COMPLETED
|
testDetails?.testStatus = true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +274,7 @@ class TestRightViewModel(
|
|||||||
SickleFindResultCaluculationWithMaxImpl()
|
SickleFindResultCaluculationWithMaxImpl()
|
||||||
calculationData = resultCalculation.getResults(wavelengthToAbsorbance)
|
calculationData = resultCalculation.getResults(wavelengthToAbsorbance)
|
||||||
testDetails?.result = calculationData.result
|
testDetails?.result = calculationData.result
|
||||||
testDetails?.testStatus = Status.COMPLETED
|
testDetails?.testStatus = true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,10 +368,7 @@ class TestRightViewModel(
|
|||||||
if (DataHolder.isAppFolderCreated) {
|
if (DataHolder.isAppFolderCreated) {
|
||||||
// SaveRawData().saveLogWithPatientData(
|
// SaveRawData().saveLogWithPatientData(
|
||||||
saveRawData.saveLogWithPatientData(
|
saveRawData.saveLogWithPatientData(
|
||||||
folderPath!!,
|
folderPath!!, fileName, calculationData, testDetails
|
||||||
fileName,
|
|
||||||
calculationData,
|
|
||||||
testDetails
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
folderPath = MyUtils.createAppFolder(appContext)
|
folderPath = MyUtils.createAppFolder(appContext)
|
||||||
@@ -381,10 +377,7 @@ class TestRightViewModel(
|
|||||||
DataHolder.appFolderPath = folderPath
|
DataHolder.appFolderPath = folderPath
|
||||||
// SaveRawData().saveLogWithPatientData(
|
// SaveRawData().saveLogWithPatientData(
|
||||||
saveRawData.saveLogWithPatientData(
|
saveRawData.saveLogWithPatientData(
|
||||||
folderPath,
|
folderPath, fileName, calculationData, testDetails
|
||||||
fileName,
|
|
||||||
calculationData,
|
|
||||||
testDetails
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// errorTriggered.postValue("Unable to save Log, Please try again")
|
// errorTriggered.postValue("Unable to save Log, Please try again")
|
||||||
@@ -427,129 +420,112 @@ class TestRightViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getCSVFileName(): String {
|
fun getCSVFileName(): String {
|
||||||
val prefixCsv: String = if (DataHolder.selectedTestType == TestType.SICKLECERT)
|
val prefixCsv: String =
|
||||||
"HPOSSC_${testDetails?.testID}"
|
if (DataHolder.selectedTestType == TestType.SICKLECERT) "HPOSSC_${testDetails?._id}"
|
||||||
else
|
else "HPOSSF_${testDetails?._id}"
|
||||||
"HPOSSF_${testDetails?.testID}"
|
|
||||||
|
|
||||||
val fileExtensionCsv = ".csv"
|
val fileExtensionCsv = ".csv"
|
||||||
|
|
||||||
return prefixCsv + fileExtensionCsv
|
return prefixCsv + fileExtensionCsv
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDetailedCSVFileName(): String {
|
|
||||||
return "detailed_" + getCSVFileName()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLogFileName(): String {
|
fun getLogFileName(): String {
|
||||||
val prefixTxt = "log_${testDetails?.testID}"
|
val prefixTxt = "log_${testDetails?._id}"
|
||||||
val fileExtensionTxt = ".txt"
|
val fileExtensionTxt = ".txt"
|
||||||
return prefixTxt + fileExtensionTxt
|
return prefixTxt + fileExtensionTxt
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addResultTestToDb() {
|
private fun addResultTestToDb() {
|
||||||
|
testDetails?.location = DataHolder.location
|
||||||
|
testDetails?.testTime = Calendar.getInstance().time.toString()
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
testDetails!!.uploadTime = Calendar.getInstance().time
|
testDetails!!.uploadTime = Calendar.getInstance().time.toString()
|
||||||
repository.addTestToDatabase(testDetails)
|
when (repository.addTestToDatabase(testDetails)) {
|
||||||
|
is Response.Success -> {
|
||||||
|
fireBaseUpload.postValue("Success")
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addFilesToQueue(context: Context) {
|
fun uploadResultToDatabase(context: Context, isOnline: Boolean) = viewModelScope.launch {
|
||||||
viewModelScope.launch {
|
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName()
|
||||||
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName()
|
val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName()
|
||||||
val pendingId = getCSVFileName().split(".")[0]
|
testDetails?.csvPath = csvFilePath
|
||||||
repository.addToPendingQueue(
|
testDetails?.reportPath = logTxtFilePath
|
||||||
PendingUploads(
|
if (isOnline) {
|
||||||
pendingId,
|
val storageRef = FirebaseStorage.getInstance().reference
|
||||||
DataHolder.mobileUniqueId!!,
|
val storageTestDetailsRef = storageRef.child("${testDetails?._id}/")
|
||||||
testDetails!!.patientID,
|
|
||||||
csvFilePath,
|
try {
|
||||||
Calendar.getInstance().time
|
val csvFileUri = Uri.fromFile(File(csvFilePath))
|
||||||
)
|
val logTxtFileUri = Uri.fromFile(File(logTxtFilePath))
|
||||||
)
|
|
||||||
}
|
val csvUploadTask =
|
||||||
viewModelScope.launch {
|
storageTestDetailsRef.child(csvFileUri.lastPathSegment!!).putFile(csvFileUri)
|
||||||
val detailedCsvFilePath = MyUtils.getAppFolderPath(context) + getDetailedCSVFileName()
|
.await()
|
||||||
val pendingId = getDetailedCSVFileName().split(".")[0]
|
val logUploadTask = storageTestDetailsRef.child(logTxtFileUri.lastPathSegment!!)
|
||||||
repository.addToPendingQueue(
|
.putFile(logTxtFileUri).await()
|
||||||
PendingUploads(
|
|
||||||
pendingId,
|
val csvUri = csvUploadTask.storage.downloadUrl.await().toString()
|
||||||
DataHolder.mobileUniqueId!!,
|
val logUri = logUploadTask.storage.downloadUrl.await().toString()
|
||||||
testDetails!!.patientID,
|
|
||||||
detailedCsvFilePath,
|
testDetails?.csvPath = csvUri
|
||||||
Calendar.getInstance().time
|
testDetails?.reportPath = logUri
|
||||||
)
|
|
||||||
)
|
addResultTestToDb()
|
||||||
}
|
} catch (exception: Exception) {
|
||||||
viewModelScope.launch {
|
// Handle the exception appropriately (e.g., log the error, display an error message)
|
||||||
val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName()
|
}
|
||||||
val pendingId = getLogFileName().split(".")[0]
|
} else {
|
||||||
repository.addToPendingQueue(
|
testDetails?.testTime = Calendar.getInstance().time.toString()
|
||||||
PendingUploads(
|
userDao.insertAll(testDetails!!)
|
||||||
pendingId,
|
|
||||||
DataHolder.mobileUniqueId!!,
|
|
||||||
testDetails!!.patientID,
|
|
||||||
logTxtFilePath,
|
|
||||||
Calendar.getInstance().time
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addFilesToCloud(context: Context) {
|
fun bulkUploadResultToDatabase(userData: UserData) = viewModelScope.launch {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
val storageRef = FirebaseStorage.getInstance().reference
|
||||||
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName()
|
val storageTestDetailsRef = storageRef.child("${testDetails?._id}/")
|
||||||
val fileName = getCSVFileName().split(".")[0]
|
try {
|
||||||
val response = repository.uploadFileToStorage(testDetails!!.patientID, csvFilePath)
|
val csvFileUri = Uri.fromFile(File(userData.csvPath))
|
||||||
|
val logTxtFileUri = Uri.fromFile(File(userData.reportPath))
|
||||||
|
|
||||||
when (response) {
|
val csvUploadTask =
|
||||||
|
storageTestDetailsRef.child(csvFileUri.lastPathSegment!!).putFile(csvFileUri)
|
||||||
|
.await()
|
||||||
|
val logUploadTask =
|
||||||
|
storageTestDetailsRef.child(logTxtFileUri.lastPathSegment!!).putFile(logTxtFileUri)
|
||||||
|
.await()
|
||||||
|
|
||||||
|
val csvUri = csvUploadTask.storage.downloadUrl.await().toString()
|
||||||
|
val logUri = logUploadTask.storage.downloadUrl.await().toString()
|
||||||
|
|
||||||
|
userData.csvPath = csvUri
|
||||||
|
userData.reportPath = logUri
|
||||||
|
|
||||||
|
bulkAddResultTestToDb(userData)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
// Handle the exception appropriately (e.g., log the error, display an error message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bulkAddResultTestToDb(userData: UserData) {
|
||||||
|
userData.location = DataHolder.location
|
||||||
|
viewModelScope.launch {
|
||||||
|
userData.uploadTime = Calendar.getInstance().time.toString()
|
||||||
|
when (repository.addTestToDatabase(userData)) {
|
||||||
is Response.Success -> {
|
is Response.Success -> {
|
||||||
Log.d(TAG, "Uploaded $csvFilePath")
|
fireBaseUpload.postValue("Success")
|
||||||
repository.removeFromPendingQueue(fileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
is Response.Error -> {
|
|
||||||
Log.d(TAG, response.exception.toString())
|
|
||||||
}
|
}
|
||||||
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
fun deleteById(userId: String) = viewModelScope.launch {
|
||||||
val detailedCsvFilePath =
|
userDao.deleteById(id = userId)
|
||||||
MyUtils.getAppFolderPath(context) + getDetailedCSVFileName()
|
|
||||||
val fileName = getDetailedCSVFileName().split(".")[0]
|
|
||||||
val response =
|
|
||||||
repository.uploadFileToStorage(testDetails!!.patientID, detailedCsvFilePath)
|
|
||||||
|
|
||||||
when (response) {
|
|
||||||
is Response.Success -> {
|
|
||||||
Log.d(TAG, "Uploaded $detailedCsvFilePath")
|
|
||||||
repository.removeFromPendingQueue(fileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
is Response.Error -> {
|
|
||||||
Log.d(TAG, response.exception.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
|
||||||
val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName()
|
|
||||||
val fileName = getLogFileName().split(".")[0]
|
|
||||||
val response =
|
|
||||||
repository.uploadFileToStorage(testDetails!!.patientID, logTxtFilePath)
|
|
||||||
|
|
||||||
when (response) {
|
|
||||||
is Response.Success -> {
|
|
||||||
Log.d(TAG, "Uploaded $logTxtFilePath")
|
|
||||||
repository.removeFromPendingQueue(fileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
is Response.Error -> {
|
|
||||||
Log.d(TAG, response.exception.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.testRight
|
package com.example.hpostesting.presentation.testRight
|
||||||
|
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@@ -6,10 +6,9 @@ import android.hardware.usb.UsbDeviceConnection
|
|||||||
import android.os.Binder
|
import android.os.Binder
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.example.hpos.data.DataHolder
|
import com.example.hpostesting.data.constant.Constants
|
||||||
import com.example.hpos.data.constant.Constants
|
import com.example.hpostesting.data.constant.TestRightCommands
|
||||||
import com.example.hpos.data.constant.TestRightCommands
|
import com.example.hpostesting.presentation.UsbServiceListener
|
||||||
import com.example.hpos.presentation.UsbServiceListener
|
|
||||||
import com.hoho.android.usbserial.driver.UsbSerialDriver
|
import com.hoho.android.usbserial.driver.UsbSerialDriver
|
||||||
import com.hoho.android.usbserial.driver.UsbSerialPort
|
import com.hoho.android.usbserial.driver.UsbSerialPort
|
||||||
import com.hoho.android.usbserial.util.SerialInputOutputManager
|
import com.hoho.android.usbserial.util.SerialInputOutputManager
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.utils
|
package com.example.hpostesting.presentation.utils
|
||||||
|
|
||||||
interface MyDialogListener {
|
interface MyDialogListener {
|
||||||
fun onClickNegativeButton()
|
fun onClickNegativeButton()
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos.presentation.utils
|
package com.example.hpostesting.presentation.utils
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.hpos
|
package com.example.hpostesting
|
||||||
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
package com.example.hpos.util
|
package com.example.hpostesting.util
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import com.example.hpos.R
|
import com.example.hpostesting.data.model.patient.PatientDetails
|
||||||
import com.example.hpos.data.model.patient.PatientDetails
|
import `in`.sminnovations.hpostesting.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.InetAddress
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
13
app/src/main/res/drawable/edit_text_background.xml
Normal file
13
app/src/main/res/drawable/edit_text_background.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
|
<corners
|
||||||
|
android:radius="20dp"/>
|
||||||
|
|
||||||
|
<solid android:color="@color/white"/>
|
||||||
|
|
||||||
|
<stroke android:color="@color/gray"
|
||||||
|
android:width="1dp"/>
|
||||||
|
|
||||||
|
</shape>
|
||||||
5
app/src/main/res/drawable/upload_data.xml
Normal file
5
app/src/main/res/drawable/upload_data.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="@color/primary"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@color/primary" android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM14,13v4h-4v-4H7l5,-5 5,5h-3z"/>
|
||||||
|
</vector>
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
app:fontProviderAuthority="com.google.android.gms.fonts"
|
|
||||||
app:fontProviderPackage="com.google.android.gms"
|
|
||||||
app:fontProviderQuery="name=Inter&weight=700"
|
|
||||||
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
|
|
||||||
</font-family>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
app:fontProviderAuthority="com.google.android.gms.fonts"
|
|
||||||
app:fontProviderPackage="com.google.android.gms"
|
|
||||||
app:fontProviderQuery="name=Inter&weight=500"
|
|
||||||
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
|
|
||||||
</font-family>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
app:fontProviderAuthority="com.google.android.gms.fonts"
|
|
||||||
app:fontProviderPackage="com.google.android.gms"
|
|
||||||
app:fontProviderQuery="name=Inter&weight=600"
|
|
||||||
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
|
|
||||||
</font-family>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
app:fontProviderAuthority="com.google.android.gms.fonts"
|
|
||||||
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs"
|
|
||||||
app:fontProviderPackage="com.google.android.gms"
|
|
||||||
app:fontProviderQuery="Poppins">
|
|
||||||
</font-family>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
app:fontProviderAuthority="com.google.android.gms.fonts"
|
|
||||||
app:fontProviderPackage="com.google.android.gms"
|
|
||||||
app:fontProviderQuery="name=Poppins&weight=500"
|
|
||||||
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
|
|
||||||
</font-family>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
app:fontProviderAuthority="com.google.android.gms.fonts"
|
|
||||||
app:fontProviderPackage="com.google.android.gms"
|
|
||||||
app:fontProviderQuery="name=Poppins&weight=600"
|
|
||||||
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
|
|
||||||
</font-family>
|
|
||||||
BIN
app/src/main/res/font/poppins_bold.ttf
Normal file
BIN
app/src/main/res/font/poppins_bold.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/poppins_extra_bold.ttf
Normal file
BIN
app/src/main/res/font/poppins_extra_bold.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/poppins_light.ttf
Normal file
BIN
app/src/main/res/font/poppins_light.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/poppins_medium.ttf
Normal file
BIN
app/src/main/res/font/poppins_medium.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/poppins_regular.ttf
Normal file
BIN
app/src/main/res/font/poppins_regular.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/poppins_semi_bold.ttf
Normal file
BIN
app/src/main/res/font/poppins_semi_bold.ttf
Normal file
Binary file not shown.
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
app:fontProviderAuthority="com.google.android.gms.fonts"
|
|
||||||
app:fontProviderPackage="com.google.android.gms"
|
|
||||||
app:fontProviderQuery="Roboto"
|
|
||||||
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
|
|
||||||
</font-family>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
app:fontProviderAuthority="com.google.android.gms.fonts"
|
|
||||||
app:fontProviderPackage="com.google.android.gms"
|
|
||||||
app:fontProviderQuery="name=Roboto&weight=500"
|
|
||||||
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
|
|
||||||
</font-family>
|
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/my_toolbar" />
|
app:layout_constraintTop_toBottomOf="@id/my_toolbar" />
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<androidx.cardview.widget.CardView
|
||||||
android:id="@+id/cv_item1"
|
android:id="@+id/cv_item1"
|
||||||
android:layout_width="128dp"
|
android:layout_width="128dp"
|
||||||
android:layout_height="128dp"
|
android:layout_height="128dp"
|
||||||
@@ -70,9 +70,9 @@
|
|||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<androidx.cardview.widget.CardView
|
||||||
android:id="@+id/cv_item2"
|
android:id="@+id/cv_item2"
|
||||||
android:layout_width="128dp"
|
android:layout_width="128dp"
|
||||||
android:layout_height="128dp"
|
android:layout_height="128dp"
|
||||||
@@ -113,9 +113,9 @@
|
|||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<androidx.cardview.widget.CardView
|
||||||
android:id="@+id/cv_item3"
|
android:id="@+id/cv_item3"
|
||||||
android:layout_width="128dp"
|
android:layout_width="128dp"
|
||||||
android:layout_height="128dp"
|
android:layout_height="128dp"
|
||||||
@@ -155,10 +155,10 @@
|
|||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<androidx.cardview.widget.CardView
|
||||||
android:id="@+id/cv_item4"
|
android:id="@+id/cv_item4"
|
||||||
android:layout_width="128dp"
|
android:layout_width="128dp"
|
||||||
android:layout_height="128dp"
|
android:layout_height="128dp"
|
||||||
@@ -199,7 +199,7 @@
|
|||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|||||||
@@ -1,23 +1,90 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns: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_height="match_parent">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
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:padding="24dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_title_no_internet"
|
||||||
|
style="@style/title1"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/internet_not_available_please_enter_the_user_id_manually"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
|
<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="24dp"
|
||||||
|
android:layout_marginHorizontal="24dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/tv_title_no_internet">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/userId"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:maxLength="18"
|
||||||
|
android:inputType="textCapCharacters"
|
||||||
|
android:hint="@string/user_id" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btn_submit"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="24dp"
|
||||||
|
android:text="@string/submit"
|
||||||
|
app:cornerRadius="100dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/til_name" />
|
||||||
|
|
||||||
|
</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
|
<TextView
|
||||||
android:id="@+id/tv_title"
|
android:id="@+id/tv_title"
|
||||||
style="@style/title1"
|
style="@style/title1"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginHorizontal="24dp"
|
android:text="@string/user_list"
|
||||||
android:layout_marginTop="16dp"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:text="@string/list_of_patients"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="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="visible"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/tv_title"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/tv_title" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_not_available"
|
android:id="@+id/tv_not_available"
|
||||||
style="@style/title1_1"
|
style="@style/title1_1"
|
||||||
@@ -32,43 +99,82 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tv_title" />
|
app:layout_constraintTop_toBottomOf="@id/tv_title" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.cardview.widget.CardView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/cardView4"
|
||||||
android:layout_width="match_parent"
|
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"
|
android:layout_height="0dp"
|
||||||
android:layout_margin="16dp"
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
android:scrollbars="vertical"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/btn_add"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/tv_title"
|
|
||||||
tools:listitem="@layout/table_item" />
|
|
||||||
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btn_add"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="24dp"
|
|
||||||
android:drawableLeft="@drawable/baseline_add_24"
|
|
||||||
android:text="@string/add"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
app:cornerRadius="16dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
<com.google.android.material.button.MaterialButton
|
app:layout_constraintTop_toBottomOf="@+id/radioGroup"
|
||||||
android:id="@+id/btn_test"
|
tools:listitem="@layout/user_item_view"/>
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="24dp"
|
|
||||||
android:drawableLeft="@drawable/test_tube"
|
|
||||||
android:text="@string/test"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
app:cornerRadius="16dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
||||||
</layout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -253,7 +253,7 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@id/cv_sample_details" />
|
app:layout_constraintTop_toBottomOf="@id/cv_sample_details" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/title3"
|
style="@style/title2"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/home"
|
android:text="@string/home"
|
||||||
@@ -277,7 +277,7 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@id/cv_sample_details" />
|
app:layout_constraintTop_toBottomOf="@id/cv_sample_details" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/title3"
|
style="@style/title2"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/new_test"
|
android:text="@string/new_test"
|
||||||
@@ -289,8 +289,9 @@
|
|||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/gray"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
android:indeterminate="true"
|
android:indeterminate="true"
|
||||||
android:indeterminateDrawable="@drawable/progressbar_drawable"
|
android:indeterminateDrawable="@drawable/progressbar_drawable"
|
||||||
|
|||||||
61
app/src/main/res/layout/user_item_view.xml
Normal file
61
app/src/main/res/layout/user_item_view.xml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:id="@+id/userCard"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
app:cardBackgroundColor="@color/primary_light"
|
||||||
|
app:cardCornerRadius="25dp"
|
||||||
|
app:cardElevation="0dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="12dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/userImage"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/userName"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/poppins_bold"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/userImage" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/userId"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/poppins_bold"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/userName" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user