Change the project into Testing app
This commit is contained in:
@@ -2,15 +2,19 @@ plugins {
|
||||
id 'com.android.application'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
id 'com.google.firebase.appdistribution'
|
||||
id 'dagger.hilt.android.plugin'
|
||||
id 'com.google.gms.google-services'
|
||||
id 'androidx.navigation.safeargs.kotlin'
|
||||
id 'kotlin-kapt'
|
||||
}
|
||||
//apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdk 33
|
||||
namespace 'in.sminnovations.hpostesting'
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.example.hpos"
|
||||
applicationId "in.sminnovations.hpostesting"
|
||||
minSdk 21
|
||||
targetSdk 33
|
||||
versionCode 2
|
||||
@@ -26,11 +30,11 @@ android {
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
jvmTarget = '17'
|
||||
}
|
||||
dataBinding {
|
||||
enabled = true
|
||||
@@ -48,19 +52,21 @@ android {
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.9.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||
implementation 'com.google.android.material:material:1.7.0'
|
||||
implementation 'androidx.core:core-ktx:1.10.1'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.9.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
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
|
||||
implementation 'com.google.firebase:firebase-firestore-ktx:24.4.1'
|
||||
implementation 'com.google.firebase:firebase-storage-ktx:20.1.0'
|
||||
//firebase
|
||||
implementation platform('com.google.firebase:firebase-bom:32.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 'androidx.core:core-ktx:+'
|
||||
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
|
||||
|
||||
// Testing
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
@@ -68,11 +74,11 @@ dependencies {
|
||||
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.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
|
||||
implementation 'com.opencsv:opencsv:4.6'
|
||||
@@ -83,7 +89,26 @@ dependencies {
|
||||
// Google ML Kit usign play services
|
||||
implementation 'com.google.android.gms:play-services-code-scanner:16.0.0'
|
||||
|
||||
}
|
||||
//repositories {
|
||||
// mavenCentral()
|
||||
//}
|
||||
//Room
|
||||
implementation "androidx.room:room-ktx:2.6.0-alpha01"
|
||||
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.platform.app.InstrumentationRegistry
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.example.hpos">
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
@@ -16,7 +15,7 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<application
|
||||
android:name=".MyApplication"
|
||||
android:name="com.example.hpostesting.HPOSTestingApplication"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
@@ -24,26 +23,27 @@
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/hpos_icon_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.HPOS"
|
||||
android:theme="@style/Theme.HPOSTesting"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".presentation.KitScanActivity"
|
||||
android:name="com.example.hpostesting.presentation.KitScanActivity"
|
||||
android:noHistory="true"
|
||||
android:exported="false" />
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.HPOS.NoActionBar"/>
|
||||
<activity
|
||||
android:name=".presentation.dashboard.DashboardActivity"
|
||||
android:name="com.example.hpostesting.presentation.dashboard.DashboardActivity"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_dashboard"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.HPOS.NoActionBar" />
|
||||
|
||||
<service
|
||||
android:name=".presentation.testRight.UsbService"
|
||||
android:name="com.example.hpostesting.presentation.testRight.UsbService"
|
||||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:name=".presentation.SplashActivity"
|
||||
android:name="com.example.hpostesting.presentation.SplashActivity"
|
||||
android:exported="true"
|
||||
android:noHistory="true"
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
@@ -54,12 +54,13 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".presentation.testRight.TestRightActivity"
|
||||
android:name="com.example.hpostesting.presentation.testRight.TestRightActivity"
|
||||
android:exported="false"
|
||||
android:parentActivityName=".presentation.MainActivity"
|
||||
android:parentActivityName="com.example.hpostesting.presentation.MainActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:noHistory="true"
|
||||
android:windowSoftInputMode="adjustPan">
|
||||
android:windowSoftInputMode="adjustPan"
|
||||
android:theme="@style/Theme.HPOS.NoActionBar">
|
||||
|
||||
<!-- <intent-filter> -->
|
||||
<!-- <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> -->
|
||||
@@ -71,9 +72,10 @@
|
||||
<!-- android:resource="@xml/device_filter" /> -->
|
||||
</activity> <!-- android:theme="@style/Theme.HPOS.ActionBar" -->
|
||||
<activity
|
||||
android:name=".presentation.MainActivity"
|
||||
android:name="com.example.hpostesting.presentation.MainActivity"
|
||||
android:exported="true"
|
||||
android:screenOrientation="portrait">
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
|
||||
</intent-filter>
|
||||
@@ -88,9 +90,6 @@
|
||||
android:stateNotNeeded="true"
|
||||
tools:replace="android:screenOrientation" />
|
||||
|
||||
<meta-data
|
||||
android:name="preloaded_fonts"
|
||||
android:resource="@array/preloaded_fonts" />
|
||||
</application>
|
||||
|
||||
</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 com.example.hpos.data.model.test.TestDetails
|
||||
import com.example.hpos.data.model.test.TestRightDeviceConstants
|
||||
import com.example.hpos.data.model.test.TestType
|
||||
import com.example.hpostesting.data.model.patient.UserData
|
||||
import com.example.hpostesting.data.model.test.TestRightDeviceConstants
|
||||
import com.example.hpostesting.data.model.test.TestType
|
||||
|
||||
object DataHolder {
|
||||
|
||||
@@ -28,7 +28,9 @@ object DataHolder {
|
||||
/* (For reference/baseline) Contains pixel no. -> Intensity of light falling on that pixel */
|
||||
val intensityReferenceArray = ArrayList<Double>()
|
||||
|
||||
var selectedTest: TestDetails? = null
|
||||
var selectedTest: UserData? = null
|
||||
|
||||
var location: UserData.Location? = null
|
||||
|
||||
var testExp: Boolean = true
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package com.example.hpos.data
|
||||
package com.example.hpostesting.data
|
||||
|
||||
import android.util.Log
|
||||
import com.example.hpos.data.model.Response
|
||||
import com.example.hpos.data.repository.DatabaseRepository
|
||||
import com.example.hpos.util.MyUtils
|
||||
import com.example.hpostesting.data.model.Response
|
||||
import com.example.hpostesting.data.repository.DatabaseRepository
|
||||
import com.example.hpostesting.util.MyUtils
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.lang.Thread.sleep
|
||||
|
||||
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.SharedPreferences
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.data.constant
|
||||
package com.example.hpostesting.data.constant
|
||||
|
||||
object Constants {
|
||||
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) {
|
||||
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 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(
|
||||
var pixelNo: Int,
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.data.model
|
||||
package com.example.hpostesting.data.model
|
||||
|
||||
data class ErrorMessage (
|
||||
val message: String,
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.data.model
|
||||
package com.example.hpostesting.data.model
|
||||
|
||||
data class Location(
|
||||
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(
|
||||
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.Date
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.data.model
|
||||
package com.example.hpostesting.data.model
|
||||
|
||||
sealed class Response<out R> {
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
data class TestDetails(
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.data.model.test
|
||||
package com.example.hpostesting.data.model.test
|
||||
|
||||
data class TestInfo(
|
||||
val value: String,
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.data.model.test
|
||||
package com.example.hpostesting.data.model.test
|
||||
|
||||
data class TestRightCalculationData(
|
||||
var absorbanceOne: Double?,
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.data.model.test
|
||||
package com.example.hpostesting.data.model.test
|
||||
|
||||
data class TestRightDeviceConstants(
|
||||
var a: String,
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.data.model.test
|
||||
package com.example.hpostesting.data.model.test
|
||||
|
||||
enum class TestRightResultType {
|
||||
NORMAL,
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.data.model.test
|
||||
package com.example.hpostesting.data.model.test
|
||||
|
||||
enum class TestType {
|
||||
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) {
|
||||
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 {
|
||||
// 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.hpos.data.model.test.TestRightCalculationData
|
||||
import com.example.hpos.data.model.test.TestRightResultType
|
||||
import com.example.hpostesting.data.constant.Constants
|
||||
import com.example.hpostesting.data.model.test.TestRightCalculationData
|
||||
import com.example.hpostesting.data.model.test.TestRightResultType
|
||||
|
||||
class ResultCalculationWithAvgImpl : TestRightResultCalculation {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.example.hpos.domain
|
||||
package com.example.hpostesting.domain
|
||||
|
||||
import android.util.Log
|
||||
import com.example.hpos.data.constant.Constants
|
||||
import com.example.hpos.data.model.test.TestRightResultType
|
||||
import com.example.hpostesting.data.constant.Constants
|
||||
import com.example.hpostesting.data.model.test.TestRightResultType
|
||||
import kotlin.math.log10
|
||||
|
||||
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.hpos.data.model.test.TestRightCalculationData
|
||||
import com.example.hpos.data.model.test.TestRightResultType
|
||||
import com.example.hpostesting.data.constant.Constants
|
||||
import com.example.hpostesting.data.model.test.TestRightCalculationData
|
||||
import com.example.hpostesting.data.model.test.TestRightResultType
|
||||
|
||||
class ResultCalculationWithMaxImpl : TestRightResultCalculation {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.example.hpos.domain
|
||||
package com.example.hpostesting.domain
|
||||
|
||||
import android.util.Log
|
||||
import com.example.hpos.data.repository.LocalFileRepository
|
||||
import com.example.hpos.data.constant.Constants
|
||||
import com.example.hpos.data.model.test.TestDetails
|
||||
import com.example.hpos.data.model.test.TestRightCalculationData
|
||||
import com.example.hpostesting.data.repository.LocalFileRepository
|
||||
import com.example.hpostesting.data.constant.Constants
|
||||
import com.example.hpostesting.data.model.patient.UserData
|
||||
import com.example.hpostesting.data.model.test.TestRightCalculationData
|
||||
import java.util.Collections.sort
|
||||
|
||||
class SaveRawData(private val localFileRepository: LocalFileRepository) {
|
||||
@@ -98,7 +98,7 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) {
|
||||
folderPath: String,
|
||||
fileName: String,
|
||||
calculationData: TestRightCalculationData,
|
||||
testDetails: TestDetails?
|
||||
testDetails: UserData?
|
||||
) {
|
||||
// val fileObj = File(folderPath, fileName)
|
||||
// val writer = FileWriter(fileObj)
|
||||
@@ -116,11 +116,11 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) {
|
||||
|
||||
private fun getLogStringFromObjWithPatientData(
|
||||
calculationData: TestRightCalculationData,
|
||||
testDetails: TestDetails?
|
||||
testDetails: UserData?
|
||||
): String {
|
||||
var outputString = "Test calculation logs ==>\n"
|
||||
outputString += "Name = ${testDetails?.patientName}\n"
|
||||
outputString += "ID = ${testDetails?.patientID}\n"
|
||||
outputString += "Name = ${testDetails?.name}\n"
|
||||
outputString += "ID = ${testDetails?._id}\n"
|
||||
// outputString += "Gender = ${patientData.gender}\n"
|
||||
outputString += "Absorbance one = ${
|
||||
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.hpos.data.model.CalculationVariableForTest
|
||||
import com.example.hpostesting.data.repository.LocalFileRepository
|
||||
import com.example.hpostesting.data.model.CalculationVariableForTest
|
||||
|
||||
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.hpos.data.model.test.TestRightCalculationData
|
||||
import com.example.hpos.data.model.test.TestRightResultType
|
||||
import com.example.hpostesting.data.constant.Constants
|
||||
import com.example.hpostesting.data.model.test.TestRightCalculationData
|
||||
import com.example.hpostesting.data.model.test.TestRightResultType
|
||||
|
||||
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 {
|
||||
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.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.example.hpos.R
|
||||
import com.example.hpos.data.DataHolder
|
||||
import com.example.hpos.data.constant.Constants
|
||||
import com.example.hpos.databinding.ActivityKitScanBinding
|
||||
import com.example.hpos.presentation.dashboard.DashboardActivity
|
||||
import com.example.hpos.presentation.testRight.TestRightActivity
|
||||
import com.example.hpostesting.data.DataHolder
|
||||
import com.example.hpostesting.data.constant.Constants
|
||||
import com.example.hpostesting.presentation.dashboard.DashboardActivity
|
||||
import com.example.hpostesting.presentation.testRight.TestRightActivity
|
||||
import com.journeyapps.barcodescanner.ScanContract
|
||||
import com.journeyapps.barcodescanner.ScanIntentResult
|
||||
import com.journeyapps.barcodescanner.ScanOptions
|
||||
import `in`.sminnovations.hpostesting.R
|
||||
import `in`.sminnovations.hpostesting.databinding.ActivityKitScanBinding
|
||||
|
||||
class KitScanActivity : AppCompatActivity() {
|
||||
|
||||
@@ -51,6 +51,7 @@ class KitScanActivity : AppCompatActivity() {
|
||||
startScanningNow()
|
||||
}
|
||||
|
||||
|
||||
binding.btnGo.setOnClickListener {
|
||||
val serialNumber = binding.nameEditText.text.toString().trim()
|
||||
if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid(serialNumber)) {
|
||||
@@ -92,7 +93,7 @@ class KitScanActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private fun checkDataNotNull(): Boolean {
|
||||
return if (DataHolder.selectedTest == null) {
|
||||
return if (DataHolder.selectedTest?._id == null) {
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
"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
|
||||
|
||||
@@ -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 {
|
||||
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.view.Menu
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
import androidx.navigation.ui.navigateUp
|
||||
import androidx.navigation.ui.setupActionBarWithNavController
|
||||
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 dagger.hilt.android.AndroidEntryPoint
|
||||
import `in`.sminnovations.hpostesting.R
|
||||
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
|
||||
|
||||
@AndroidEntryPoint
|
||||
class DashboardActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
||||
private lateinit var binding: ActivityDashboardBinding
|
||||
private lateinit var viewModel: DashboardViewModel
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -43,10 +40,6 @@ class DashboardActivity : AppCompatActivity() {
|
||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||
navView.setupWithNavController(navController)
|
||||
|
||||
viewModel = ViewModelProvider(
|
||||
this,
|
||||
MyViewModelFactory()
|
||||
)[DashboardViewModel::class.java]
|
||||
}
|
||||
|
||||
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.view.LayoutInflater
|
||||
@@ -6,8 +6,8 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.example.hpos.databinding.FragmentGalleryBinding
|
||||
import com.example.hpos.presentation.dashboard.ui.gallery.GalleryViewModel
|
||||
import com.example.hpostesting.presentation.dashboard.ui.gallery.GalleryViewModel
|
||||
import `in`.sminnovations.hpostesting.databinding.FragmentGalleryBinding
|
||||
|
||||
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 {
|
||||
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.view.LayoutInflater
|
||||
@@ -6,8 +6,8 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.example.hpos.databinding.FragmentSlideshowBinding
|
||||
import com.example.hpos.presentation.dashboard.ui.slideshow.SlideshowViewModel
|
||||
import com.example.hpostesting.presentation.dashboard.ui.slideshow.SlideshowViewModel
|
||||
import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding
|
||||
|
||||
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.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.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.MutableLiveData
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.presentation.testRight
|
||||
package com.example.hpostesting.presentation.testRight
|
||||
|
||||
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]"
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.presentation.testRight
|
||||
package com.example.hpostesting.presentation.testRight
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.BroadcastReceiver
|
||||
@@ -15,23 +15,24 @@ import android.os.IBinder
|
||||
import android.util.Log
|
||||
import android.view.Menu
|
||||
import android.widget.Toast
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.get
|
||||
import 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.databinding.ActivityTestRightBinding
|
||||
import com.example.hpos.util.MyViewModelFactory
|
||||
import com.example.hpostesting.data.DataHolder
|
||||
import com.example.hpostesting.data.constant.Constants
|
||||
import com.hoho.android.usbserial.driver.UsbSerialDriver
|
||||
import com.hoho.android.usbserial.driver.UsbSerialProber
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import `in`.sminnovations.hpostesting.R
|
||||
import `in`.sminnovations.hpostesting.databinding.ActivityTestRightBinding
|
||||
|
||||
|
||||
@AndroidEntryPoint
|
||||
class TestRightActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityTestRightBinding
|
||||
private lateinit var viewModel: TestRightViewModel
|
||||
private val viewModel by viewModels<TestRightViewModel>()
|
||||
private var myMenu: Menu? = null
|
||||
|
||||
private lateinit var mDriver: UsbSerialDriver
|
||||
@@ -78,10 +79,6 @@ class TestRightActivity : AppCompatActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityTestRightBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
viewModel = ViewModelProvider(
|
||||
this,
|
||||
MyViewModelFactory()
|
||||
)[TestRightViewModel::class.java]
|
||||
|
||||
setSupportActionBar(binding.myToolbar)
|
||||
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.Handler
|
||||
@@ -10,17 +10,19 @@ import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import com.example.hpos.R
|
||||
import com.example.hpos.data.DataHolder
|
||||
import com.example.hpos.data.constant.Constants
|
||||
import com.example.hpos.data.constant.TestRightCommands
|
||||
import com.example.hpos.data.model.ErrorMessage
|
||||
import com.example.hpos.databinding.FragmentTestRightExpReferenceBinding
|
||||
import com.example.hpos.presentation.UsbServiceListener
|
||||
import com.example.hpos.presentation.utils.MyDialogListener
|
||||
import com.example.hpos.presentation.utils.UIUtils
|
||||
import com.example.hpostesting.data.DataHolder
|
||||
import com.example.hpostesting.data.constant.Constants
|
||||
import com.example.hpostesting.data.constant.TestRightCommands
|
||||
import com.example.hpostesting.data.model.ErrorMessage
|
||||
import com.example.hpostesting.presentation.UsbServiceListener
|
||||
import com.example.hpostesting.presentation.utils.MyDialogListener
|
||||
import com.example.hpostesting.presentation.utils.UIUtils
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import `in`.sminnovations.hpostesting.R
|
||||
import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpReferenceBinding
|
||||
|
||||
|
||||
@AndroidEntryPoint
|
||||
class TestRightExpReference : Fragment() {
|
||||
|
||||
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.os.Bundle
|
||||
@@ -10,19 +10,20 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import com.example.hpos.R
|
||||
import com.example.hpos.data.DataHolder
|
||||
import com.example.hpos.data.PreferenceUtility
|
||||
import com.example.hpos.data.constant.Constants
|
||||
import com.example.hpos.data.constant.TestRightCommands
|
||||
import com.example.hpos.data.model.ErrorMessage
|
||||
import com.example.hpos.data.model.test.TestType
|
||||
import com.example.hpos.databinding.FragmentTestRightExpSampleBinding
|
||||
import com.example.hpos.presentation.MainActivity
|
||||
import com.example.hpos.presentation.UsbServiceListener
|
||||
import com.example.hpos.presentation.utils.MyDialogListener
|
||||
import com.example.hpos.presentation.utils.UIUtils
|
||||
import com.example.hpostesting.data.DataHolder
|
||||
import com.example.hpostesting.data.constant.Constants
|
||||
import com.example.hpostesting.data.constant.TestRightCommands
|
||||
import com.example.hpostesting.data.model.ErrorMessage
|
||||
import com.example.hpostesting.data.model.test.TestType
|
||||
import com.example.hpostesting.presentation.MainActivity
|
||||
import com.example.hpostesting.presentation.UsbServiceListener
|
||||
import com.example.hpostesting.presentation.utils.MyDialogListener
|
||||
import com.example.hpostesting.presentation.utils.UIUtils
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import `in`.sminnovations.hpostesting.R
|
||||
import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpSampleBinding
|
||||
|
||||
@AndroidEntryPoint
|
||||
class TestRightExpSample : Fragment() {
|
||||
|
||||
private lateinit var binding: FragmentTestRightExpSampleBinding
|
||||
@@ -256,11 +257,9 @@ class TestRightExpSample : Fragment() {
|
||||
|
||||
// val fileNameCsv = prefixCsv + id + fileExtensionCsv
|
||||
|
||||
|
||||
// NEW ------------------------------
|
||||
viewModel.saveCsv(requireContext().applicationContext, viewModel.getCSVFileName())
|
||||
viewModel.saveCsvForTesting(requireContext().applicationContext, viewModel.getDetailedCSVFileName())
|
||||
|
||||
// viewModel.saveCsvForTesting(requireContext().applicationContext, viewModel.getDetailedCSVFileName())
|
||||
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.os.Bundle
|
||||
@@ -9,32 +9,35 @@ import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import com.example.hpos.R
|
||||
import com.example.hpos.data.DataHolder
|
||||
import com.example.hpos.data.PreferenceUtility
|
||||
import com.example.hpos.data.constant.Constants
|
||||
import com.example.hpos.data.model.test.TestRightResultType
|
||||
import com.example.hpos.data.model.test.TestType
|
||||
import com.example.hpos.databinding.FragmentTestRightResultsBinding
|
||||
import com.example.hpos.presentation.dashboard.DashboardActivity
|
||||
import com.example.hpos.util.MyUtils
|
||||
import com.example.hpos.util.MyUtils.calculateAgeFromYOB
|
||||
import com.example.hpostesting.data.DataHolder
|
||||
import com.example.hpostesting.data.constant.Constants
|
||||
import com.example.hpostesting.data.model.test.TestRightResultType
|
||||
import com.example.hpostesting.data.model.test.TestType
|
||||
import com.example.hpostesting.presentation.dashboard.DashboardActivity
|
||||
import com.example.hpostesting.util.MyUtils.calculateAgeFromYOB
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import `in`.sminnovations.hpostesting.R
|
||||
import `in`.sminnovations.hpostesting.databinding.FragmentTestRightResultsBinding
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
|
||||
@AndroidEntryPoint
|
||||
class TestRightResults : Fragment() {
|
||||
|
||||
private lateinit var binding: FragmentTestRightResultsBinding
|
||||
private val viewModel: TestRightViewModel by activityViewModels()
|
||||
|
||||
private val TAG = "TestRightResults"
|
||||
private var isOnline = false
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View {
|
||||
// Inflate the layout for this fragment
|
||||
binding = FragmentTestRightResultsBinding.inflate(inflater, container, false)
|
||||
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
|
||||
isOnline = isNetworkAvailable
|
||||
}
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@@ -43,14 +46,13 @@ class TestRightResults : Fragment() {
|
||||
setupListeners()
|
||||
updateResults()
|
||||
|
||||
viewModel.addResultTestToDb()
|
||||
|
||||
// This is to add files to the pending queue
|
||||
viewModel.addFilesToQueue(requireContext())
|
||||
|
||||
// Uploading to cloud storage and deleting the from the pending queue when uploaded
|
||||
if (MyUtils.isInternetConnected()) {
|
||||
viewModel.addFilesToCloud(requireContext())
|
||||
viewModel.fireBaseUpload.observe(viewLifecycleOwner) {
|
||||
if (it == "Success") {
|
||||
Toast.makeText(
|
||||
requireContext(), "Test Results Upload Successfully", Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
binding.progressBar.visibility = View.GONE
|
||||
}
|
||||
|
||||
}
|
||||
@@ -68,35 +70,49 @@ class TestRightResults : Fragment() {
|
||||
}
|
||||
|
||||
private fun updateResults() {
|
||||
binding.tvName.text = getString(R.string.name_in_textview, viewModel.testDetails?.patientName)
|
||||
binding.tvAge.text =
|
||||
getString(R.string.age_in_textview, viewModel.testDetails?.patientAge?.calculateAgeFromYOB().toString())
|
||||
if (viewModel.testDetails?.name == "" && viewModel.testDetails?.birthYear == "") {
|
||||
binding.tvName.visibility = View.GONE
|
||||
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) {
|
||||
TestRightResultType.NORMAL -> {
|
||||
binding.resultNormal.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
TestRightResultType.SICKLECELLDISEASE -> {
|
||||
binding.resultDisease.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
TestRightResultType.SICKLECELLTRAIT -> {
|
||||
binding.resultTrait.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
TestRightResultType.POSITIVEBORDERLINE -> {
|
||||
binding.resultPositiveBorderline.visibility = View.VISIBLE
|
||||
binding.tvRecommended.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
TestRightResultType.NEGATIVEBORDERLINE -> {
|
||||
binding.resultNegativeBorderline.visibility = View.VISIBLE
|
||||
binding.tvRecommended.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
else -> {
|
||||
// binding.resultUndefined.visibility = View.VISIBLE
|
||||
Toast.makeText(requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG).show()
|
||||
Toast.makeText(
|
||||
requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG
|
||||
).show()
|
||||
moveToSamplePage()
|
||||
}
|
||||
}
|
||||
@@ -106,20 +122,31 @@ class TestRightResults : Fragment() {
|
||||
binding.resultDisease.visibility = View.VISIBLE
|
||||
binding.resultDisease.text = "Positive"
|
||||
}
|
||||
|
||||
TestRightResultType.NORMAL -> {
|
||||
binding.resultNormal.visibility = View.VISIBLE
|
||||
binding.resultNormal.text = "Negative"
|
||||
}
|
||||
|
||||
else -> {
|
||||
Toast.makeText(requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG).show()
|
||||
Toast.makeText(
|
||||
requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG
|
||||
).show()
|
||||
moveToSamplePage()
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (viewModel.patientDetails.age < 5) {
|
||||
// binding.tvRecommended.visibility = View.VISIBLE
|
||||
// binding.tvRecommended.text = getString(R.string.recommended_age)
|
||||
// }
|
||||
if (isOnline) {
|
||||
viewModel.uploadResultToDatabase(requireContext(), true)
|
||||
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) {
|
||||
DataHolder.sampleReadCounter = 0
|
||||
DataHolder.isReferenceTaken = false
|
||||
parentFragmentManager.beginTransaction()
|
||||
.replace(R.id.fl_main, TestRightExpReference())
|
||||
parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightExpReference())
|
||||
.commit()
|
||||
} else {
|
||||
parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightExpSample())
|
||||
@@ -144,55 +170,6 @@ class TestRightResults : Fragment() {
|
||||
|
||||
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.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
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.constant.Constants
|
||||
import com.example.hpos.data.model.CalculationVariableForTest
|
||||
import com.example.hpos.data.model.ErrorMessage
|
||||
import com.example.hpos.data.model.PendingUploads
|
||||
import com.example.hpos.data.model.test.Status
|
||||
import com.example.hpos.data.model.test.TestRightCalculationData
|
||||
import com.example.hpos.data.model.test.TestRightDeviceConstants
|
||||
import com.example.hpos.data.model.test.TestType
|
||||
import com.example.hpos.domain.ResultCalculationWithMaxImpl
|
||||
import com.example.hpos.domain.SaveRawData
|
||||
import com.example.hpos.domain.SaveRawDataTest
|
||||
import com.example.hpos.domain.SickleFindResultCaluculationWithMaxImpl
|
||||
import com.example.hpos.domain.TestRightResultCalculation
|
||||
import com.example.hpos.util.MyUtils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import com.example.hpostesting.data.DataHolder
|
||||
import com.example.hpostesting.data.NetworkStatusLiveData
|
||||
import com.example.hpostesting.data.constant.Constants
|
||||
import com.example.hpostesting.data.dao.UserDao
|
||||
import com.example.hpostesting.data.model.CalculationVariableForTest
|
||||
import com.example.hpostesting.data.model.ErrorMessage
|
||||
import com.example.hpostesting.data.model.Response
|
||||
import com.example.hpostesting.data.model.patient.UserData
|
||||
import com.example.hpostesting.data.model.test.TestRightCalculationData
|
||||
import com.example.hpostesting.data.model.test.TestRightDeviceConstants
|
||||
import com.example.hpostesting.data.model.test.TestType
|
||||
import com.example.hpostesting.data.repository.DatabaseRepository
|
||||
import com.example.hpostesting.domain.ResultCalculationWithMaxImpl
|
||||
import com.example.hpostesting.domain.SaveRawData
|
||||
import com.example.hpostesting.domain.SaveRawDataTest
|
||||
import com.example.hpostesting.domain.SickleFindResultCaluculationWithMaxImpl
|
||||
import com.example.hpostesting.domain.TestRightResultCalculation
|
||||
import com.example.hpostesting.util.MyUtils
|
||||
import com.google.firebase.storage.FirebaseStorage
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.tasks.await
|
||||
import java.io.File
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.log10
|
||||
import kotlin.math.pow
|
||||
|
||||
class TestRightViewModel(
|
||||
@HiltViewModel
|
||||
class TestRightViewModel @Inject constructor(
|
||||
private val saveRawData: SaveRawData,
|
||||
private val saveRawDataTest: SaveRawDataTest,
|
||||
private val repository: DatabaseRepository
|
||||
private val repository: DatabaseRepository,
|
||||
private val userDao: UserDao,
|
||||
context: Context
|
||||
) : ViewModel() {
|
||||
|
||||
private val TAG = "TestRightViewModel"
|
||||
|
||||
var isServiceConnected = false
|
||||
val progressBar = MutableLiveData(false)
|
||||
|
||||
// val errorTriggered = MutableLiveData<String>("")
|
||||
val errorTriggered = MutableLiveData<ErrorMessage>()
|
||||
var numberOfSampleRun = 0
|
||||
|
||||
// lateinit var patientDetails: PatientData
|
||||
val fireBaseUpload = MutableLiveData<String>()
|
||||
|
||||
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
|
||||
|
||||
/* (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"
|
||||
errorTriggered.postValue(
|
||||
ErrorMessage(
|
||||
"Error 201: In processing the data from device",
|
||||
Constants.ERROR_NORMAL
|
||||
"Error 201: In processing the data from device", Constants.ERROR_NORMAL
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -89,8 +99,7 @@ class TestRightViewModel(
|
||||
// "Error 202: Unable to fetch data from device."
|
||||
errorTriggered.postValue(
|
||||
ErrorMessage(
|
||||
"Error 202: Unable to fetch data from device.",
|
||||
Constants.ERROR_NORMAL
|
||||
"Error 202: Unable to fetch data from device.", Constants.ERROR_NORMAL
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -103,13 +112,9 @@ class TestRightViewModel(
|
||||
if (DataHolder.deviceConstant != null) {
|
||||
for (x in 1..Constants.TEST_RIGHT_TOTAL_PIXEL) {
|
||||
// val index = x - 1
|
||||
val wavelength: Double =
|
||||
(DataHolder.deviceConstant!!.a.toDouble() * (x.toDouble()
|
||||
.pow((3).toDouble()))) +
|
||||
(DataHolder.deviceConstant!!.b.toDouble() * (x.toDouble()
|
||||
.pow((2).toDouble()))) +
|
||||
(DataHolder.deviceConstant!!.c.toDouble() * x) +
|
||||
(DataHolder.deviceConstant!!.d.toDouble())
|
||||
val wavelength: Double = (DataHolder.deviceConstant!!.a.toDouble() * (x.toDouble()
|
||||
.pow((3).toDouble()))) + (DataHolder.deviceConstant!!.b.toDouble() * (x.toDouble()
|
||||
.pow((2).toDouble()))) + (DataHolder.deviceConstant!!.c.toDouble() * x) + (DataHolder.deviceConstant!!.d.toDouble())
|
||||
|
||||
DataHolder.wavelengthToPixelArray.add(wavelength)
|
||||
}
|
||||
@@ -118,8 +123,7 @@ class TestRightViewModel(
|
||||
// "Error 203: Unable to fetch data from device."
|
||||
errorTriggered.postValue(
|
||||
ErrorMessage(
|
||||
"Error 203: Unable to fetch data from device.",
|
||||
Constants.ERROR_NORMAL
|
||||
"Error 203: Unable to fetch data from device.", Constants.ERROR_NORMAL
|
||||
)
|
||||
)
|
||||
|
||||
@@ -136,22 +140,17 @@ class TestRightViewModel(
|
||||
val listOfString = fullString.split("\n")
|
||||
|
||||
for (line in listOfString) {
|
||||
if ("Buf" in line) {
|
||||
/* Removing trailing spaces and "Buf" from the string then taking lhs & rhs of ':' */
|
||||
val numbers = line.trim()
|
||||
.substring(3).split(":")
|
||||
if ("Buf" in line) {/* Removing trailing spaces and "Buf" from the string then taking lhs & rhs of ':' */
|
||||
val numbers = line.trim().substring(3).split(":")
|
||||
if (numbers.size >= 2) {
|
||||
|
||||
if (isReference)
|
||||
DataHolder.intensityReferenceArray.add(numbers[1].toDouble())
|
||||
else
|
||||
intensitySampleArray.add(numbers[1].toDouble())
|
||||
if (isReference) DataHolder.intensityReferenceArray.add(numbers[1].toDouble())
|
||||
else intensitySampleArray.add(numbers[1].toDouble())
|
||||
} else {
|
||||
// "Error 204: Unable to fetch data from device."
|
||||
errorTriggered.postValue(
|
||||
ErrorMessage(
|
||||
"Error 204: Unable to fetch data from device.",
|
||||
Constants.ERROR_NORMAL
|
||||
"Error 204: Unable to fetch data from device.", Constants.ERROR_NORMAL
|
||||
)
|
||||
)
|
||||
|
||||
@@ -265,7 +264,7 @@ class TestRightViewModel(
|
||||
|
||||
testDetails?.result = calculationData.result
|
||||
testDetails?.resultRatio = calculationData.ratioValue
|
||||
testDetails?.testStatus = Status.COMPLETED
|
||||
testDetails?.testStatus = true
|
||||
|
||||
}
|
||||
|
||||
@@ -275,7 +274,7 @@ class TestRightViewModel(
|
||||
SickleFindResultCaluculationWithMaxImpl()
|
||||
calculationData = resultCalculation.getResults(wavelengthToAbsorbance)
|
||||
testDetails?.result = calculationData.result
|
||||
testDetails?.testStatus = Status.COMPLETED
|
||||
testDetails?.testStatus = true
|
||||
|
||||
}
|
||||
|
||||
@@ -369,10 +368,7 @@ class TestRightViewModel(
|
||||
if (DataHolder.isAppFolderCreated) {
|
||||
// SaveRawData().saveLogWithPatientData(
|
||||
saveRawData.saveLogWithPatientData(
|
||||
folderPath!!,
|
||||
fileName,
|
||||
calculationData,
|
||||
testDetails
|
||||
folderPath!!, fileName, calculationData, testDetails
|
||||
)
|
||||
} else {
|
||||
folderPath = MyUtils.createAppFolder(appContext)
|
||||
@@ -381,10 +377,7 @@ class TestRightViewModel(
|
||||
DataHolder.appFolderPath = folderPath
|
||||
// SaveRawData().saveLogWithPatientData(
|
||||
saveRawData.saveLogWithPatientData(
|
||||
folderPath,
|
||||
fileName,
|
||||
calculationData,
|
||||
testDetails
|
||||
folderPath, fileName, calculationData, testDetails
|
||||
)
|
||||
} else {
|
||||
// errorTriggered.postValue("Unable to save Log, Please try again")
|
||||
@@ -427,129 +420,112 @@ class TestRightViewModel(
|
||||
}
|
||||
|
||||
fun getCSVFileName(): String {
|
||||
val prefixCsv: String = if (DataHolder.selectedTestType == TestType.SICKLECERT)
|
||||
"HPOSSC_${testDetails?.testID}"
|
||||
else
|
||||
"HPOSSF_${testDetails?.testID}"
|
||||
val prefixCsv: String =
|
||||
if (DataHolder.selectedTestType == TestType.SICKLECERT) "HPOSSC_${testDetails?._id}"
|
||||
else "HPOSSF_${testDetails?._id}"
|
||||
|
||||
val fileExtensionCsv = ".csv"
|
||||
|
||||
return prefixCsv + fileExtensionCsv
|
||||
}
|
||||
|
||||
fun getDetailedCSVFileName(): String {
|
||||
return "detailed_" + getCSVFileName()
|
||||
}
|
||||
|
||||
fun getLogFileName(): String {
|
||||
val prefixTxt = "log_${testDetails?.testID}"
|
||||
val prefixTxt = "log_${testDetails?._id}"
|
||||
val fileExtensionTxt = ".txt"
|
||||
return prefixTxt + fileExtensionTxt
|
||||
}
|
||||
|
||||
fun addResultTestToDb() {
|
||||
private fun addResultTestToDb() {
|
||||
testDetails?.location = DataHolder.location
|
||||
testDetails?.testTime = Calendar.getInstance().time.toString()
|
||||
viewModelScope.launch {
|
||||
testDetails!!.uploadTime = Calendar.getInstance().time
|
||||
repository.addTestToDatabase(testDetails)
|
||||
testDetails!!.uploadTime = Calendar.getInstance().time.toString()
|
||||
when (repository.addTestToDatabase(testDetails)) {
|
||||
is Response.Success -> {
|
||||
fireBaseUpload.postValue("Success")
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addFilesToQueue(context: Context) {
|
||||
viewModelScope.launch {
|
||||
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName()
|
||||
val pendingId = getCSVFileName().split(".")[0]
|
||||
repository.addToPendingQueue(
|
||||
PendingUploads(
|
||||
pendingId,
|
||||
DataHolder.mobileUniqueId!!,
|
||||
testDetails!!.patientID,
|
||||
csvFilePath,
|
||||
Calendar.getInstance().time
|
||||
)
|
||||
)
|
||||
}
|
||||
viewModelScope.launch {
|
||||
val detailedCsvFilePath = MyUtils.getAppFolderPath(context) + getDetailedCSVFileName()
|
||||
val pendingId = getDetailedCSVFileName().split(".")[0]
|
||||
repository.addToPendingQueue(
|
||||
PendingUploads(
|
||||
pendingId,
|
||||
DataHolder.mobileUniqueId!!,
|
||||
testDetails!!.patientID,
|
||||
detailedCsvFilePath,
|
||||
Calendar.getInstance().time
|
||||
)
|
||||
)
|
||||
}
|
||||
viewModelScope.launch {
|
||||
val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName()
|
||||
val pendingId = getLogFileName().split(".")[0]
|
||||
repository.addToPendingQueue(
|
||||
PendingUploads(
|
||||
pendingId,
|
||||
DataHolder.mobileUniqueId!!,
|
||||
testDetails!!.patientID,
|
||||
logTxtFilePath,
|
||||
Calendar.getInstance().time
|
||||
)
|
||||
)
|
||||
fun uploadResultToDatabase(context: Context, isOnline: Boolean) = viewModelScope.launch {
|
||||
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName()
|
||||
val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName()
|
||||
testDetails?.csvPath = csvFilePath
|
||||
testDetails?.reportPath = logTxtFilePath
|
||||
if (isOnline) {
|
||||
val storageRef = FirebaseStorage.getInstance().reference
|
||||
val storageTestDetailsRef = storageRef.child("${testDetails?._id}/")
|
||||
|
||||
try {
|
||||
val csvFileUri = Uri.fromFile(File(csvFilePath))
|
||||
val logTxtFileUri = Uri.fromFile(File(logTxtFilePath))
|
||||
|
||||
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()
|
||||
|
||||
testDetails?.csvPath = csvUri
|
||||
testDetails?.reportPath = logUri
|
||||
|
||||
addResultTestToDb()
|
||||
} catch (exception: Exception) {
|
||||
// Handle the exception appropriately (e.g., log the error, display an error message)
|
||||
}
|
||||
} else {
|
||||
testDetails?.testTime = Calendar.getInstance().time.toString()
|
||||
userDao.insertAll(testDetails!!)
|
||||
}
|
||||
}
|
||||
|
||||
fun addFilesToCloud(context: Context) {
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName()
|
||||
val fileName = getCSVFileName().split(".")[0]
|
||||
val response = repository.uploadFileToStorage(testDetails!!.patientID, csvFilePath)
|
||||
fun bulkUploadResultToDatabase(userData: UserData) = viewModelScope.launch {
|
||||
val storageRef = FirebaseStorage.getInstance().reference
|
||||
val storageTestDetailsRef = storageRef.child("${testDetails?._id}/")
|
||||
try {
|
||||
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 -> {
|
||||
Log.d(TAG, "Uploaded $csvFilePath")
|
||||
repository.removeFromPendingQueue(fileName)
|
||||
}
|
||||
|
||||
is Response.Error -> {
|
||||
Log.d(TAG, response.exception.toString())
|
||||
fireBaseUpload.postValue("Success")
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
val detailedCsvFilePath =
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
fun deleteById(userId: String) = viewModelScope.launch {
|
||||
userDao.deleteById(id = userId)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.presentation.testRight
|
||||
package com.example.hpostesting.presentation.testRight
|
||||
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
@@ -6,10 +6,9 @@ import android.hardware.usb.UsbDeviceConnection
|
||||
import android.os.Binder
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import com.example.hpos.data.DataHolder
|
||||
import com.example.hpos.data.constant.Constants
|
||||
import com.example.hpos.data.constant.TestRightCommands
|
||||
import com.example.hpos.presentation.UsbServiceListener
|
||||
import com.example.hpostesting.data.constant.Constants
|
||||
import com.example.hpostesting.data.constant.TestRightCommands
|
||||
import com.example.hpostesting.presentation.UsbServiceListener
|
||||
import com.hoho.android.usbserial.driver.UsbSerialDriver
|
||||
import com.hoho.android.usbserial.driver.UsbSerialPort
|
||||
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 {
|
||||
fun onClickNegativeButton()
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos.presentation.utils
|
||||
package com.example.hpostesting.presentation.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.hpos
|
||||
package com.example.hpostesting
|
||||
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
@@ -1,12 +1,11 @@
|
||||
package com.example.hpos.util
|
||||
package com.example.hpostesting.util
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Environment
|
||||
import com.example.hpos.R
|
||||
import com.example.hpos.data.model.patient.PatientDetails
|
||||
import com.example.hpostesting.data.model.patient.PatientDetails
|
||||
import `in`.sminnovations.hpostesting.R
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.net.InetAddress
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
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_constraintTop_toBottomOf="@id/my_toolbar" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cv_item1"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
@@ -70,9 +70,9 @@
|
||||
|
||||
</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:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
@@ -113,9 +113,9 @@
|
||||
|
||||
</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:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
@@ -155,10 +155,10 @@
|
||||
|
||||
</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:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
@@ -199,7 +199,7 @@
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,23 +1,90 @@
|
||||
<?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: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
|
||||
android:id="@+id/internetNotAvailableCL"
|
||||
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
|
||||
android:id="@+id/tv_title"
|
||||
style="@style/title1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/list_of_patients"
|
||||
android:text="@string/user_list"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/uploadData"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/upload_data"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tv_title"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/tv_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_not_available"
|
||||
style="@style/title1_1"
|
||||
@@ -32,43 +99,82 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_title" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cardView4"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardElevation="0dp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_title"
|
||||
tools:layout_editor_absoluteX="24dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.appcompat.widget.SearchView
|
||||
android:id="@+id/search_product"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:background="@drawable/edit_text_background"
|
||||
android:inputType="text"
|
||||
app:iconifiedByDefault="false"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<requestFocus />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/radioGroup"
|
||||
android:layout_width="0dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/cardView4">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/userIdRadioButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/user_id" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/abhaIdRadioButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/abha_id"
|
||||
app:layout_constraintTop_toBottomOf="@id/userIdRadioButton" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/aadharIdRadioButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/aadhar_id"
|
||||
app:layout_constraintTop_toBottomOf="@id/abhaIdRadioButton" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_order"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="16dp"
|
||||
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:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_test"
|
||||
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" />
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/radioGroup"
|
||||
tools:listitem="@layout/user_item_view"/>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
</layout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -253,7 +253,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/cv_sample_details" />
|
||||
|
||||
<TextView
|
||||
style="@style/title3"
|
||||
style="@style/title2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/home"
|
||||
@@ -277,7 +277,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/cv_sample_details" />
|
||||
|
||||
<TextView
|
||||
style="@style/title3"
|
||||
style="@style/title2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/new_test"
|
||||
@@ -289,8 +289,9 @@
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/gray"
|
||||
android:layout_centerInParent="true"
|
||||
android:indeterminate="true"
|
||||
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