Change the project into Testing app

This commit is contained in:
mohamedkaif356
2023-06-28 12:41:18 +05:30
parent 69df710006
commit 0c063583ca
118 changed files with 1729 additions and 2760 deletions

View File

@@ -2,15 +2,19 @@ plugins {
id 'com.android.application' id 'com.android.application'
id 'org.jetbrains.kotlin.android' id 'org.jetbrains.kotlin.android'
id 'com.google.firebase.appdistribution' id 'com.google.firebase.appdistribution'
id 'dagger.hilt.android.plugin'
id 'com.google.gms.google-services' id 'com.google.gms.google-services'
id 'androidx.navigation.safeargs.kotlin'
id 'kotlin-kapt'
} }
//apply plugin: 'kotlin-android' //apply plugin: 'kotlin-android'
android { android {
compileSdk 33 compileSdk 33
namespace 'in.sminnovations.hpostesting'
defaultConfig { defaultConfig {
applicationId "com.example.hpos" applicationId "in.sminnovations.hpostesting"
minSdk 21 minSdk 21
targetSdk 33 targetSdk 33
versionCode 2 versionCode 2
@@ -26,11 +30,11 @@ android {
} }
} }
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_17
} }
kotlinOptions { kotlinOptions {
jvmTarget = '1.8' jvmTarget = '17'
} }
dataBinding { dataBinding {
enabled = true enabled = true
@@ -48,19 +52,21 @@ android {
dependencies { dependencies {
implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.appcompat:appcompat:1.5.1' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.7.0' implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1' implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.5.2'
// Firebase //firebase
implementation 'com.google.firebase:firebase-firestore-ktx:24.4.1' implementation platform('com.google.firebase:firebase-bom:32.1.0')
implementation 'com.google.firebase:firebase-storage-ktx:20.1.0' implementation 'com.google.firebase:firebase-firestore-ktx'
implementation 'com.google.firebase:firebase-auth-ktx'
implementation 'com.google.firebase:firebase-storage-ktx'
implementation 'com.firebaseui:firebase-ui-firestore:8.0.2'
implementation 'com.google.android.gms:play-services-auth:20.5.0'
implementation 'com.google.android.gms:play-services-location:21.0.1' implementation 'com.google.android.gms:play-services-location:21.0.1'
// implementation 'androidx.core:core-ktx:+' implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
// Testing // Testing
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
@@ -68,11 +74,11 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
implementation 'com.opencsv:opencsv:4.6' implementation 'com.opencsv:opencsv:4.6'
implementation 'com.github.mik3y:usb-serial-for-android:3.4.6' implementation 'com.github.mik3y:usb-serial-for-android:3.4.6'
implementation "androidx.fragment:fragment-ktx:1.5.5" implementation "androidx.fragment:fragment-ktx:1.6.0"
// CSV read, write // CSV read, write
implementation 'com.opencsv:opencsv:4.6' implementation 'com.opencsv:opencsv:4.6'
@@ -83,7 +89,26 @@ dependencies {
// Google ML Kit usign play services // Google ML Kit usign play services
implementation 'com.google.android.gms:play-services-code-scanner:16.0.0' implementation 'com.google.android.gms:play-services-code-scanner:16.0.0'
} //Room
//repositories { implementation "androidx.room:room-ktx:2.6.0-alpha01"
// mavenCentral() implementation "androidx.room:room-runtime:2.6.0-alpha01"
//} kapt ("androidx.room:room-compiler:2.6.0-alpha01")
//image
implementation 'com.github.bumptech.glide:glide:4.13.2'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
// Navigation Component
implementation "androidx.navigation:navigation-fragment-ktx:2.7.0-beta01"
implementation "androidx.navigation:navigation-ui-ktx:2.7.0-beta01"
//Dagger - Hilt
implementation "com.google.dagger:hilt-android:2.46"
kapt "com.google.dagger:hilt-android-compiler:2.46"
kapt "androidx.hilt:hilt-compiler:1.0.0"
// Retrofit + GSON
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
}

View File

@@ -1,4 +1,4 @@
package com.example.hpos package com.example.hpostesting
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry

View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools">
package="com.example.hpos">
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -16,7 +15,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application <application
android:name=".MyApplication" android:name="com.example.hpostesting.HPOSTestingApplication"
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
@@ -24,26 +23,27 @@
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/hpos_icon_round" android:roundIcon="@mipmap/hpos_icon_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.HPOS" android:theme="@style/Theme.HPOSTesting"
tools:targetApi="31"> tools:targetApi="31">
<activity <activity
android:name=".presentation.KitScanActivity" android:name="com.example.hpostesting.presentation.KitScanActivity"
android:noHistory="true" android:noHistory="true"
android:exported="false" /> android:exported="false"
android:theme="@style/Theme.HPOS.NoActionBar"/>
<activity <activity
android:name=".presentation.dashboard.DashboardActivity" android:name="com.example.hpostesting.presentation.dashboard.DashboardActivity"
android:exported="false" android:exported="false"
android:label="@string/title_activity_dashboard" android:label="@string/title_activity_dashboard"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/Theme.HPOS.NoActionBar" /> android:theme="@style/Theme.HPOS.NoActionBar" />
<service <service
android:name=".presentation.testRight.UsbService" android:name="com.example.hpostesting.presentation.testRight.UsbService"
android:enabled="true" android:enabled="true"
android:exported="false" /> android:exported="false" />
<activity <activity
android:name=".presentation.SplashActivity" android:name="com.example.hpostesting.presentation.SplashActivity"
android:exported="true" android:exported="true"
android:noHistory="true" android:noHistory="true"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
@@ -54,12 +54,13 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".presentation.testRight.TestRightActivity" android:name="com.example.hpostesting.presentation.testRight.TestRightActivity"
android:exported="false" android:exported="false"
android:parentActivityName=".presentation.MainActivity" android:parentActivityName="com.example.hpostesting.presentation.MainActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:noHistory="true" android:noHistory="true"
android:windowSoftInputMode="adjustPan"> android:windowSoftInputMode="adjustPan"
android:theme="@style/Theme.HPOS.NoActionBar">
<!-- <intent-filter> --> <!-- <intent-filter> -->
<!-- <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> --> <!-- <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> -->
@@ -71,9 +72,10 @@
<!-- android:resource="@xml/device_filter" /> --> <!-- android:resource="@xml/device_filter" /> -->
</activity> <!-- android:theme="@style/Theme.HPOS.ActionBar" --> </activity> <!-- android:theme="@style/Theme.HPOS.ActionBar" -->
<activity <activity
android:name=".presentation.MainActivity" android:name="com.example.hpostesting.presentation.MainActivity"
android:exported="true" android:exported="true"
android:screenOrientation="portrait"> android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter> <intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter> </intent-filter>
@@ -88,9 +90,6 @@
android:stateNotNeeded="true" android:stateNotNeeded="true"
tools:replace="android:screenOrientation" /> tools:replace="android:screenOrientation" />
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
</application> </application>
</manifest> </manifest>

View File

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

View File

@@ -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;
}
}

View File

@@ -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)
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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
}
}

View File

@@ -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()
// }
}

View File

@@ -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
}
}
}

View File

@@ -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)
}
}
}

View File

@@ -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
}
}

View File

@@ -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
// }
}

View File

@@ -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()
}
}
}

View File

@@ -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()
}
}

View File

@@ -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)
}
}

View File

@@ -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");
}
}

View File

@@ -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)
}

View File

@@ -1,9 +1,9 @@
package com.example.hpos.data package com.example.hpostesting.data
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.example.hpos.data.model.test.TestDetails import com.example.hpostesting.data.model.patient.UserData
import com.example.hpos.data.model.test.TestRightDeviceConstants import com.example.hpostesting.data.model.test.TestRightDeviceConstants
import com.example.hpos.data.model.test.TestType import com.example.hpostesting.data.model.test.TestType
object DataHolder { object DataHolder {
@@ -28,7 +28,9 @@ object DataHolder {
/* (For reference/baseline) Contains pixel no. -> Intensity of light falling on that pixel */ /* (For reference/baseline) Contains pixel no. -> Intensity of light falling on that pixel */
val intensityReferenceArray = ArrayList<Double>() val intensityReferenceArray = ArrayList<Double>()
var selectedTest: TestDetails? = null var selectedTest: UserData? = null
var location: UserData.Location? = null
var testExp: Boolean = true var testExp: Boolean = true
} }

View File

@@ -1,12 +1,11 @@
package com.example.hpos.data package com.example.hpostesting.data
import android.util.Log import android.util.Log
import com.example.hpos.data.model.Response import com.example.hpostesting.data.model.Response
import com.example.hpos.data.repository.DatabaseRepository import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpos.util.MyUtils import com.example.hpostesting.util.MyUtils
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.lang.Thread.sleep
class FileUploader { class FileUploader {

View File

@@ -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)
}
}

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data package com.example.hpostesting.data
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.constant package com.example.hpostesting.data.constant
object Constants { object Constants {
const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION" const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION"

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.constant package com.example.hpostesting.data.constant
enum class TestRightCommands(val command: String) { enum class TestRightCommands(val command: String) {
led2Set50("led2 50\r"), led2Set50("led2 50\r"),

View File

@@ -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
}
}
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.datasource package com.example.hpostesting.data.datasource
import com.opencsv.CSVWriter import com.opencsv.CSVWriter
import java.io.File import java.io.File

View 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 = ""
}

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.model package com.example.hpostesting.data.model
data class CalculationVariableForTest( data class CalculationVariableForTest(
var pixelNo: Int, var pixelNo: Int,

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.model package com.example.hpostesting.data.model
data class ErrorMessage ( data class ErrorMessage (
val message: String, val message: String,

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.model package com.example.hpostesting.data.model
data class Location( data class Location(
var latitude: Double?, var latitude: Double?,

View File

@@ -1,6 +1,6 @@
package com.example.hpos.data.model package com.example.hpostesting.data.model
import com.example.hpos.data.model.test.TestRightResultType import com.example.hpostesting.data.model.test.TestRightResultType
data class PatientData( data class PatientData(
val name: String, val name: String,

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.model package com.example.hpostesting.data.model
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.model package com.example.hpostesting.data.model
sealed class Response<out R> { sealed class Response<out R> {
data class Success<out T>(val data: T) : Response<T>() data class Success<out T>(val data: T) : Response<T>()

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.model.patient package com.example.hpostesting.data.model.patient
import java.util.Date import java.util.Date

View File

@@ -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
)
}

View File

@@ -1,6 +1,6 @@
package com.example.hpos.data.model.test package com.example.hpostesting.data.model.test
import com.example.hpos.data.model.Location import com.example.hpostesting.data.model.Location
import java.util.Date import java.util.Date
data class TestDetails( data class TestDetails(

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.model.test package com.example.hpostesting.data.model.test
data class TestInfo( data class TestInfo(
val value: String, val value: String,

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.model.test package com.example.hpostesting.data.model.test
data class TestRightCalculationData( data class TestRightCalculationData(
var absorbanceOne: Double?, var absorbanceOne: Double?,

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.model.test package com.example.hpostesting.data.model.test
data class TestRightDeviceConstants( data class TestRightDeviceConstants(
var a: String, var a: String,

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.model.test package com.example.hpostesting.data.model.test
enum class TestRightResultType { enum class TestRightResultType {
NORMAL, NORMAL,

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.model.test package com.example.hpostesting.data.model.test
enum class TestType { enum class TestType {
SICKLECERT, SICKLECERT,

View File

@@ -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)
}
}
}

View File

@@ -1,6 +1,6 @@
package com.example.hpos.data.repository package com.example.hpostesting.data.repository
import com.example.hpos.data.datasource.LocalFileDataSource import com.example.hpostesting.data.datasource.LocalFileDataSource
class LocalFileRepository(private val localFileDataSource: LocalFileDataSource) { class LocalFileRepository(private val localFileDataSource: LocalFileDataSource) {
fun saveCsvToDisk(filepath: String, contents: ArrayList<Array<String>>) = fun saveCsvToDisk(filepath: String, contents: ArrayList<Array<String>>) =

View File

@@ -1,4 +1,4 @@
package com.example.hpos.data.repository package com.example.hpostesting.data.repository
interface Repository { interface Repository {
// suspend fun addToDatabase(data: PatientDetails) // suspend fun addToDatabase(data: PatientDetails)

View File

@@ -1,8 +1,8 @@
package com.example.hpos.domain package com.example.hpostesting.domain
import com.example.hpos.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpos.data.model.test.TestRightCalculationData import com.example.hpostesting.data.model.test.TestRightCalculationData
import com.example.hpos.data.model.test.TestRightResultType import com.example.hpostesting.data.model.test.TestRightResultType
class ResultCalculationWithAvgImpl : TestRightResultCalculation { class ResultCalculationWithAvgImpl : TestRightResultCalculation {

View File

@@ -1,8 +1,8 @@
package com.example.hpos.domain package com.example.hpostesting.domain
import android.util.Log import android.util.Log
import com.example.hpos.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpos.data.model.test.TestRightResultType import com.example.hpostesting.data.model.test.TestRightResultType
import kotlin.math.log10 import kotlin.math.log10
class ResultCalculationWithFirstImpl { class ResultCalculationWithFirstImpl {

View File

@@ -1,8 +1,8 @@
package com.example.hpos.domain package com.example.hpostesting.domain
import com.example.hpos.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpos.data.model.test.TestRightCalculationData import com.example.hpostesting.data.model.test.TestRightCalculationData
import com.example.hpos.data.model.test.TestRightResultType import com.example.hpostesting.data.model.test.TestRightResultType
class ResultCalculationWithMaxImpl : TestRightResultCalculation { class ResultCalculationWithMaxImpl : TestRightResultCalculation {

View File

@@ -1,10 +1,10 @@
package com.example.hpos.domain package com.example.hpostesting.domain
import android.util.Log import android.util.Log
import com.example.hpos.data.repository.LocalFileRepository import com.example.hpostesting.data.repository.LocalFileRepository
import com.example.hpos.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpos.data.model.test.TestDetails import com.example.hpostesting.data.model.patient.UserData
import com.example.hpos.data.model.test.TestRightCalculationData import com.example.hpostesting.data.model.test.TestRightCalculationData
import java.util.Collections.sort import java.util.Collections.sort
class SaveRawData(private val localFileRepository: LocalFileRepository) { class SaveRawData(private val localFileRepository: LocalFileRepository) {
@@ -98,7 +98,7 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) {
folderPath: String, folderPath: String,
fileName: String, fileName: String,
calculationData: TestRightCalculationData, calculationData: TestRightCalculationData,
testDetails: TestDetails? testDetails: UserData?
) { ) {
// val fileObj = File(folderPath, fileName) // val fileObj = File(folderPath, fileName)
// val writer = FileWriter(fileObj) // val writer = FileWriter(fileObj)
@@ -116,11 +116,11 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) {
private fun getLogStringFromObjWithPatientData( private fun getLogStringFromObjWithPatientData(
calculationData: TestRightCalculationData, calculationData: TestRightCalculationData,
testDetails: TestDetails? testDetails: UserData?
): String { ): String {
var outputString = "Test calculation logs ==>\n" var outputString = "Test calculation logs ==>\n"
outputString += "Name = ${testDetails?.patientName}\n" outputString += "Name = ${testDetails?.name}\n"
outputString += "ID = ${testDetails?.patientID}\n" outputString += "ID = ${testDetails?._id}\n"
// outputString += "Gender = ${patientData.gender}\n" // outputString += "Gender = ${patientData.gender}\n"
outputString += "Absorbance one = ${ outputString += "Absorbance one = ${
String.format( String.format(

View File

@@ -1,7 +1,7 @@
package com.example.hpos.domain package com.example.hpostesting.domain
import com.example.hpos.data.repository.LocalFileRepository import com.example.hpostesting.data.repository.LocalFileRepository
import com.example.hpos.data.model.CalculationVariableForTest import com.example.hpostesting.data.model.CalculationVariableForTest
class SaveRawDataTest(private val localFileRepository: LocalFileRepository) { class SaveRawDataTest(private val localFileRepository: LocalFileRepository) {

View File

@@ -1,8 +1,8 @@
package com.example.hpos.domain package com.example.hpostesting.domain
import com.example.hpos.data.constant.Constants import com.example.hpostesting.data.constant.Constants
import com.example.hpos.data.model.test.TestRightCalculationData import com.example.hpostesting.data.model.test.TestRightCalculationData
import com.example.hpos.data.model.test.TestRightResultType import com.example.hpostesting.data.model.test.TestRightResultType
class SickleFindResultCaluculationWithMaxImpl : TestRightResultCalculation{ class SickleFindResultCaluculationWithMaxImpl : TestRightResultCalculation{

View File

@@ -1,6 +1,6 @@
package com.example.hpos.domain package com.example.hpostesting.domain
import com.example.hpos.data.model.test.TestRightCalculationData import com.example.hpostesting.data.model.test.TestRightCalculationData
interface TestRightResultCalculation { interface TestRightResultCalculation {
fun getResults( fun getResults(

View File

@@ -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()
}
}

View File

@@ -1,19 +1,19 @@
package com.example.hpos.presentation package com.example.hpostesting.presentation
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.example.hpos.R import com.example.hpostesting.data.DataHolder
import com.example.hpos.data.DataHolder import com.example.hpostesting.data.constant.Constants
import com.example.hpos.data.constant.Constants import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpos.databinding.ActivityKitScanBinding import com.example.hpostesting.presentation.testRight.TestRightActivity
import com.example.hpos.presentation.dashboard.DashboardActivity
import com.example.hpos.presentation.testRight.TestRightActivity
import com.journeyapps.barcodescanner.ScanContract import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanIntentResult import com.journeyapps.barcodescanner.ScanIntentResult
import com.journeyapps.barcodescanner.ScanOptions import com.journeyapps.barcodescanner.ScanOptions
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityKitScanBinding
class KitScanActivity : AppCompatActivity() { class KitScanActivity : AppCompatActivity() {
@@ -51,6 +51,7 @@ class KitScanActivity : AppCompatActivity() {
startScanningNow() startScanningNow()
} }
binding.btnGo.setOnClickListener { binding.btnGo.setOnClickListener {
val serialNumber = binding.nameEditText.text.toString().trim() val serialNumber = binding.nameEditText.text.toString().trim()
if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid(serialNumber)) { if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid(serialNumber)) {
@@ -92,7 +93,7 @@ class KitScanActivity : AppCompatActivity() {
} }
private fun checkDataNotNull(): Boolean { private fun checkDataNotNull(): Boolean {
return if (DataHolder.selectedTest == null) { return if (DataHolder.selectedTest?._id == null) {
Toast.makeText( Toast.makeText(
applicationContext, applicationContext,
"Please Select patient before starting test", "Please Select patient before starting test",

View File

@@ -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()
}
}
}
}
}

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation package com.example.hpostesting.presentation
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel

View File

@@ -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
}
}
}

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation package com.example.hpostesting.presentation
interface UsbServiceListener { interface UsbServiceListener {
fun onUsbRead(data: ByteArray?) fun onUsbRead(data: ByteArray?)

View File

@@ -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)
}
}
}
}
}
}

View File

@@ -1,27 +1,24 @@
package com.example.hpos.presentation.dashboard package com.example.hpostesting.presentation.dashboard
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import com.example.hpos.R
import com.example.hpos.databinding.ActivityDashboardBinding
import com.example.hpos.util.MyUtils
import com.example.hpos.util.MyViewModelFactory
import com.google.android.material.navigation.NavigationView import com.google.android.material.navigation.NavigationView
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding
@AndroidEntryPoint
class DashboardActivity : AppCompatActivity() { class DashboardActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityDashboardBinding private lateinit var binding: ActivityDashboardBinding
private lateinit var viewModel: DashboardViewModel
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -43,10 +40,6 @@ class DashboardActivity : AppCompatActivity() {
setupActionBarWithNavController(navController, appBarConfiguration) setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController) navView.setupWithNavController(navController)
viewModel = ViewModelProvider(
this,
MyViewModelFactory()
)[DashboardViewModel::class.java]
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.dashboard package com.example.hpostesting.presentation.dashboard
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
@@ -6,8 +6,8 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.example.hpos.databinding.FragmentGalleryBinding import com.example.hpostesting.presentation.dashboard.ui.gallery.GalleryViewModel
import com.example.hpos.presentation.dashboard.ui.gallery.GalleryViewModel import `in`.sminnovations.hpostesting.databinding.FragmentGalleryBinding
class GalleryFragment : Fragment() { class GalleryFragment : Fragment() {

View File

@@ -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
}
}

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.dashboard package com.example.hpostesting.presentation.dashboard
interface ItemClickListener { interface ItemClickListener {
fun onClick(pos: Int) fun onClick(pos: Int)

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.dashboard package com.example.hpostesting.presentation.dashboard
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
@@ -6,8 +6,8 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.example.hpos.databinding.FragmentSlideshowBinding import com.example.hpostesting.presentation.dashboard.ui.slideshow.SlideshowViewModel
import com.example.hpos.presentation.dashboard.ui.slideshow.SlideshowViewModel import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding
class SlideshowFragment : Fragment() { class SlideshowFragment : Fragment() {

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.dashboard.ui.gallery package com.example.hpostesting.presentation.dashboard.ui.gallery
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.dashboard.ui.home package com.example.hpostesting.presentation.dashboard.ui.home
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.dashboard.ui.slideshow package com.example.hpostesting.presentation.dashboard.ui.slideshow
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.testRight package com.example.hpostesting.presentation.testRight
class InputData { class InputData {
val inputRead = "0,1.69989422e-06,1.60642711e-01,3.85754470e+02,0,0,1,0,FFF-EEEE-PPPP-WW-YY-NNNN\nOK [0]" val inputRead = "0,1.69989422e-06,1.60642711e-01,3.85754470e+02,0,0,1,0,FFF-EEEE-PPPP-WW-YY-NNNN\nOK [0]"

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.testRight package com.example.hpostesting.presentation.testRight
import android.app.PendingIntent import android.app.PendingIntent
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
@@ -15,23 +15,24 @@ import android.os.IBinder
import android.util.Log import android.util.Log
import android.view.Menu import android.view.Menu
import android.widget.Toast import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.get import androidx.core.view.get
import androidx.lifecycle.ViewModelProvider import com.example.hpostesting.data.DataHolder
import com.example.hpos.R import com.example.hpostesting.data.constant.Constants
import com.example.hpos.data.DataHolder
import com.example.hpos.data.constant.Constants
import com.example.hpos.databinding.ActivityTestRightBinding
import com.example.hpos.util.MyViewModelFactory
import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber import com.hoho.android.usbserial.driver.UsbSerialProber
import dagger.hilt.android.AndroidEntryPoint
import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.ActivityTestRightBinding
@AndroidEntryPoint
class TestRightActivity : AppCompatActivity() { class TestRightActivity : AppCompatActivity() {
private lateinit var binding: ActivityTestRightBinding private lateinit var binding: ActivityTestRightBinding
private lateinit var viewModel: TestRightViewModel private val viewModel by viewModels<TestRightViewModel>()
private var myMenu: Menu? = null private var myMenu: Menu? = null
private lateinit var mDriver: UsbSerialDriver private lateinit var mDriver: UsbSerialDriver
@@ -78,10 +79,6 @@ class TestRightActivity : AppCompatActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityTestRightBinding.inflate(layoutInflater) binding = ActivityTestRightBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
viewModel = ViewModelProvider(
this,
MyViewModelFactory()
)[TestRightViewModel::class.java]
setSupportActionBar(binding.myToolbar) setSupportActionBar(binding.myToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.testRight package com.example.hpostesting.presentation.testRight
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@@ -10,17 +10,19 @@ import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpos.R import com.example.hpostesting.data.DataHolder
import com.example.hpos.data.DataHolder import com.example.hpostesting.data.constant.Constants
import com.example.hpos.data.constant.Constants import com.example.hpostesting.data.constant.TestRightCommands
import com.example.hpos.data.constant.TestRightCommands import com.example.hpostesting.data.model.ErrorMessage
import com.example.hpos.data.model.ErrorMessage import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpos.databinding.FragmentTestRightExpReferenceBinding import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpos.presentation.UsbServiceListener import com.example.hpostesting.presentation.utils.UIUtils
import com.example.hpos.presentation.utils.MyDialogListener import dagger.hilt.android.AndroidEntryPoint
import com.example.hpos.presentation.utils.UIUtils import `in`.sminnovations.hpostesting.R
import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpReferenceBinding
@AndroidEntryPoint
class TestRightExpReference : Fragment() { class TestRightExpReference : Fragment() {
private lateinit var binding: FragmentTestRightExpReferenceBinding private lateinit var binding: FragmentTestRightExpReferenceBinding

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.testRight package com.example.hpostesting.presentation.testRight
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
@@ -10,19 +10,20 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpos.R import com.example.hpostesting.data.DataHolder
import com.example.hpos.data.DataHolder import com.example.hpostesting.data.constant.Constants
import com.example.hpos.data.PreferenceUtility import com.example.hpostesting.data.constant.TestRightCommands
import com.example.hpos.data.constant.Constants import com.example.hpostesting.data.model.ErrorMessage
import com.example.hpos.data.constant.TestRightCommands import com.example.hpostesting.data.model.test.TestType
import com.example.hpos.data.model.ErrorMessage import com.example.hpostesting.presentation.MainActivity
import com.example.hpos.data.model.test.TestType import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpos.databinding.FragmentTestRightExpSampleBinding import com.example.hpostesting.presentation.utils.MyDialogListener
import com.example.hpos.presentation.MainActivity import com.example.hpostesting.presentation.utils.UIUtils
import com.example.hpos.presentation.UsbServiceListener import dagger.hilt.android.AndroidEntryPoint
import com.example.hpos.presentation.utils.MyDialogListener import `in`.sminnovations.hpostesting.R
import com.example.hpos.presentation.utils.UIUtils import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpSampleBinding
@AndroidEntryPoint
class TestRightExpSample : Fragment() { class TestRightExpSample : Fragment() {
private lateinit var binding: FragmentTestRightExpSampleBinding private lateinit var binding: FragmentTestRightExpSampleBinding
@@ -256,11 +257,9 @@ class TestRightExpSample : Fragment() {
// val fileNameCsv = prefixCsv + id + fileExtensionCsv // val fileNameCsv = prefixCsv + id + fileExtensionCsv
// NEW ------------------------------ // NEW ------------------------------
viewModel.saveCsv(requireContext().applicationContext, viewModel.getCSVFileName()) viewModel.saveCsv(requireContext().applicationContext, viewModel.getCSVFileName())
viewModel.saveCsvForTesting(requireContext().applicationContext, viewModel.getDetailedCSVFileName()) // viewModel.saveCsvForTesting(requireContext().applicationContext, viewModel.getDetailedCSVFileName())
viewModel.saveLogWithPatient(requireContext().applicationContext, viewModel.getLogFileName()) viewModel.saveLogWithPatient(requireContext().applicationContext, viewModel.getLogFileName())
} }

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.testRight package com.example.hpostesting.presentation.testRight
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
@@ -9,32 +9,35 @@ import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.example.hpos.R import com.example.hpostesting.data.DataHolder
import com.example.hpos.data.DataHolder import com.example.hpostesting.data.constant.Constants
import com.example.hpos.data.PreferenceUtility import com.example.hpostesting.data.model.test.TestRightResultType
import com.example.hpos.data.constant.Constants import com.example.hpostesting.data.model.test.TestType
import com.example.hpos.data.model.test.TestRightResultType import com.example.hpostesting.presentation.dashboard.DashboardActivity
import com.example.hpos.data.model.test.TestType import com.example.hpostesting.util.MyUtils.calculateAgeFromYOB
import com.example.hpos.databinding.FragmentTestRightResultsBinding import dagger.hilt.android.AndroidEntryPoint
import com.example.hpos.presentation.dashboard.DashboardActivity import `in`.sminnovations.hpostesting.R
import com.example.hpos.util.MyUtils import `in`.sminnovations.hpostesting.databinding.FragmentTestRightResultsBinding
import com.example.hpos.util.MyUtils.calculateAgeFromYOB
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
@AndroidEntryPoint
class TestRightResults : Fragment() { class TestRightResults : Fragment() {
private lateinit var binding: FragmentTestRightResultsBinding private lateinit var binding: FragmentTestRightResultsBinding
private val viewModel: TestRightViewModel by activityViewModels() private val viewModel: TestRightViewModel by activityViewModels()
private val TAG = "TestRightResults" private val TAG = "TestRightResults"
private var isOnline = false
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
savedInstanceState: Bundle?
): View { ): View {
// Inflate the layout for this fragment // Inflate the layout for this fragment
binding = FragmentTestRightResultsBinding.inflate(inflater, container, false) binding = FragmentTestRightResultsBinding.inflate(inflater, container, false)
viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable ->
isOnline = isNetworkAvailable
}
return binding.root return binding.root
} }
@@ -43,14 +46,13 @@ class TestRightResults : Fragment() {
setupListeners() setupListeners()
updateResults() updateResults()
viewModel.addResultTestToDb() viewModel.fireBaseUpload.observe(viewLifecycleOwner) {
if (it == "Success") {
// This is to add files to the pending queue Toast.makeText(
viewModel.addFilesToQueue(requireContext()) requireContext(), "Test Results Upload Successfully", Toast.LENGTH_SHORT
).show()
// Uploading to cloud storage and deleting the from the pending queue when uploaded }
if (MyUtils.isInternetConnected()) { binding.progressBar.visibility = View.GONE
viewModel.addFilesToCloud(requireContext())
} }
} }
@@ -68,35 +70,49 @@ class TestRightResults : Fragment() {
} }
private fun updateResults() { private fun updateResults() {
binding.tvName.text = getString(R.string.name_in_textview, viewModel.testDetails?.patientName) if (viewModel.testDetails?.name == "" && viewModel.testDetails?.birthYear == "") {
binding.tvAge.text = binding.tvName.visibility = View.GONE
getString(R.string.age_in_textview, viewModel.testDetails?.patientAge?.calculateAgeFromYOB().toString()) binding.tvAge.visibility = View.GONE
} else {
binding.tvName.text = getString(R.string.name_in_textview, viewModel.testDetails?.name)
binding.tvAge.text = getString(
R.string.age_in_textview,
viewModel.testDetails?.birthYear?.toInt()?.calculateAgeFromYOB().toString()
)
}
binding.tvId.text = getString(R.string.patient_id_in_tv, viewModel.testDetails?.patientID) binding.tvId.text = getString(R.string.patient_id_in_tv, viewModel.testDetails?._id)
if (DataHolder.selectedTestType == TestType.SICKLECERT){ if (DataHolder.selectedTestType == TestType.SICKLECERT) {
when (viewModel.testDetails?.result) { when (viewModel.testDetails?.result) {
TestRightResultType.NORMAL -> { TestRightResultType.NORMAL -> {
binding.resultNormal.visibility = View.VISIBLE binding.resultNormal.visibility = View.VISIBLE
} }
TestRightResultType.SICKLECELLDISEASE -> { TestRightResultType.SICKLECELLDISEASE -> {
binding.resultDisease.visibility = View.VISIBLE binding.resultDisease.visibility = View.VISIBLE
} }
TestRightResultType.SICKLECELLTRAIT -> { TestRightResultType.SICKLECELLTRAIT -> {
binding.resultTrait.visibility = View.VISIBLE binding.resultTrait.visibility = View.VISIBLE
} }
TestRightResultType.POSITIVEBORDERLINE -> { TestRightResultType.POSITIVEBORDERLINE -> {
binding.resultPositiveBorderline.visibility = View.VISIBLE binding.resultPositiveBorderline.visibility = View.VISIBLE
binding.tvRecommended.visibility = View.VISIBLE binding.tvRecommended.visibility = View.VISIBLE
} }
TestRightResultType.NEGATIVEBORDERLINE -> { TestRightResultType.NEGATIVEBORDERLINE -> {
binding.resultNegativeBorderline.visibility = View.VISIBLE binding.resultNegativeBorderline.visibility = View.VISIBLE
binding.tvRecommended.visibility = View.VISIBLE binding.tvRecommended.visibility = View.VISIBLE
} }
else -> { else -> {
// binding.resultUndefined.visibility = View.VISIBLE // binding.resultUndefined.visibility = View.VISIBLE
Toast.makeText(requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG).show() Toast.makeText(
requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG
).show()
moveToSamplePage() moveToSamplePage()
} }
} }
@@ -106,20 +122,31 @@ class TestRightResults : Fragment() {
binding.resultDisease.visibility = View.VISIBLE binding.resultDisease.visibility = View.VISIBLE
binding.resultDisease.text = "Positive" binding.resultDisease.text = "Positive"
} }
TestRightResultType.NORMAL -> { TestRightResultType.NORMAL -> {
binding.resultNormal.visibility = View.VISIBLE binding.resultNormal.visibility = View.VISIBLE
binding.resultNormal.text = "Negative" binding.resultNormal.text = "Negative"
} }
else -> { else -> {
Toast.makeText(requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG).show() Toast.makeText(
requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG
).show()
moveToSamplePage() moveToSamplePage()
} }
} }
} }
// if (viewModel.patientDetails.age < 5) { if (isOnline) {
// binding.tvRecommended.visibility = View.VISIBLE viewModel.uploadResultToDatabase(requireContext(), true)
// binding.tvRecommended.text = getString(R.string.recommended_age) binding.progressBar.visibility = View.VISIBLE
// } } else {
viewModel.uploadResultToDatabase(requireContext(), false)
Toast.makeText(
requireContext(),
"Internet not available, Test Data added to Local DB",
Toast.LENGTH_SHORT
).show()
}
} }
@@ -127,8 +154,7 @@ class TestRightResults : Fragment() {
if (DataHolder.sampleReadCounter > Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE) { if (DataHolder.sampleReadCounter > Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE) {
DataHolder.sampleReadCounter = 0 DataHolder.sampleReadCounter = 0
DataHolder.isReferenceTaken = false DataHolder.isReferenceTaken = false
parentFragmentManager.beginTransaction() parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightExpReference())
.replace(R.id.fl_main, TestRightExpReference())
.commit() .commit()
} else { } else {
parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightExpSample()) parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightExpSample())
@@ -144,55 +170,6 @@ class TestRightResults : Fragment() {
viewModel.saveLog(requireContext().applicationContext, fileName) viewModel.saveLog(requireContext().applicationContext, fileName)
// if (!DataHolder.isAppFolderCreated) {
// val folderPath = MyUtils.createAppFolder(requireContext().applicationContext)
// if (folderPath != null) {
// DataHolder.isAppFolderCreated = true
// DataHolder.appFolderPath = folderPath
// viewModel.saveLog(DataHolder.appFolderPath, fileName)
// }
// } else {
// viewModel.saveLog(DataHolder.appFolderPath, fileName)
// }
} }
// private fun saveCsv() {
// Log.d(TAG, "saveCsv() called")
//
// val sdfDate = SimpleDateFormat("ddMMyyyy HHmmss")
// val fileName: String = sdfDate.format(Date()) + ".csv"
//
// if (!DataHolder.isAppFolderCreated) {
// val folderPath = MyUtils.createAppFolder(requireContext().applicationContext)
// if (folderPath != null) {
// DataHolder.isAppFolderCreated = true
// DataHolder.appFolderPath = folderPath
// viewModel.saveCsv(DataHolder.appFolderPath, fileName)
//
// viewModel.saveCsvForTesting(DataHolder.appFolderPath, "testing$fileName")
// }
// } else {
// viewModel.saveCsv(DataHolder.appFolderPath, fileName)
//
// viewModel.saveCsvForTesting(DataHolder.appFolderPath, "testing$fileName")
// }
//
// }
private fun saveCsv() {
Log.d(TAG, "saveCsv() called")
// val sdfDate = SimpleDateFormat("ddMMyyyy HHmmss")
// val fileName: String = sdfDate.format(Date()) + ".csv"
val prefix = "HPOSSC_${DataHolder.deviceSerialNumber}_"
val fileExtension = ".csv"
val fileName = PreferenceUtility.generateId(requireContext(), prefix) + fileExtension
viewModel.saveCsv(requireContext().applicationContext, fileName)
viewModel.saveCsvForTesting(requireContext().applicationContext, "testing$fileName")
}
} }

View File

@@ -1,56 +1,67 @@
package com.example.hpos.presentation.testRight package com.example.hpostesting.presentation.testRight
import android.content.Context import android.content.Context
import android.net.Uri
import android.util.Log import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.hpos.data.DataHolder import com.example.hpostesting.data.DataHolder
import com.example.hpos.data.repository.DatabaseRepository import com.example.hpostesting.data.NetworkStatusLiveData
import com.example.hpos.data.model.Response import com.example.hpostesting.data.constant.Constants
import com.example.hpos.data.constant.Constants import com.example.hpostesting.data.dao.UserDao
import com.example.hpos.data.model.CalculationVariableForTest import com.example.hpostesting.data.model.CalculationVariableForTest
import com.example.hpos.data.model.ErrorMessage import com.example.hpostesting.data.model.ErrorMessage
import com.example.hpos.data.model.PendingUploads import com.example.hpostesting.data.model.Response
import com.example.hpos.data.model.test.Status import com.example.hpostesting.data.model.patient.UserData
import com.example.hpos.data.model.test.TestRightCalculationData import com.example.hpostesting.data.model.test.TestRightCalculationData
import com.example.hpos.data.model.test.TestRightDeviceConstants import com.example.hpostesting.data.model.test.TestRightDeviceConstants
import com.example.hpos.data.model.test.TestType import com.example.hpostesting.data.model.test.TestType
import com.example.hpos.domain.ResultCalculationWithMaxImpl import com.example.hpostesting.data.repository.DatabaseRepository
import com.example.hpos.domain.SaveRawData import com.example.hpostesting.domain.ResultCalculationWithMaxImpl
import com.example.hpos.domain.SaveRawDataTest import com.example.hpostesting.domain.SaveRawData
import com.example.hpos.domain.SickleFindResultCaluculationWithMaxImpl import com.example.hpostesting.domain.SaveRawDataTest
import com.example.hpos.domain.TestRightResultCalculation import com.example.hpostesting.domain.SickleFindResultCaluculationWithMaxImpl
import com.example.hpos.util.MyUtils import com.example.hpostesting.domain.TestRightResultCalculation
import kotlinx.coroutines.Dispatchers import com.example.hpostesting.util.MyUtils
import kotlinx.coroutines.GlobalScope import com.google.firebase.storage.FirebaseStorage
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
import javax.inject.Inject
import kotlin.math.log10 import kotlin.math.log10
import kotlin.math.pow import kotlin.math.pow
class TestRightViewModel( @HiltViewModel
class TestRightViewModel @Inject constructor(
private val saveRawData: SaveRawData, private val saveRawData: SaveRawData,
private val saveRawDataTest: SaveRawDataTest, private val saveRawDataTest: SaveRawDataTest,
private val repository: DatabaseRepository private val repository: DatabaseRepository,
private val userDao: UserDao,
context: Context
) : ViewModel() { ) : ViewModel() {
private val TAG = "TestRightViewModel"
var isServiceConnected = false var isServiceConnected = false
val progressBar = MutableLiveData(false) val progressBar = MutableLiveData(false)
// val errorTriggered = MutableLiveData<String>("")
val errorTriggered = MutableLiveData<ErrorMessage>() val errorTriggered = MutableLiveData<ErrorMessage>()
var numberOfSampleRun = 0 var numberOfSampleRun = 0
// lateinit var patientDetails: PatientData val fireBaseUpload = MutableLiveData<String>()
val testDetails = DataHolder.selectedTest val testDetails = DataHolder.selectedTest
// var deviceConstant: TestRightDeviceConstants? = null private val _networkStatusLiveData = NetworkStatusLiveData(context)
val networkStatusLiveData: LiveData<Boolean>
get() = _networkStatusLiveData
val allUserData = userDao.getAll()
private lateinit var calculationData: TestRightCalculationData private lateinit var calculationData: TestRightCalculationData
/* (For exp sample) Contains pixel no. -> Intensity of light falling on that pixel */ /* (For exp sample) Contains pixel no. -> Intensity of light falling on that pixel */
@@ -79,8 +90,7 @@ class TestRightViewModel(
// "Error 201: In processing the data from device" // "Error 201: In processing the data from device"
errorTriggered.postValue( errorTriggered.postValue(
ErrorMessage( ErrorMessage(
"Error 201: In processing the data from device", "Error 201: In processing the data from device", Constants.ERROR_NORMAL
Constants.ERROR_NORMAL
) )
) )
} }
@@ -89,8 +99,7 @@ class TestRightViewModel(
// "Error 202: Unable to fetch data from device." // "Error 202: Unable to fetch data from device."
errorTriggered.postValue( errorTriggered.postValue(
ErrorMessage( ErrorMessage(
"Error 202: Unable to fetch data from device.", "Error 202: Unable to fetch data from device.", Constants.ERROR_NORMAL
Constants.ERROR_NORMAL
) )
) )
} }
@@ -103,13 +112,9 @@ class TestRightViewModel(
if (DataHolder.deviceConstant != null) { if (DataHolder.deviceConstant != null) {
for (x in 1..Constants.TEST_RIGHT_TOTAL_PIXEL) { for (x in 1..Constants.TEST_RIGHT_TOTAL_PIXEL) {
// val index = x - 1 // val index = x - 1
val wavelength: Double = val wavelength: Double = (DataHolder.deviceConstant!!.a.toDouble() * (x.toDouble()
(DataHolder.deviceConstant!!.a.toDouble() * (x.toDouble() .pow((3).toDouble()))) + (DataHolder.deviceConstant!!.b.toDouble() * (x.toDouble()
.pow((3).toDouble()))) + .pow((2).toDouble()))) + (DataHolder.deviceConstant!!.c.toDouble() * x) + (DataHolder.deviceConstant!!.d.toDouble())
(DataHolder.deviceConstant!!.b.toDouble() * (x.toDouble()
.pow((2).toDouble()))) +
(DataHolder.deviceConstant!!.c.toDouble() * x) +
(DataHolder.deviceConstant!!.d.toDouble())
DataHolder.wavelengthToPixelArray.add(wavelength) DataHolder.wavelengthToPixelArray.add(wavelength)
} }
@@ -118,8 +123,7 @@ class TestRightViewModel(
// "Error 203: Unable to fetch data from device." // "Error 203: Unable to fetch data from device."
errorTriggered.postValue( errorTriggered.postValue(
ErrorMessage( ErrorMessage(
"Error 203: Unable to fetch data from device.", "Error 203: Unable to fetch data from device.", Constants.ERROR_NORMAL
Constants.ERROR_NORMAL
) )
) )
@@ -136,22 +140,17 @@ class TestRightViewModel(
val listOfString = fullString.split("\n") val listOfString = fullString.split("\n")
for (line in listOfString) { for (line in listOfString) {
if ("Buf" in line) { if ("Buf" in line) {/* Removing trailing spaces and "Buf" from the string then taking lhs & rhs of ':' */
/* Removing trailing spaces and "Buf" from the string then taking lhs & rhs of ':' */ val numbers = line.trim().substring(3).split(":")
val numbers = line.trim()
.substring(3).split(":")
if (numbers.size >= 2) { if (numbers.size >= 2) {
if (isReference) if (isReference) DataHolder.intensityReferenceArray.add(numbers[1].toDouble())
DataHolder.intensityReferenceArray.add(numbers[1].toDouble()) else intensitySampleArray.add(numbers[1].toDouble())
else
intensitySampleArray.add(numbers[1].toDouble())
} else { } else {
// "Error 204: Unable to fetch data from device." // "Error 204: Unable to fetch data from device."
errorTriggered.postValue( errorTriggered.postValue(
ErrorMessage( ErrorMessage(
"Error 204: Unable to fetch data from device.", "Error 204: Unable to fetch data from device.", Constants.ERROR_NORMAL
Constants.ERROR_NORMAL
) )
) )
@@ -265,7 +264,7 @@ class TestRightViewModel(
testDetails?.result = calculationData.result testDetails?.result = calculationData.result
testDetails?.resultRatio = calculationData.ratioValue testDetails?.resultRatio = calculationData.ratioValue
testDetails?.testStatus = Status.COMPLETED testDetails?.testStatus = true
} }
@@ -275,7 +274,7 @@ class TestRightViewModel(
SickleFindResultCaluculationWithMaxImpl() SickleFindResultCaluculationWithMaxImpl()
calculationData = resultCalculation.getResults(wavelengthToAbsorbance) calculationData = resultCalculation.getResults(wavelengthToAbsorbance)
testDetails?.result = calculationData.result testDetails?.result = calculationData.result
testDetails?.testStatus = Status.COMPLETED testDetails?.testStatus = true
} }
@@ -369,10 +368,7 @@ class TestRightViewModel(
if (DataHolder.isAppFolderCreated) { if (DataHolder.isAppFolderCreated) {
// SaveRawData().saveLogWithPatientData( // SaveRawData().saveLogWithPatientData(
saveRawData.saveLogWithPatientData( saveRawData.saveLogWithPatientData(
folderPath!!, folderPath!!, fileName, calculationData, testDetails
fileName,
calculationData,
testDetails
) )
} else { } else {
folderPath = MyUtils.createAppFolder(appContext) folderPath = MyUtils.createAppFolder(appContext)
@@ -381,10 +377,7 @@ class TestRightViewModel(
DataHolder.appFolderPath = folderPath DataHolder.appFolderPath = folderPath
// SaveRawData().saveLogWithPatientData( // SaveRawData().saveLogWithPatientData(
saveRawData.saveLogWithPatientData( saveRawData.saveLogWithPatientData(
folderPath, folderPath, fileName, calculationData, testDetails
fileName,
calculationData,
testDetails
) )
} else { } else {
// errorTriggered.postValue("Unable to save Log, Please try again") // errorTriggered.postValue("Unable to save Log, Please try again")
@@ -427,129 +420,112 @@ class TestRightViewModel(
} }
fun getCSVFileName(): String { fun getCSVFileName(): String {
val prefixCsv: String = if (DataHolder.selectedTestType == TestType.SICKLECERT) val prefixCsv: String =
"HPOSSC_${testDetails?.testID}" if (DataHolder.selectedTestType == TestType.SICKLECERT) "HPOSSC_${testDetails?._id}"
else else "HPOSSF_${testDetails?._id}"
"HPOSSF_${testDetails?.testID}"
val fileExtensionCsv = ".csv" val fileExtensionCsv = ".csv"
return prefixCsv + fileExtensionCsv return prefixCsv + fileExtensionCsv
} }
fun getDetailedCSVFileName(): String {
return "detailed_" + getCSVFileName()
}
fun getLogFileName(): String { fun getLogFileName(): String {
val prefixTxt = "log_${testDetails?.testID}" val prefixTxt = "log_${testDetails?._id}"
val fileExtensionTxt = ".txt" val fileExtensionTxt = ".txt"
return prefixTxt + fileExtensionTxt return prefixTxt + fileExtensionTxt
} }
fun addResultTestToDb() { private fun addResultTestToDb() {
testDetails?.location = DataHolder.location
testDetails?.testTime = Calendar.getInstance().time.toString()
viewModelScope.launch { viewModelScope.launch {
testDetails!!.uploadTime = Calendar.getInstance().time testDetails!!.uploadTime = Calendar.getInstance().time.toString()
repository.addTestToDatabase(testDetails) when (repository.addTestToDatabase(testDetails)) {
is Response.Success -> {
fireBaseUpload.postValue("Success")
}
else -> {}
}
} }
} }
fun addFilesToQueue(context: Context) { fun uploadResultToDatabase(context: Context, isOnline: Boolean) = viewModelScope.launch {
viewModelScope.launch { val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName()
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName() val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName()
val pendingId = getCSVFileName().split(".")[0] testDetails?.csvPath = csvFilePath
repository.addToPendingQueue( testDetails?.reportPath = logTxtFilePath
PendingUploads( if (isOnline) {
pendingId, val storageRef = FirebaseStorage.getInstance().reference
DataHolder.mobileUniqueId!!, val storageTestDetailsRef = storageRef.child("${testDetails?._id}/")
testDetails!!.patientID,
csvFilePath, try {
Calendar.getInstance().time val csvFileUri = Uri.fromFile(File(csvFilePath))
) val logTxtFileUri = Uri.fromFile(File(logTxtFilePath))
)
} val csvUploadTask =
viewModelScope.launch { storageTestDetailsRef.child(csvFileUri.lastPathSegment!!).putFile(csvFileUri)
val detailedCsvFilePath = MyUtils.getAppFolderPath(context) + getDetailedCSVFileName() .await()
val pendingId = getDetailedCSVFileName().split(".")[0] val logUploadTask = storageTestDetailsRef.child(logTxtFileUri.lastPathSegment!!)
repository.addToPendingQueue( .putFile(logTxtFileUri).await()
PendingUploads(
pendingId, val csvUri = csvUploadTask.storage.downloadUrl.await().toString()
DataHolder.mobileUniqueId!!, val logUri = logUploadTask.storage.downloadUrl.await().toString()
testDetails!!.patientID,
detailedCsvFilePath, testDetails?.csvPath = csvUri
Calendar.getInstance().time testDetails?.reportPath = logUri
)
) addResultTestToDb()
} } catch (exception: Exception) {
viewModelScope.launch { // Handle the exception appropriately (e.g., log the error, display an error message)
val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName() }
val pendingId = getLogFileName().split(".")[0] } else {
repository.addToPendingQueue( testDetails?.testTime = Calendar.getInstance().time.toString()
PendingUploads( userDao.insertAll(testDetails!!)
pendingId,
DataHolder.mobileUniqueId!!,
testDetails!!.patientID,
logTxtFilePath,
Calendar.getInstance().time
)
)
} }
} }
fun addFilesToCloud(context: Context) { fun bulkUploadResultToDatabase(userData: UserData) = viewModelScope.launch {
GlobalScope.launch(Dispatchers.IO) { val storageRef = FirebaseStorage.getInstance().reference
val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName() val storageTestDetailsRef = storageRef.child("${testDetails?._id}/")
val fileName = getCSVFileName().split(".")[0] try {
val response = repository.uploadFileToStorage(testDetails!!.patientID, csvFilePath) val csvFileUri = Uri.fromFile(File(userData.csvPath))
val logTxtFileUri = Uri.fromFile(File(userData.reportPath))
when (response) { val csvUploadTask =
storageTestDetailsRef.child(csvFileUri.lastPathSegment!!).putFile(csvFileUri)
.await()
val logUploadTask =
storageTestDetailsRef.child(logTxtFileUri.lastPathSegment!!).putFile(logTxtFileUri)
.await()
val csvUri = csvUploadTask.storage.downloadUrl.await().toString()
val logUri = logUploadTask.storage.downloadUrl.await().toString()
userData.csvPath = csvUri
userData.reportPath = logUri
bulkAddResultTestToDb(userData)
} catch (exception: Exception) {
// Handle the exception appropriately (e.g., log the error, display an error message)
}
}
private fun bulkAddResultTestToDb(userData: UserData) {
userData.location = DataHolder.location
viewModelScope.launch {
userData.uploadTime = Calendar.getInstance().time.toString()
when (repository.addTestToDatabase(userData)) {
is Response.Success -> { is Response.Success -> {
Log.d(TAG, "Uploaded $csvFilePath") fireBaseUpload.postValue("Success")
repository.removeFromPendingQueue(fileName)
}
is Response.Error -> {
Log.d(TAG, response.exception.toString())
} }
else -> {}
} }
} }
}
GlobalScope.launch(Dispatchers.IO) { fun deleteById(userId: String) = viewModelScope.launch {
val detailedCsvFilePath = userDao.deleteById(id = userId)
MyUtils.getAppFolderPath(context) + getDetailedCSVFileName()
val fileName = getDetailedCSVFileName().split(".")[0]
val response =
repository.uploadFileToStorage(testDetails!!.patientID, detailedCsvFilePath)
when (response) {
is Response.Success -> {
Log.d(TAG, "Uploaded $detailedCsvFilePath")
repository.removeFromPendingQueue(fileName)
}
is Response.Error -> {
Log.d(TAG, response.exception.toString())
}
}
}
GlobalScope.launch(Dispatchers.IO) {
val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName()
val fileName = getLogFileName().split(".")[0]
val response =
repository.uploadFileToStorage(testDetails!!.patientID, logTxtFilePath)
when (response) {
is Response.Success -> {
Log.d(TAG, "Uploaded $logTxtFilePath")
repository.removeFromPendingQueue(fileName)
}
is Response.Error -> {
Log.d(TAG, response.exception.toString())
}
}
}
} }

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.testRight package com.example.hpostesting.presentation.testRight
import android.app.Service import android.app.Service
import android.content.Intent import android.content.Intent
@@ -6,10 +6,9 @@ import android.hardware.usb.UsbDeviceConnection
import android.os.Binder import android.os.Binder
import android.os.IBinder import android.os.IBinder
import android.util.Log import android.util.Log
import com.example.hpos.data.DataHolder import com.example.hpostesting.data.constant.Constants
import com.example.hpos.data.constant.Constants import com.example.hpostesting.data.constant.TestRightCommands
import com.example.hpos.data.constant.TestRightCommands import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpos.presentation.UsbServiceListener
import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialPort import com.hoho.android.usbserial.driver.UsbSerialPort
import com.hoho.android.usbserial.util.SerialInputOutputManager import com.hoho.android.usbserial.util.SerialInputOutputManager

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.utils package com.example.hpostesting.presentation.utils
interface MyDialogListener { interface MyDialogListener {
fun onClickNegativeButton() fun onClickNegativeButton()

View File

@@ -1,4 +1,4 @@
package com.example.hpos.presentation.utils package com.example.hpostesting.presentation.utils
import android.content.Context import android.content.Context
import android.widget.Toast import android.widget.Toast

View File

@@ -1,4 +1,4 @@
package com.example.hpos package com.example.hpostesting
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date

View File

@@ -1,12 +1,11 @@
package com.example.hpos.util package com.example.hpostesting.util
import android.content.Context import android.content.Context
import android.os.Environment import android.os.Environment
import com.example.hpos.R import com.example.hpostesting.data.model.patient.PatientDetails
import com.example.hpos.data.model.patient.PatientDetails import `in`.sminnovations.hpostesting.R
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.net.InetAddress
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale

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

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

View File

@@ -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&amp;weight=700"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>

View File

@@ -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&amp;weight=500"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>

View File

@@ -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&amp;weight=600"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>

View File

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

View File

@@ -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&amp;weight=500"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>

View File

@@ -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&amp;weight=600"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

@@ -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&amp;weight=500"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>

View File

@@ -30,7 +30,7 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/my_toolbar" /> app:layout_constraintTop_toBottomOf="@id/my_toolbar" />
<com.google.android.material.card.MaterialCardView <androidx.cardview.widget.CardView
android:id="@+id/cv_item1" android:id="@+id/cv_item1"
android:layout_width="128dp" android:layout_width="128dp"
android:layout_height="128dp" android:layout_height="128dp"
@@ -70,9 +70,9 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView> </androidx.cardview.widget.CardView>
<com.google.android.material.card.MaterialCardView <androidx.cardview.widget.CardView
android:id="@+id/cv_item2" android:id="@+id/cv_item2"
android:layout_width="128dp" android:layout_width="128dp"
android:layout_height="128dp" android:layout_height="128dp"
@@ -113,9 +113,9 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView> </androidx.cardview.widget.CardView>
<com.google.android.material.card.MaterialCardView <androidx.cardview.widget.CardView
android:id="@+id/cv_item3" android:id="@+id/cv_item3"
android:layout_width="128dp" android:layout_width="128dp"
android:layout_height="128dp" android:layout_height="128dp"
@@ -155,10 +155,10 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView> </androidx.cardview.widget.CardView>
<com.google.android.material.card.MaterialCardView <androidx.cardview.widget.CardView
android:id="@+id/cv_item4" android:id="@+id/cv_item4"
android:layout_width="128dp" android:layout_width="128dp"
android:layout_height="128dp" android:layout_height="128dp"
@@ -199,7 +199,7 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView> </androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,23 +1,90 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/internetNotAvailableCL"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:visibility="gone"
android:padding="24dp">
<TextView
android:id="@+id/tv_title_no_internet"
style="@style/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/internet_not_available_please_enter_the_user_id_manually"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_name"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginHorizontal="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_title_no_internet">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/userId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLength="18"
android:inputType="textCapCharacters"
android:hint="@string/user_id" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/submit"
app:cornerRadius="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_name" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/internetAvailableCL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
android:padding="24dp">
<TextView <TextView
android:id="@+id/tv_title" android:id="@+id/tv_title"
style="@style/title1" style="@style/title1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp" android:text="@string/user_list"
android:layout_marginTop="16dp" app:layout_constraintEnd_toEndOf="parent"
android:text="@string/list_of_patients"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/uploadData"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/upload_data"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/tv_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/tv_title" />
<TextView <TextView
android:id="@+id/tv_not_available" android:id="@+id/tv_not_available"
style="@style/title1_1" style="@style/title1_1"
@@ -32,43 +99,82 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" /> app:layout_constraintTop_toBottomOf="@id/tv_title" />
<androidx.recyclerview.widget.RecyclerView <androidx.cardview.widget.CardView
android:id="@+id/recycler_view" android:id="@+id/cardView4"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="0dp"
app:layout_constraintTop_toBottomOf="@+id/tv_title"
tools:layout_editor_absoluteX="24dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.SearchView
android:id="@+id/search_product"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/edit_text_background"
android:inputType="text"
app:iconifiedByDefault="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<requestFocus />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="0dp"
android:orientation="horizontal"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardView4">
<RadioButton
android:id="@+id/userIdRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/user_id" />
<RadioButton
android:id="@+id/abhaIdRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/abha_id"
app:layout_constraintTop_toBottomOf="@id/userIdRadioButton" />
<RadioButton
android:id="@+id/aadharIdRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/aadhar_id"
app:layout_constraintTop_toBottomOf="@id/abhaIdRadioButton" />
</RadioGroup>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_order"
android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_margin="16dp" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:scrollbars="vertical"
app:layout_constraintBottom_toTopOf="@id/btn_add"
app:layout_constraintTop_toBottomOf="@id/tv_title"
tools:listitem="@layout/table_item" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:drawableLeft="@drawable/baseline_add_24"
android:text="@string/add"
android:textColor="@color/white"
app:cornerRadius="16dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
<com.google.android.material.button.MaterialButton app:layout_constraintTop_toBottomOf="@+id/radioGroup"
android:id="@+id/btn_test" tools:listitem="@layout/user_item_view"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:drawableLeft="@drawable/test_tube"
android:text="@string/test"
android:textColor="@color/white"
app:cornerRadius="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</layout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -253,7 +253,7 @@
app:layout_constraintTop_toBottomOf="@id/cv_sample_details" /> app:layout_constraintTop_toBottomOf="@id/cv_sample_details" />
<TextView <TextView
style="@style/title3" style="@style/title2"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/home" android:text="@string/home"
@@ -277,7 +277,7 @@
app:layout_constraintTop_toBottomOf="@id/cv_sample_details" /> app:layout_constraintTop_toBottomOf="@id/cv_sample_details" />
<TextView <TextView
style="@style/title3" style="@style/title2"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/new_test" android:text="@string/new_test"
@@ -289,8 +289,9 @@
<ProgressBar <ProgressBar
android:id="@+id/progressBar" android:id="@+id/progressBar"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:background="@color/gray"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:indeterminate="true" android:indeterminate="true"
android:indeterminateDrawable="@drawable/progressbar_drawable" android:indeterminateDrawable="@drawable/progressbar_drawable"

View 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