diff --git a/app/build.gradle b/app/build.gradle index 6ab91af..7f7f01a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,15 +2,19 @@ plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'com.google.firebase.appdistribution' + id 'dagger.hilt.android.plugin' id 'com.google.gms.google-services' + id 'androidx.navigation.safeargs.kotlin' + id 'kotlin-kapt' } //apply plugin: 'kotlin-android' android { compileSdk 33 + namespace 'in.sminnovations.hpostesting' defaultConfig { - applicationId "com.example.hpos" + applicationId "in.sminnovations.hpostesting" minSdk 21 targetSdk 33 versionCode 2 @@ -26,11 +30,11 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '17' } dataBinding { enabled = true @@ -48,19 +52,21 @@ android { dependencies { - implementation 'androidx.core:core-ktx:1.9.0' - implementation 'androidx.appcompat:appcompat:1.5.1' - implementation 'com.google.android.material:material:1.7.0' + implementation 'androidx.core:core-ktx:1.10.1' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.9.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1' - implementation 'androidx.navigation:navigation-fragment-ktx:2.5.2' - implementation 'androidx.navigation:navigation-ui-ktx:2.5.2' - // Firebase - implementation 'com.google.firebase:firebase-firestore-ktx:24.4.1' - implementation 'com.google.firebase:firebase-storage-ktx:20.1.0' + //firebase + implementation platform('com.google.firebase:firebase-bom:32.1.0') + implementation 'com.google.firebase:firebase-firestore-ktx' + implementation 'com.google.firebase:firebase-auth-ktx' + implementation 'com.google.firebase:firebase-storage-ktx' + implementation 'com.firebaseui:firebase-ui-firestore:8.0.2' + implementation 'com.google.android.gms:play-services-auth:20.5.0' implementation 'com.google.android.gms:play-services-location:21.0.1' -// implementation 'androidx.core:core-ktx:+' + implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1' // Testing testImplementation 'junit:junit:4.13.2' @@ -68,11 +74,11 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1" implementation 'com.opencsv:opencsv:4.6' implementation 'com.github.mik3y:usb-serial-for-android:3.4.6' - implementation "androidx.fragment:fragment-ktx:1.5.5" + implementation "androidx.fragment:fragment-ktx:1.6.0" // CSV read, write implementation 'com.opencsv:opencsv:4.6' @@ -83,7 +89,26 @@ dependencies { // Google ML Kit usign play services implementation 'com.google.android.gms:play-services-code-scanner:16.0.0' -} -//repositories { -// mavenCentral() -//} \ No newline at end of file + //Room + implementation "androidx.room:room-ktx:2.6.0-alpha01" + implementation "androidx.room:room-runtime:2.6.0-alpha01" + kapt ("androidx.room:room-compiler:2.6.0-alpha01") + + //image + implementation 'com.github.bumptech.glide:glide:4.13.2' + annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' + + // Navigation Component + implementation "androidx.navigation:navigation-fragment-ktx:2.7.0-beta01" + implementation "androidx.navigation:navigation-ui-ktx:2.7.0-beta01" + + //Dagger - Hilt + implementation "com.google.dagger:hilt-android:2.46" + kapt "com.google.dagger:hilt-android-compiler:2.46" + kapt "androidx.hilt:hilt-compiler:1.0.0" + + // Retrofit + GSON + implementation "com.squareup.retrofit2:retrofit:2.9.0" + implementation "com.squareup.retrofit2:converter-gson:2.9.0" + +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/hpos/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/hpostesting/ExampleInstrumentedTest.kt similarity index 95% rename from app/src/androidTest/java/com/example/hpos/ExampleInstrumentedTest.kt rename to app/src/androidTest/java/com/example/hpostesting/ExampleInstrumentedTest.kt index d0e5ba2..0059e7a 100644 --- a/app/src/androidTest/java/com/example/hpos/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/com/example/hpostesting/ExampleInstrumentedTest.kt @@ -1,4 +1,4 @@ -package com.example.hpos +package com.example.hpostesting import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c5cbae7..11878c1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> @@ -16,7 +15,7 @@ + android:exported="false" + android:theme="@style/Theme.HPOS.NoActionBar"/> @@ -54,12 +54,13 @@ + android:windowSoftInputMode="adjustPan" + android:theme="@style/Theme.HPOS.NoActionBar"> @@ -71,9 +72,10 @@ + android:screenOrientation="portrait" + android:theme="@style/AppTheme.NoActionBar"> @@ -88,9 +90,6 @@ android:stateNotNeeded="true" tools:replace="android:screenOrientation" /> - \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/MyApplication.kt b/app/src/main/java/com/example/hpos/MyApplication.kt deleted file mode 100644 index 62fc52f..0000000 --- a/app/src/main/java/com/example/hpos/MyApplication.kt +++ /dev/null @@ -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 diff --git a/app/src/main/java/com/example/hpos/data/model/AadharCard.java b/app/src/main/java/com/example/hpos/data/model/AadharCard.java deleted file mode 100644 index c95cef8..0000000 --- a/app/src/main/java/com/example/hpos/data/model/AadharCard.java +++ /dev/null @@ -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; - } -} diff --git a/app/src/main/java/com/example/hpos/data/repository/DatabaseRepository.kt b/app/src/main/java/com/example/hpos/data/repository/DatabaseRepository.kt deleted file mode 100644 index d8d328d..0000000 --- a/app/src/main/java/com/example/hpos/data/repository/DatabaseRepository.kt +++ /dev/null @@ -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 { - 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> { - return try { - val querySnapshot = db.collection("patientData").get().await() - - val patientList = mutableListOf() - 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 { - 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 { - val testList = mutableListOf() - 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 { - 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 { - 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 { - val pendingList = mutableListOf() - 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 { - return try { - db.collection("pendingUploads") - .document(fileName) - .delete() - .await() - - Response.Success(true) - } catch (e: Exception) { - e.printStackTrace() - Response.Error(e) - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/domain/AadhaarScanner/QrCodeException.java b/app/src/main/java/com/example/hpos/domain/AadhaarScanner/QrCodeException.java deleted file mode 100644 index 0e3fcd6..0000000 --- a/app/src/main/java/com/example/hpos/domain/AadhaarScanner/QrCodeException.java +++ /dev/null @@ -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); - } -} diff --git a/app/src/main/java/com/example/hpos/domain/AadhaarScanner/SecureQrCode.java b/app/src/main/java/com/example/hpos/domain/AadhaarScanner/SecureQrCode.java deleted file mode 100644 index 0a2b977..0000000 --- a/app/src/main/java/com/example/hpos/domain/AadhaarScanner/SecureQrCode.java +++ /dev/null @@ -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 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 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 separateData(byte[] source) { - List 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 encodedData) throws QrCodeException{ - Iterator i = encodedData.iterator(); - decodedData = new ArrayList(); - 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); - } -} diff --git a/app/src/main/java/com/example/hpos/presentation/MainActivity.kt b/app/src/main/java/com/example/hpos/presentation/MainActivity.kt deleted file mode 100644 index e13599f..0000000 --- a/app/src/main/java/com/example/hpos/presentation/MainActivity.kt +++ /dev/null @@ -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 - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/RVAdapter.kt b/app/src/main/java/com/example/hpos/presentation/RVAdapter.kt deleted file mode 100644 index a207742..0000000 --- a/app/src/main/java/com/example/hpos/presentation/RVAdapter.kt +++ /dev/null @@ -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() { - -// private lateinit var binding: TableItemBinding - private val dataset = ArrayList() - - 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) { - 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) { -// dataset.clear() -// dataset.addAll(newDataSet) -// notifyDataSetChanged() -// } - -} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/SplashActivity.kt b/app/src/main/java/com/example/hpos/presentation/SplashActivity.kt deleted file mode 100644 index a77474d..0000000 --- a/app/src/main/java/com/example/hpos/presentation/SplashActivity.kt +++ /dev/null @@ -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 - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/DashboardViewModel.kt b/app/src/main/java/com/example/hpos/presentation/dashboard/DashboardViewModel.kt deleted file mode 100644 index 055e1a6..0000000 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/DashboardViewModel.kt +++ /dev/null @@ -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>() -// val allTestDetails = MutableLiveData>>() - val allTestDetails = MutableLiveData>() - - 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) - } - } - - -} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/HomeFragment.kt b/app/src/main/java/com/example/hpos/presentation/dashboard/HomeFragment.kt deleted file mode 100644 index 6eb3bed..0000000 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/HomeFragment.kt +++ /dev/null @@ -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 - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/register/RegisterOneCreateAbha.kt b/app/src/main/java/com/example/hpos/presentation/dashboard/register/RegisterOneCreateAbha.kt deleted file mode 100644 index 46c2d70..0000000 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/register/RegisterOneCreateAbha.kt +++ /dev/null @@ -1,69 +0,0 @@ -package com.example.hpos.presentation.dashboard.register - -import android.content.ActivityNotFoundException -import android.content.Intent -import android.net.Uri -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.fragment.app.Fragment -import androidx.fragment.app.activityViewModels -import androidx.navigation.fragment.findNavController -import com.example.hpos.R -import com.example.hpos.data.constant.Constants -import com.example.hpos.databinding.FragmentRegisterOneCreateAbhaBinding -import com.example.hpos.presentation.dashboard.DashboardViewModel - - -class RegisterOneCreateAbha : Fragment() { - - private val TAG = "RegisterOneCreateAbha" - private lateinit var binding: FragmentRegisterOneCreateAbhaBinding - private val viewModel: DashboardViewModel by activityViewModels() - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentRegisterOneCreateAbhaBinding.inflate(inflater, container, false) - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding.btnRedirect.setOnClickListener { - redirectApp() - } - binding.tvSkip.setOnClickListener { - // Taking to aadhaar page if ABHA is skipped - findNavController().navigate(R.id.action_registerOneCreateAbha_to_registerTwoAadhaarFragment) - } - } - - private fun redirectApp() { - val launchIntent: Intent? = requireActivity().packageManager - .getLaunchIntentForPackage(Constants.ABHA_APP_PACKAGE) - - if (launchIntent != null) { - startActivity(launchIntent) - } else { - try { - startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=${Constants.ABHA_APP_PACKAGE}"))) - } catch (e: ActivityNotFoundException) { - startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=${Constants.ABHA_APP_PACKAGE}"))) - } - } - } - -// private fun appInstalledOrNot(uri: String): Boolean { -// val pm: PackageManager = requireActivity().packageManager -// try { -// pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES) -// return true -// } catch (e: PackageManager.NameNotFoundException) { -// } -// return false -// } - -} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/register/RegisterOneScanAbhaFragment.kt b/app/src/main/java/com/example/hpos/presentation/dashboard/register/RegisterOneScanAbhaFragment.kt deleted file mode 100644 index 33dbc5b..0000000 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/register/RegisterOneScanAbhaFragment.kt +++ /dev/null @@ -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() - } - } - - -} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/register/RegisterThreeEnterPatientDetails.kt b/app/src/main/java/com/example/hpos/presentation/dashboard/register/RegisterThreeEnterPatientDetails.kt deleted file mode 100644 index 41d9fbc..0000000 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/register/RegisterThreeEnterPatientDetails.kt +++ /dev/null @@ -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() - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/register/RegisterTwoAadhaarFragment.kt b/app/src/main/java/com/example/hpos/presentation/dashboard/register/RegisterTwoAadhaarFragment.kt deleted file mode 100644 index 60e9ace..0000000 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/register/RegisterTwoAadhaarFragment.kt +++ /dev/null @@ -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) - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/util/MyViewModelFactory.kt b/app/src/main/java/com/example/hpos/util/MyViewModelFactory.kt deleted file mode 100644 index 5cdcc36..0000000 --- a/app/src/main/java/com/example/hpos/util/MyViewModelFactory.kt +++ /dev/null @@ -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 create(modelClass: Class): 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"); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/HPOSTestingApplication.kt b/app/src/main/java/com/example/hpostesting/HPOSTestingApplication.kt new file mode 100644 index 0000000..1cee7e6 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/HPOSTestingApplication.kt @@ -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) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/data/DataHolder.kt b/app/src/main/java/com/example/hpostesting/data/DataHolder.kt similarity index 71% rename from app/src/main/java/com/example/hpos/data/DataHolder.kt rename to app/src/main/java/com/example/hpostesting/data/DataHolder.kt index 7b9305a..1ff8020 100644 --- a/app/src/main/java/com/example/hpos/data/DataHolder.kt +++ b/app/src/main/java/com/example/hpostesting/data/DataHolder.kt @@ -1,9 +1,9 @@ -package com.example.hpos.data +package com.example.hpostesting.data import androidx.lifecycle.MutableLiveData -import com.example.hpos.data.model.test.TestDetails -import com.example.hpos.data.model.test.TestRightDeviceConstants -import com.example.hpos.data.model.test.TestType +import com.example.hpostesting.data.model.patient.UserData +import com.example.hpostesting.data.model.test.TestRightDeviceConstants +import com.example.hpostesting.data.model.test.TestType object DataHolder { @@ -28,7 +28,9 @@ object DataHolder { /* (For reference/baseline) Contains pixel no. -> Intensity of light falling on that pixel */ val intensityReferenceArray = ArrayList() - var selectedTest: TestDetails? = null + var selectedTest: UserData? = null + + var location: UserData.Location? = null var testExp: Boolean = true } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/data/FileUploader.kt b/app/src/main/java/com/example/hpostesting/data/FileUploader.kt similarity index 86% rename from app/src/main/java/com/example/hpos/data/FileUploader.kt rename to app/src/main/java/com/example/hpostesting/data/FileUploader.kt index feec4a5..e76d929 100644 --- a/app/src/main/java/com/example/hpos/data/FileUploader.kt +++ b/app/src/main/java/com/example/hpostesting/data/FileUploader.kt @@ -1,12 +1,11 @@ -package com.example.hpos.data +package com.example.hpostesting.data import android.util.Log -import com.example.hpos.data.model.Response -import com.example.hpos.data.repository.DatabaseRepository -import com.example.hpos.util.MyUtils +import com.example.hpostesting.data.model.Response +import com.example.hpostesting.data.repository.DatabaseRepository +import com.example.hpostesting.util.MyUtils import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch -import java.lang.Thread.sleep class FileUploader { diff --git a/app/src/main/java/com/example/hpostesting/data/InternetConnectionLiveData.kt b/app/src/main/java/com/example/hpostesting/data/InternetConnectionLiveData.kt new file mode 100644 index 0000000..b8b9031 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/data/InternetConnectionLiveData.kt @@ -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() { + + 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/data/PreferenceUtility.kt b/app/src/main/java/com/example/hpostesting/data/PreferenceUtility.kt similarity index 95% rename from app/src/main/java/com/example/hpos/data/PreferenceUtility.kt rename to app/src/main/java/com/example/hpostesting/data/PreferenceUtility.kt index e8786bf..43f74be 100644 --- a/app/src/main/java/com/example/hpos/data/PreferenceUtility.kt +++ b/app/src/main/java/com/example/hpostesting/data/PreferenceUtility.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data +package com.example.hpostesting.data import android.content.Context import android.content.SharedPreferences diff --git a/app/src/main/java/com/example/hpos/data/constant/Constants.kt b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt similarity index 94% rename from app/src/main/java/com/example/hpos/data/constant/Constants.kt rename to app/src/main/java/com/example/hpostesting/data/constant/Constants.kt index b2d993f..967eb05 100644 --- a/app/src/main/java/com/example/hpos/data/constant/Constants.kt +++ b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.constant +package com.example.hpostesting.data.constant object Constants { const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION" diff --git a/app/src/main/java/com/example/hpos/data/constant/TestRightCommands.kt b/app/src/main/java/com/example/hpostesting/data/constant/TestRightCommands.kt similarity index 84% rename from app/src/main/java/com/example/hpos/data/constant/TestRightCommands.kt rename to app/src/main/java/com/example/hpostesting/data/constant/TestRightCommands.kt index 8a92eca..ac5ec1f 100644 --- a/app/src/main/java/com/example/hpos/data/constant/TestRightCommands.kt +++ b/app/src/main/java/com/example/hpostesting/data/constant/TestRightCommands.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.constant +package com.example.hpostesting.data.constant enum class TestRightCommands(val command: String) { led2Set50("led2 50\r"), diff --git a/app/src/main/java/com/example/hpostesting/data/dao/Converters.kt b/app/src/main/java/com/example/hpostesting/data/dao/Converters.kt new file mode 100644 index 0000000..db1c43e --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/data/dao/Converters.kt @@ -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 + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt b/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt new file mode 100644 index 0000000..f8edb9d --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt @@ -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 +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/dao/UserDao.kt b/app/src/main/java/com/example/hpostesting/data/dao/UserDao.kt new file mode 100644 index 0000000..d0eb121 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/data/dao/UserDao.kt @@ -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> + + @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) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/data/datasource/LocalFileDataSource.kt b/app/src/main/java/com/example/hpostesting/data/datasource/LocalFileDataSource.kt similarity index 91% rename from app/src/main/java/com/example/hpos/data/datasource/LocalFileDataSource.kt rename to app/src/main/java/com/example/hpostesting/data/datasource/LocalFileDataSource.kt index acc0bcc..39ccd8c 100644 --- a/app/src/main/java/com/example/hpos/data/datasource/LocalFileDataSource.kt +++ b/app/src/main/java/com/example/hpostesting/data/datasource/LocalFileDataSource.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.datasource +package com.example.hpostesting.data.datasource import com.opencsv.CSVWriter import java.io.File diff --git a/app/src/main/java/com/example/hpostesting/data/model/AadharCard.kt b/app/src/main/java/com/example/hpostesting/data/model/AadharCard.kt new file mode 100644 index 0000000..add68ef --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/data/model/AadharCard.kt @@ -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 = "" + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/data/model/CalculationVariableForTest.kt b/app/src/main/java/com/example/hpostesting/data/model/CalculationVariableForTest.kt similarity index 84% rename from app/src/main/java/com/example/hpos/data/model/CalculationVariableForTest.kt rename to app/src/main/java/com/example/hpostesting/data/model/CalculationVariableForTest.kt index c15cc2b..321ba48 100644 --- a/app/src/main/java/com/example/hpos/data/model/CalculationVariableForTest.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/CalculationVariableForTest.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.model +package com.example.hpostesting.data.model data class CalculationVariableForTest( var pixelNo: Int, diff --git a/app/src/main/java/com/example/hpos/data/model/ErrorMessage.kt b/app/src/main/java/com/example/hpostesting/data/model/ErrorMessage.kt similarity index 61% rename from app/src/main/java/com/example/hpos/data/model/ErrorMessage.kt rename to app/src/main/java/com/example/hpostesting/data/model/ErrorMessage.kt index 2eac286..9adb2b5 100644 --- a/app/src/main/java/com/example/hpos/data/model/ErrorMessage.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/ErrorMessage.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.model +package com.example.hpostesting.data.model data class ErrorMessage ( val message: String, diff --git a/app/src/main/java/com/example/hpos/data/model/Location.kt b/app/src/main/java/com/example/hpostesting/data/model/Location.kt similarity index 72% rename from app/src/main/java/com/example/hpos/data/model/Location.kt rename to app/src/main/java/com/example/hpostesting/data/model/Location.kt index 9226af9..091cffa 100644 --- a/app/src/main/java/com/example/hpos/data/model/Location.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/Location.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.model +package com.example.hpostesting.data.model data class Location( var latitude: Double?, diff --git a/app/src/main/java/com/example/hpos/data/model/PatientData.kt b/app/src/main/java/com/example/hpostesting/data/model/PatientData.kt similarity index 53% rename from app/src/main/java/com/example/hpos/data/model/PatientData.kt rename to app/src/main/java/com/example/hpostesting/data/model/PatientData.kt index 7ef43d5..0c4f160 100644 --- a/app/src/main/java/com/example/hpos/data/model/PatientData.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/PatientData.kt @@ -1,6 +1,6 @@ -package com.example.hpos.data.model +package com.example.hpostesting.data.model -import com.example.hpos.data.model.test.TestRightResultType +import com.example.hpostesting.data.model.test.TestRightResultType data class PatientData( val name: String, diff --git a/app/src/main/java/com/example/hpos/data/model/PendingUploads.kt b/app/src/main/java/com/example/hpostesting/data/model/PendingUploads.kt similarity index 87% rename from app/src/main/java/com/example/hpos/data/model/PendingUploads.kt rename to app/src/main/java/com/example/hpostesting/data/model/PendingUploads.kt index c5096b7..9bd748c 100644 --- a/app/src/main/java/com/example/hpos/data/model/PendingUploads.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/PendingUploads.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.model +package com.example.hpostesting.data.model import java.util.Calendar import java.util.Date diff --git a/app/src/main/java/com/example/hpos/data/model/Response.kt b/app/src/main/java/com/example/hpostesting/data/model/Response.kt similarity index 82% rename from app/src/main/java/com/example/hpos/data/model/Response.kt rename to app/src/main/java/com/example/hpostesting/data/model/Response.kt index 8c5886d..6cadb5f 100644 --- a/app/src/main/java/com/example/hpos/data/model/Response.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/Response.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.model +package com.example.hpostesting.data.model sealed class Response { data class Success(val data: T) : Response() diff --git a/app/src/main/java/com/example/hpos/data/model/patient/PatientData.kt b/app/src/main/java/com/example/hpostesting/data/model/patient/PatientData.kt similarity index 96% rename from app/src/main/java/com/example/hpos/data/model/patient/PatientData.kt rename to app/src/main/java/com/example/hpostesting/data/model/patient/PatientData.kt index cb735de..d9347b7 100644 --- a/app/src/main/java/com/example/hpos/data/model/patient/PatientData.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/patient/PatientData.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.model.patient +package com.example.hpostesting.data.model.patient import java.util.Date diff --git a/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt b/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt new file mode 100644 index 0000000..6ec7742 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/data/model/patient/UserData.kt @@ -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 + ) +} diff --git a/app/src/main/java/com/example/hpos/data/model/test/TestDetails.kt b/app/src/main/java/com/example/hpostesting/data/model/test/TestDetails.kt similarity index 89% rename from app/src/main/java/com/example/hpos/data/model/test/TestDetails.kt rename to app/src/main/java/com/example/hpostesting/data/model/test/TestDetails.kt index 9c4ee9d..5f0260b 100644 --- a/app/src/main/java/com/example/hpos/data/model/test/TestDetails.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/test/TestDetails.kt @@ -1,6 +1,6 @@ -package com.example.hpos.data.model.test +package com.example.hpostesting.data.model.test -import com.example.hpos.data.model.Location +import com.example.hpostesting.data.model.Location import java.util.Date data class TestDetails( diff --git a/app/src/main/java/com/example/hpos/data/model/test/TestInfo.kt b/app/src/main/java/com/example/hpostesting/data/model/test/TestInfo.kt similarity index 81% rename from app/src/main/java/com/example/hpos/data/model/test/TestInfo.kt rename to app/src/main/java/com/example/hpostesting/data/model/test/TestInfo.kt index 27b0ae6..8a5ff3b 100644 --- a/app/src/main/java/com/example/hpos/data/model/test/TestInfo.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/test/TestInfo.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.model.test +package com.example.hpostesting.data.model.test data class TestInfo( val value: String, diff --git a/app/src/main/java/com/example/hpos/data/model/test/TestRightCalculationData.kt b/app/src/main/java/com/example/hpostesting/data/model/test/TestRightCalculationData.kt similarity index 89% rename from app/src/main/java/com/example/hpos/data/model/test/TestRightCalculationData.kt rename to app/src/main/java/com/example/hpostesting/data/model/test/TestRightCalculationData.kt index 78fef73..cb88749 100644 --- a/app/src/main/java/com/example/hpos/data/model/test/TestRightCalculationData.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/test/TestRightCalculationData.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.model.test +package com.example.hpostesting.data.model.test data class TestRightCalculationData( var absorbanceOne: Double?, diff --git a/app/src/main/java/com/example/hpos/data/model/test/TestRightDeviceConstants.kt b/app/src/main/java/com/example/hpostesting/data/model/test/TestRightDeviceConstants.kt similarity index 70% rename from app/src/main/java/com/example/hpos/data/model/test/TestRightDeviceConstants.kt rename to app/src/main/java/com/example/hpostesting/data/model/test/TestRightDeviceConstants.kt index 0539f37..011e4bb 100644 --- a/app/src/main/java/com/example/hpos/data/model/test/TestRightDeviceConstants.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/test/TestRightDeviceConstants.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.model.test +package com.example.hpostesting.data.model.test data class TestRightDeviceConstants( var a: String, diff --git a/app/src/main/java/com/example/hpos/data/model/test/TestRightResultType.kt b/app/src/main/java/com/example/hpostesting/data/model/test/TestRightResultType.kt similarity index 75% rename from app/src/main/java/com/example/hpos/data/model/test/TestRightResultType.kt rename to app/src/main/java/com/example/hpostesting/data/model/test/TestRightResultType.kt index e88ff92..345e880 100644 --- a/app/src/main/java/com/example/hpos/data/model/test/TestRightResultType.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/test/TestRightResultType.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.model.test +package com.example.hpostesting.data.model.test enum class TestRightResultType { NORMAL, diff --git a/app/src/main/java/com/example/hpos/data/model/test/TestType.kt b/app/src/main/java/com/example/hpostesting/data/model/test/TestType.kt similarity index 53% rename from app/src/main/java/com/example/hpos/data/model/test/TestType.kt rename to app/src/main/java/com/example/hpostesting/data/model/test/TestType.kt index c3dcf42..c3f1902 100644 --- a/app/src/main/java/com/example/hpos/data/model/test/TestType.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/test/TestType.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.model.test +package com.example.hpostesting.data.model.test enum class TestType { SICKLECERT, diff --git a/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt b/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt new file mode 100644 index 0000000..06277c4 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/data/repository/DatabaseRepository.kt @@ -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 { + 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 { + 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 { + 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 { + val pendingList = mutableListOf() + 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 { + return try { + db.collection("pendingUploads").document(fileName).delete().await() + + Response.Success(true) + } catch (e: Exception) { + e.printStackTrace() + Response.Error(e) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/data/repository/LocalFileRepository.kt b/app/src/main/java/com/example/hpostesting/data/repository/LocalFileRepository.kt similarity index 75% rename from app/src/main/java/com/example/hpos/data/repository/LocalFileRepository.kt rename to app/src/main/java/com/example/hpostesting/data/repository/LocalFileRepository.kt index 9eae08b..6290bf0 100644 --- a/app/src/main/java/com/example/hpos/data/repository/LocalFileRepository.kt +++ b/app/src/main/java/com/example/hpostesting/data/repository/LocalFileRepository.kt @@ -1,6 +1,6 @@ -package com.example.hpos.data.repository +package com.example.hpostesting.data.repository -import com.example.hpos.data.datasource.LocalFileDataSource +import com.example.hpostesting.data.datasource.LocalFileDataSource class LocalFileRepository(private val localFileDataSource: LocalFileDataSource) { fun saveCsvToDisk(filepath: String, contents: ArrayList>) = diff --git a/app/src/main/java/com/example/hpos/data/repository/Repository.kt b/app/src/main/java/com/example/hpostesting/data/repository/Repository.kt similarity index 61% rename from app/src/main/java/com/example/hpos/data/repository/Repository.kt rename to app/src/main/java/com/example/hpostesting/data/repository/Repository.kt index ab985b6..3419ceb 100644 --- a/app/src/main/java/com/example/hpos/data/repository/Repository.kt +++ b/app/src/main/java/com/example/hpostesting/data/repository/Repository.kt @@ -1,4 +1,4 @@ -package com.example.hpos.data.repository +package com.example.hpostesting.data.repository interface Repository { // suspend fun addToDatabase(data: PatientDetails) diff --git a/app/src/main/java/com/example/hpos/domain/ResultCalculationWithAvgImpl.kt b/app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithAvgImpl.kt similarity index 93% rename from app/src/main/java/com/example/hpos/domain/ResultCalculationWithAvgImpl.kt rename to app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithAvgImpl.kt index 870ac95..05c1e8d 100644 --- a/app/src/main/java/com/example/hpos/domain/ResultCalculationWithAvgImpl.kt +++ b/app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithAvgImpl.kt @@ -1,8 +1,8 @@ -package com.example.hpos.domain +package com.example.hpostesting.domain -import com.example.hpos.data.constant.Constants -import com.example.hpos.data.model.test.TestRightCalculationData -import com.example.hpos.data.model.test.TestRightResultType +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.model.test.TestRightCalculationData +import com.example.hpostesting.data.model.test.TestRightResultType class ResultCalculationWithAvgImpl : TestRightResultCalculation { diff --git a/app/src/main/java/com/example/hpos/domain/ResultCalculationWithFirstImpl.kt b/app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithFirstImpl.kt similarity index 95% rename from app/src/main/java/com/example/hpos/domain/ResultCalculationWithFirstImpl.kt rename to app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithFirstImpl.kt index a3e790d..8888379 100644 --- a/app/src/main/java/com/example/hpos/domain/ResultCalculationWithFirstImpl.kt +++ b/app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithFirstImpl.kt @@ -1,8 +1,8 @@ -package com.example.hpos.domain +package com.example.hpostesting.domain import android.util.Log -import com.example.hpos.data.constant.Constants -import com.example.hpos.data.model.test.TestRightResultType +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.model.test.TestRightResultType import kotlin.math.log10 class ResultCalculationWithFirstImpl { diff --git a/app/src/main/java/com/example/hpos/domain/ResultCalculationWithMaxImpl.kt b/app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithMaxImpl.kt similarity index 94% rename from app/src/main/java/com/example/hpos/domain/ResultCalculationWithMaxImpl.kt rename to app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithMaxImpl.kt index c6362be..687c483 100644 --- a/app/src/main/java/com/example/hpos/domain/ResultCalculationWithMaxImpl.kt +++ b/app/src/main/java/com/example/hpostesting/domain/ResultCalculationWithMaxImpl.kt @@ -1,8 +1,8 @@ -package com.example.hpos.domain +package com.example.hpostesting.domain -import com.example.hpos.data.constant.Constants -import com.example.hpos.data.model.test.TestRightCalculationData -import com.example.hpos.data.model.test.TestRightResultType +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.model.test.TestRightCalculationData +import com.example.hpostesting.data.model.test.TestRightResultType class ResultCalculationWithMaxImpl : TestRightResultCalculation { diff --git a/app/src/main/java/com/example/hpos/domain/SaveRawData.kt b/app/src/main/java/com/example/hpostesting/domain/SaveRawData.kt similarity index 91% rename from app/src/main/java/com/example/hpos/domain/SaveRawData.kt rename to app/src/main/java/com/example/hpostesting/domain/SaveRawData.kt index 155420b..971dcc3 100644 --- a/app/src/main/java/com/example/hpos/domain/SaveRawData.kt +++ b/app/src/main/java/com/example/hpostesting/domain/SaveRawData.kt @@ -1,10 +1,10 @@ -package com.example.hpos.domain +package com.example.hpostesting.domain import android.util.Log -import com.example.hpos.data.repository.LocalFileRepository -import com.example.hpos.data.constant.Constants -import com.example.hpos.data.model.test.TestDetails -import com.example.hpos.data.model.test.TestRightCalculationData +import com.example.hpostesting.data.repository.LocalFileRepository +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.model.patient.UserData +import com.example.hpostesting.data.model.test.TestRightCalculationData import java.util.Collections.sort class SaveRawData(private val localFileRepository: LocalFileRepository) { @@ -98,7 +98,7 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) { folderPath: String, fileName: String, calculationData: TestRightCalculationData, - testDetails: TestDetails? + testDetails: UserData? ) { // val fileObj = File(folderPath, fileName) // val writer = FileWriter(fileObj) @@ -116,11 +116,11 @@ class SaveRawData(private val localFileRepository: LocalFileRepository) { private fun getLogStringFromObjWithPatientData( calculationData: TestRightCalculationData, - testDetails: TestDetails? + testDetails: UserData? ): String { var outputString = "Test calculation logs ==>\n" - outputString += "Name = ${testDetails?.patientName}\n" - outputString += "ID = ${testDetails?.patientID}\n" + outputString += "Name = ${testDetails?.name}\n" + outputString += "ID = ${testDetails?._id}\n" // outputString += "Gender = ${patientData.gender}\n" outputString += "Absorbance one = ${ String.format( diff --git a/app/src/main/java/com/example/hpos/domain/SaveRawDataTest.kt b/app/src/main/java/com/example/hpostesting/domain/SaveRawDataTest.kt similarity index 92% rename from app/src/main/java/com/example/hpos/domain/SaveRawDataTest.kt rename to app/src/main/java/com/example/hpostesting/domain/SaveRawDataTest.kt index 4173f7c..4b9b55c 100644 --- a/app/src/main/java/com/example/hpos/domain/SaveRawDataTest.kt +++ b/app/src/main/java/com/example/hpostesting/domain/SaveRawDataTest.kt @@ -1,7 +1,7 @@ -package com.example.hpos.domain +package com.example.hpostesting.domain -import com.example.hpos.data.repository.LocalFileRepository -import com.example.hpos.data.model.CalculationVariableForTest +import com.example.hpostesting.data.repository.LocalFileRepository +import com.example.hpostesting.data.model.CalculationVariableForTest class SaveRawDataTest(private val localFileRepository: LocalFileRepository) { diff --git a/app/src/main/java/com/example/hpos/domain/SickleFindResultCaluculationWithMaxImpl.kt b/app/src/main/java/com/example/hpostesting/domain/SickleFindResultCaluculationWithMaxImpl.kt similarity index 93% rename from app/src/main/java/com/example/hpos/domain/SickleFindResultCaluculationWithMaxImpl.kt rename to app/src/main/java/com/example/hpostesting/domain/SickleFindResultCaluculationWithMaxImpl.kt index 8cca8a3..2180dc0 100644 --- a/app/src/main/java/com/example/hpos/domain/SickleFindResultCaluculationWithMaxImpl.kt +++ b/app/src/main/java/com/example/hpostesting/domain/SickleFindResultCaluculationWithMaxImpl.kt @@ -1,8 +1,8 @@ -package com.example.hpos.domain +package com.example.hpostesting.domain -import com.example.hpos.data.constant.Constants -import com.example.hpos.data.model.test.TestRightCalculationData -import com.example.hpos.data.model.test.TestRightResultType +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.model.test.TestRightCalculationData +import com.example.hpostesting.data.model.test.TestRightResultType class SickleFindResultCaluculationWithMaxImpl : TestRightResultCalculation{ diff --git a/app/src/main/java/com/example/hpos/domain/TestRightResultCalculation.kt b/app/src/main/java/com/example/hpostesting/domain/TestRightResultCalculation.kt similarity index 57% rename from app/src/main/java/com/example/hpos/domain/TestRightResultCalculation.kt rename to app/src/main/java/com/example/hpostesting/domain/TestRightResultCalculation.kt index cd65dc6..f625a5d 100644 --- a/app/src/main/java/com/example/hpos/domain/TestRightResultCalculation.kt +++ b/app/src/main/java/com/example/hpostesting/domain/TestRightResultCalculation.kt @@ -1,6 +1,6 @@ -package com.example.hpos.domain +package com.example.hpostesting.domain -import com.example.hpos.data.model.test.TestRightCalculationData +import com.example.hpostesting.data.model.test.TestRightCalculationData interface TestRightResultCalculation { fun getResults( diff --git a/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt b/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt new file mode 100644 index 0000000..2a5c3cc --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/domain/di/AppModule.kt @@ -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() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/KitScanActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/KitScanActivity.kt similarity index 87% rename from app/src/main/java/com/example/hpos/presentation/KitScanActivity.kt rename to app/src/main/java/com/example/hpostesting/presentation/KitScanActivity.kt index 6f45544..30d7d17 100644 --- a/app/src/main/java/com/example/hpos/presentation/KitScanActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/KitScanActivity.kt @@ -1,19 +1,19 @@ -package com.example.hpos.presentation +package com.example.hpostesting.presentation import android.content.Intent import android.os.Bundle import android.util.Log import android.widget.Toast import androidx.appcompat.app.AppCompatActivity -import com.example.hpos.R -import com.example.hpos.data.DataHolder -import com.example.hpos.data.constant.Constants -import com.example.hpos.databinding.ActivityKitScanBinding -import com.example.hpos.presentation.dashboard.DashboardActivity -import com.example.hpos.presentation.testRight.TestRightActivity +import com.example.hpostesting.data.DataHolder +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.presentation.dashboard.DashboardActivity +import com.example.hpostesting.presentation.testRight.TestRightActivity import com.journeyapps.barcodescanner.ScanContract import com.journeyapps.barcodescanner.ScanIntentResult import com.journeyapps.barcodescanner.ScanOptions +import `in`.sminnovations.hpostesting.R +import `in`.sminnovations.hpostesting.databinding.ActivityKitScanBinding class KitScanActivity : AppCompatActivity() { @@ -51,6 +51,7 @@ class KitScanActivity : AppCompatActivity() { startScanningNow() } + binding.btnGo.setOnClickListener { val serialNumber = binding.nameEditText.text.toString().trim() if (serialNumber.isNotEmpty() && checkDataNotNull() && isSerialValid(serialNumber)) { @@ -92,7 +93,7 @@ class KitScanActivity : AppCompatActivity() { } private fun checkDataNotNull(): Boolean { - return if (DataHolder.selectedTest == null) { + return if (DataHolder.selectedTest?._id == null) { Toast.makeText( applicationContext, "Please Select patient before starting test", diff --git a/app/src/main/java/com/example/hpostesting/presentation/MainActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/MainActivity.kt new file mode 100644 index 0000000..11a9476 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/presentation/MainActivity.kt @@ -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, + 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() + } + } + } + } +} diff --git a/app/src/main/java/com/example/hpos/presentation/MainViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/MainViewModel.kt similarity index 61% rename from app/src/main/java/com/example/hpos/presentation/MainViewModel.kt rename to app/src/main/java/com/example/hpostesting/presentation/MainViewModel.kt index d5a1bfb..cfd2a82 100644 --- a/app/src/main/java/com/example/hpos/presentation/MainViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/MainViewModel.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation +package com.example.hpostesting.presentation import androidx.lifecycle.ViewModel diff --git a/app/src/main/java/com/example/hpostesting/presentation/SplashActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/SplashActivity.kt new file mode 100644 index 0000000..a32c1fb --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/presentation/SplashActivity.kt @@ -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() + 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 + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/UsbServiceListener.kt b/app/src/main/java/com/example/hpostesting/presentation/UsbServiceListener.kt similarity index 70% rename from app/src/main/java/com/example/hpos/presentation/UsbServiceListener.kt rename to app/src/main/java/com/example/hpostesting/presentation/UsbServiceListener.kt index 7a331d8..f041e98 100644 --- a/app/src/main/java/com/example/hpos/presentation/UsbServiceListener.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/UsbServiceListener.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation +package com.example.hpostesting.presentation interface UsbServiceListener { fun onUsbRead(data: ByteArray?) diff --git a/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt b/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt new file mode 100644 index 0000000..88ac1c4 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/presentation/adapter/UserListAdapter.kt @@ -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, private val view: View) : + FirestoreRecyclerAdapter(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) + } + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/DashboardActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt similarity index 79% rename from app/src/main/java/com/example/hpos/presentation/dashboard/DashboardActivity.kt rename to app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt index eb644fb..cdd7d10 100644 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/DashboardActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/DashboardActivity.kt @@ -1,27 +1,24 @@ -package com.example.hpos.presentation.dashboard +package com.example.hpostesting.presentation.dashboard import android.os.Bundle import android.view.Menu -import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.drawerlayout.widget.DrawerLayout -import androidx.lifecycle.ViewModelProvider import androidx.navigation.findNavController import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.navigateUp import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupWithNavController -import com.example.hpos.R -import com.example.hpos.databinding.ActivityDashboardBinding -import com.example.hpos.util.MyUtils -import com.example.hpos.util.MyViewModelFactory import com.google.android.material.navigation.NavigationView +import dagger.hilt.android.AndroidEntryPoint +import `in`.sminnovations.hpostesting.R +import `in`.sminnovations.hpostesting.databinding.ActivityDashboardBinding +@AndroidEntryPoint class DashboardActivity : AppCompatActivity() { private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var binding: ActivityDashboardBinding - private lateinit var viewModel: DashboardViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -43,10 +40,6 @@ class DashboardActivity : AppCompatActivity() { setupActionBarWithNavController(navController, appBarConfiguration) navView.setupWithNavController(navController) - viewModel = ViewModelProvider( - this, - MyViewModelFactory() - )[DashboardViewModel::class.java] } override fun onCreateOptionsMenu(menu: Menu): Boolean { diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/GalleryFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/GalleryFragment.kt similarity index 83% rename from app/src/main/java/com/example/hpos/presentation/dashboard/GalleryFragment.kt rename to app/src/main/java/com/example/hpostesting/presentation/dashboard/GalleryFragment.kt index 3b300ac..3043ca5 100644 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/GalleryFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/GalleryFragment.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.dashboard +package com.example.hpostesting.presentation.dashboard import android.os.Bundle import android.view.LayoutInflater @@ -6,8 +6,8 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider -import com.example.hpos.databinding.FragmentGalleryBinding -import com.example.hpos.presentation.dashboard.ui.gallery.GalleryViewModel +import com.example.hpostesting.presentation.dashboard.ui.gallery.GalleryViewModel +import `in`.sminnovations.hpostesting.databinding.FragmentGalleryBinding class GalleryFragment : Fragment() { diff --git a/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt new file mode 100644 index 0000000..329b937 --- /dev/null +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/HomeFragment.kt @@ -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().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().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) { + userDataList.forEach { userData -> + if (userData._id.isEmpty()) { + viewModel.deleteById(userData._id) + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/ItemClickListener.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/ItemClickListener.kt similarity index 51% rename from app/src/main/java/com/example/hpos/presentation/dashboard/ItemClickListener.kt rename to app/src/main/java/com/example/hpostesting/presentation/dashboard/ItemClickListener.kt index e2ca22c..ed60eda 100644 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/ItemClickListener.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/ItemClickListener.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.dashboard +package com.example.hpostesting.presentation.dashboard interface ItemClickListener { fun onClick(pos: Int) diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/SlideshowFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/SlideshowFragment.kt similarity index 83% rename from app/src/main/java/com/example/hpos/presentation/dashboard/SlideshowFragment.kt rename to app/src/main/java/com/example/hpostesting/presentation/dashboard/SlideshowFragment.kt index 4e98ad4..dffb325 100644 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/SlideshowFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/SlideshowFragment.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.dashboard +package com.example.hpostesting.presentation.dashboard import android.os.Bundle import android.view.LayoutInflater @@ -6,8 +6,8 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider -import com.example.hpos.databinding.FragmentSlideshowBinding -import com.example.hpos.presentation.dashboard.ui.slideshow.SlideshowViewModel +import com.example.hpostesting.presentation.dashboard.ui.slideshow.SlideshowViewModel +import `in`.sminnovations.hpostesting.databinding.FragmentSlideshowBinding class SlideshowFragment : Fragment() { diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/ui/gallery/GalleryViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/gallery/GalleryViewModel.kt similarity index 81% rename from app/src/main/java/com/example/hpos/presentation/dashboard/ui/gallery/GalleryViewModel.kt rename to app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/gallery/GalleryViewModel.kt index 7ca47c0..7906635 100644 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/ui/gallery/GalleryViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/gallery/GalleryViewModel.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.dashboard.ui.gallery +package com.example.hpostesting.presentation.dashboard.ui.gallery import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/ui/home/HomeViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/home/HomeViewModel.kt similarity index 82% rename from app/src/main/java/com/example/hpos/presentation/dashboard/ui/home/HomeViewModel.kt rename to app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/home/HomeViewModel.kt index e151bcb..4b02588 100644 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/home/HomeViewModel.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.dashboard.ui.home +package com.example.hpostesting.presentation.dashboard.ui.home import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData diff --git a/app/src/main/java/com/example/hpos/presentation/dashboard/ui/slideshow/SlideshowViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/slideshow/SlideshowViewModel.kt similarity index 81% rename from app/src/main/java/com/example/hpos/presentation/dashboard/ui/slideshow/SlideshowViewModel.kt rename to app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/slideshow/SlideshowViewModel.kt index 04eec20..6d33a57 100644 --- a/app/src/main/java/com/example/hpos/presentation/dashboard/ui/slideshow/SlideshowViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/dashboard/ui/slideshow/SlideshowViewModel.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.dashboard.ui.slideshow +package com.example.hpostesting.presentation.dashboard.ui.slideshow import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData diff --git a/app/src/main/java/com/example/hpos/presentation/testRight/InputData.kt b/app/src/main/java/com/example/hpostesting/presentation/testRight/InputData.kt similarity index 99% rename from app/src/main/java/com/example/hpos/presentation/testRight/InputData.kt rename to app/src/main/java/com/example/hpostesting/presentation/testRight/InputData.kt index 85909a4..449dbda 100644 --- a/app/src/main/java/com/example/hpos/presentation/testRight/InputData.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/testRight/InputData.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.testRight +package com.example.hpostesting.presentation.testRight class InputData { val inputRead = "0,1.69989422e-06,1.60642711e-01,3.85754470e+02,0,0,1,0,FFF-EEEE-PPPP-WW-YY-NNNN\nOK [0]" diff --git a/app/src/main/java/com/example/hpos/presentation/testRight/TestRightActivity.kt b/app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightActivity.kt similarity index 94% rename from app/src/main/java/com/example/hpos/presentation/testRight/TestRightActivity.kt rename to app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightActivity.kt index 5024bdf..a647fa4 100644 --- a/app/src/main/java/com/example/hpos/presentation/testRight/TestRightActivity.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightActivity.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.testRight +package com.example.hpostesting.presentation.testRight import android.app.PendingIntent import android.content.BroadcastReceiver @@ -15,23 +15,24 @@ import android.os.IBinder import android.util.Log import android.view.Menu import android.widget.Toast +import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.view.get -import androidx.lifecycle.ViewModelProvider -import com.example.hpos.R -import com.example.hpos.data.DataHolder -import com.example.hpos.data.constant.Constants -import com.example.hpos.databinding.ActivityTestRightBinding -import com.example.hpos.util.MyViewModelFactory +import com.example.hpostesting.data.DataHolder +import com.example.hpostesting.data.constant.Constants import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialProber +import dagger.hilt.android.AndroidEntryPoint +import `in`.sminnovations.hpostesting.R +import `in`.sminnovations.hpostesting.databinding.ActivityTestRightBinding +@AndroidEntryPoint class TestRightActivity : AppCompatActivity() { private lateinit var binding: ActivityTestRightBinding - private lateinit var viewModel: TestRightViewModel + private val viewModel by viewModels() private var myMenu: Menu? = null private lateinit var mDriver: UsbSerialDriver @@ -78,10 +79,6 @@ class TestRightActivity : AppCompatActivity() { super.onCreate(savedInstanceState) binding = ActivityTestRightBinding.inflate(layoutInflater) setContentView(binding.root) - viewModel = ViewModelProvider( - this, - MyViewModelFactory() - )[TestRightViewModel::class.java] setSupportActionBar(binding.myToolbar) supportActionBar?.setDisplayHomeAsUpEnabled(true) diff --git a/app/src/main/java/com/example/hpos/presentation/testRight/TestRightExpReference.kt b/app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightExpReference.kt similarity index 94% rename from app/src/main/java/com/example/hpos/presentation/testRight/TestRightExpReference.kt rename to app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightExpReference.kt index 2d85640..f41bcca 100644 --- a/app/src/main/java/com/example/hpos/presentation/testRight/TestRightExpReference.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightExpReference.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.testRight +package com.example.hpostesting.presentation.testRight import android.os.Bundle import android.os.Handler @@ -10,17 +10,19 @@ import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import com.example.hpos.R -import com.example.hpos.data.DataHolder -import com.example.hpos.data.constant.Constants -import com.example.hpos.data.constant.TestRightCommands -import com.example.hpos.data.model.ErrorMessage -import com.example.hpos.databinding.FragmentTestRightExpReferenceBinding -import com.example.hpos.presentation.UsbServiceListener -import com.example.hpos.presentation.utils.MyDialogListener -import com.example.hpos.presentation.utils.UIUtils +import com.example.hpostesting.data.DataHolder +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.constant.TestRightCommands +import com.example.hpostesting.data.model.ErrorMessage +import com.example.hpostesting.presentation.UsbServiceListener +import com.example.hpostesting.presentation.utils.MyDialogListener +import com.example.hpostesting.presentation.utils.UIUtils +import dagger.hilt.android.AndroidEntryPoint +import `in`.sminnovations.hpostesting.R +import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpReferenceBinding +@AndroidEntryPoint class TestRightExpReference : Fragment() { private lateinit var binding: FragmentTestRightExpReferenceBinding diff --git a/app/src/main/java/com/example/hpos/presentation/testRight/TestRightExpSample.kt b/app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightExpSample.kt similarity index 92% rename from app/src/main/java/com/example/hpos/presentation/testRight/TestRightExpSample.kt rename to app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightExpSample.kt index 33b40dd..bbfcb41 100644 --- a/app/src/main/java/com/example/hpos/presentation/testRight/TestRightExpSample.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightExpSample.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.testRight +package com.example.hpostesting.presentation.testRight import android.content.Intent import android.os.Bundle @@ -10,19 +10,20 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import com.example.hpos.R -import com.example.hpos.data.DataHolder -import com.example.hpos.data.PreferenceUtility -import com.example.hpos.data.constant.Constants -import com.example.hpos.data.constant.TestRightCommands -import com.example.hpos.data.model.ErrorMessage -import com.example.hpos.data.model.test.TestType -import com.example.hpos.databinding.FragmentTestRightExpSampleBinding -import com.example.hpos.presentation.MainActivity -import com.example.hpos.presentation.UsbServiceListener -import com.example.hpos.presentation.utils.MyDialogListener -import com.example.hpos.presentation.utils.UIUtils +import com.example.hpostesting.data.DataHolder +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.constant.TestRightCommands +import com.example.hpostesting.data.model.ErrorMessage +import com.example.hpostesting.data.model.test.TestType +import com.example.hpostesting.presentation.MainActivity +import com.example.hpostesting.presentation.UsbServiceListener +import com.example.hpostesting.presentation.utils.MyDialogListener +import com.example.hpostesting.presentation.utils.UIUtils +import dagger.hilt.android.AndroidEntryPoint +import `in`.sminnovations.hpostesting.R +import `in`.sminnovations.hpostesting.databinding.FragmentTestRightExpSampleBinding +@AndroidEntryPoint class TestRightExpSample : Fragment() { private lateinit var binding: FragmentTestRightExpSampleBinding @@ -256,11 +257,9 @@ class TestRightExpSample : Fragment() { // val fileNameCsv = prefixCsv + id + fileExtensionCsv - // NEW ------------------------------ viewModel.saveCsv(requireContext().applicationContext, viewModel.getCSVFileName()) - viewModel.saveCsvForTesting(requireContext().applicationContext, viewModel.getDetailedCSVFileName()) - +// viewModel.saveCsvForTesting(requireContext().applicationContext, viewModel.getDetailedCSVFileName()) viewModel.saveLogWithPatient(requireContext().applicationContext, viewModel.getLogFileName()) } diff --git a/app/src/main/java/com/example/hpos/presentation/testRight/TestRightResults.kt b/app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightResults.kt similarity index 50% rename from app/src/main/java/com/example/hpos/presentation/testRight/TestRightResults.kt rename to app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightResults.kt index 279eb37..37b0dfe 100644 --- a/app/src/main/java/com/example/hpos/presentation/testRight/TestRightResults.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightResults.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.testRight +package com.example.hpostesting.presentation.testRight import android.content.Intent import android.os.Bundle @@ -9,32 +9,35 @@ import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import com.example.hpos.R -import com.example.hpos.data.DataHolder -import com.example.hpos.data.PreferenceUtility -import com.example.hpos.data.constant.Constants -import com.example.hpos.data.model.test.TestRightResultType -import com.example.hpos.data.model.test.TestType -import com.example.hpos.databinding.FragmentTestRightResultsBinding -import com.example.hpos.presentation.dashboard.DashboardActivity -import com.example.hpos.util.MyUtils -import com.example.hpos.util.MyUtils.calculateAgeFromYOB +import com.example.hpostesting.data.DataHolder +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.model.test.TestRightResultType +import com.example.hpostesting.data.model.test.TestType +import com.example.hpostesting.presentation.dashboard.DashboardActivity +import com.example.hpostesting.util.MyUtils.calculateAgeFromYOB +import dagger.hilt.android.AndroidEntryPoint +import `in`.sminnovations.hpostesting.R +import `in`.sminnovations.hpostesting.databinding.FragmentTestRightResultsBinding import java.text.SimpleDateFormat import java.util.Date +@AndroidEntryPoint class TestRightResults : Fragment() { private lateinit var binding: FragmentTestRightResultsBinding private val viewModel: TestRightViewModel by activityViewModels() private val TAG = "TestRightResults" + private var isOnline = false override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { // Inflate the layout for this fragment binding = FragmentTestRightResultsBinding.inflate(inflater, container, false) + viewModel.networkStatusLiveData.observe(viewLifecycleOwner) { isNetworkAvailable -> + isOnline = isNetworkAvailable + } return binding.root } @@ -43,14 +46,13 @@ class TestRightResults : Fragment() { setupListeners() updateResults() - viewModel.addResultTestToDb() - - // This is to add files to the pending queue - viewModel.addFilesToQueue(requireContext()) - - // Uploading to cloud storage and deleting the from the pending queue when uploaded - if (MyUtils.isInternetConnected()) { - viewModel.addFilesToCloud(requireContext()) + viewModel.fireBaseUpload.observe(viewLifecycleOwner) { + if (it == "Success") { + Toast.makeText( + requireContext(), "Test Results Upload Successfully", Toast.LENGTH_SHORT + ).show() + } + binding.progressBar.visibility = View.GONE } } @@ -68,35 +70,49 @@ class TestRightResults : Fragment() { } private fun updateResults() { - binding.tvName.text = getString(R.string.name_in_textview, viewModel.testDetails?.patientName) - binding.tvAge.text = - getString(R.string.age_in_textview, viewModel.testDetails?.patientAge?.calculateAgeFromYOB().toString()) + if (viewModel.testDetails?.name == "" && viewModel.testDetails?.birthYear == "") { + binding.tvName.visibility = View.GONE + binding.tvAge.visibility = View.GONE + } else { + binding.tvName.text = getString(R.string.name_in_textview, viewModel.testDetails?.name) + binding.tvAge.text = getString( + R.string.age_in_textview, + viewModel.testDetails?.birthYear?.toInt()?.calculateAgeFromYOB().toString() + ) + } - binding.tvId.text = getString(R.string.patient_id_in_tv, viewModel.testDetails?.patientID) + binding.tvId.text = getString(R.string.patient_id_in_tv, viewModel.testDetails?._id) - if (DataHolder.selectedTestType == TestType.SICKLECERT){ + if (DataHolder.selectedTestType == TestType.SICKLECERT) { when (viewModel.testDetails?.result) { TestRightResultType.NORMAL -> { binding.resultNormal.visibility = View.VISIBLE } + TestRightResultType.SICKLECELLDISEASE -> { binding.resultDisease.visibility = View.VISIBLE } + TestRightResultType.SICKLECELLTRAIT -> { binding.resultTrait.visibility = View.VISIBLE } + TestRightResultType.POSITIVEBORDERLINE -> { binding.resultPositiveBorderline.visibility = View.VISIBLE binding.tvRecommended.visibility = View.VISIBLE } + TestRightResultType.NEGATIVEBORDERLINE -> { binding.resultNegativeBorderline.visibility = View.VISIBLE binding.tvRecommended.visibility = View.VISIBLE } + else -> { // binding.resultUndefined.visibility = View.VISIBLE - Toast.makeText(requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG).show() + Toast.makeText( + requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG + ).show() moveToSamplePage() } } @@ -106,20 +122,31 @@ class TestRightResults : Fragment() { binding.resultDisease.visibility = View.VISIBLE binding.resultDisease.text = "Positive" } + TestRightResultType.NORMAL -> { binding.resultNormal.visibility = View.VISIBLE binding.resultNormal.text = "Negative" } + else -> { - Toast.makeText(requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG).show() + Toast.makeText( + requireContext().applicationContext, "Please Test Again", Toast.LENGTH_LONG + ).show() moveToSamplePage() } } } -// if (viewModel.patientDetails.age < 5) { -// binding.tvRecommended.visibility = View.VISIBLE -// binding.tvRecommended.text = getString(R.string.recommended_age) -// } + if (isOnline) { + viewModel.uploadResultToDatabase(requireContext(), true) + binding.progressBar.visibility = View.VISIBLE + } else { + viewModel.uploadResultToDatabase(requireContext(), false) + Toast.makeText( + requireContext(), + "Internet not available, Test Data added to Local DB", + Toast.LENGTH_SHORT + ).show() + } } @@ -127,8 +154,7 @@ class TestRightResults : Fragment() { if (DataHolder.sampleReadCounter > Constants.MAXIMUM_TEST_ALLOWED_BEFORE_REFERENCE) { DataHolder.sampleReadCounter = 0 DataHolder.isReferenceTaken = false - parentFragmentManager.beginTransaction() - .replace(R.id.fl_main, TestRightExpReference()) + parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightExpReference()) .commit() } else { parentFragmentManager.beginTransaction().replace(R.id.fl_main, TestRightExpSample()) @@ -144,55 +170,6 @@ class TestRightResults : Fragment() { viewModel.saveLog(requireContext().applicationContext, fileName) -// if (!DataHolder.isAppFolderCreated) { -// val folderPath = MyUtils.createAppFolder(requireContext().applicationContext) -// if (folderPath != null) { -// DataHolder.isAppFolderCreated = true -// DataHolder.appFolderPath = folderPath -// viewModel.saveLog(DataHolder.appFolderPath, fileName) -// } -// } else { -// viewModel.saveLog(DataHolder.appFolderPath, fileName) -// } + } - -// private fun saveCsv() { -// Log.d(TAG, "saveCsv() called") -// -// val sdfDate = SimpleDateFormat("ddMMyyyy HHmmss") -// val fileName: String = sdfDate.format(Date()) + ".csv" -// -// if (!DataHolder.isAppFolderCreated) { -// val folderPath = MyUtils.createAppFolder(requireContext().applicationContext) -// if (folderPath != null) { -// DataHolder.isAppFolderCreated = true -// DataHolder.appFolderPath = folderPath -// viewModel.saveCsv(DataHolder.appFolderPath, fileName) -// -// viewModel.saveCsvForTesting(DataHolder.appFolderPath, "testing$fileName") -// } -// } else { -// viewModel.saveCsv(DataHolder.appFolderPath, fileName) -// -// viewModel.saveCsvForTesting(DataHolder.appFolderPath, "testing$fileName") -// } -// -// } - - private fun saveCsv() { - Log.d(TAG, "saveCsv() called") - -// val sdfDate = SimpleDateFormat("ddMMyyyy HHmmss") -// val fileName: String = sdfDate.format(Date()) + ".csv" - - val prefix = "HPOSSC_${DataHolder.deviceSerialNumber}_" - val fileExtension = ".csv" - - val fileName = PreferenceUtility.generateId(requireContext(), prefix) + fileExtension - - - viewModel.saveCsv(requireContext().applicationContext, fileName) - viewModel.saveCsvForTesting(requireContext().applicationContext, "testing$fileName") - } - } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpos/presentation/testRight/TestRightViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightViewModel.kt similarity index 70% rename from app/src/main/java/com/example/hpos/presentation/testRight/TestRightViewModel.kt rename to app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightViewModel.kt index fd33939..542dd34 100644 --- a/app/src/main/java/com/example/hpos/presentation/testRight/TestRightViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/testRight/TestRightViewModel.kt @@ -1,56 +1,67 @@ -package com.example.hpos.presentation.testRight +package com.example.hpostesting.presentation.testRight import android.content.Context +import android.net.Uri import android.util.Log +import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.example.hpos.data.DataHolder -import com.example.hpos.data.repository.DatabaseRepository -import com.example.hpos.data.model.Response -import com.example.hpos.data.constant.Constants -import com.example.hpos.data.model.CalculationVariableForTest -import com.example.hpos.data.model.ErrorMessage -import com.example.hpos.data.model.PendingUploads -import com.example.hpos.data.model.test.Status -import com.example.hpos.data.model.test.TestRightCalculationData -import com.example.hpos.data.model.test.TestRightDeviceConstants -import com.example.hpos.data.model.test.TestType -import com.example.hpos.domain.ResultCalculationWithMaxImpl -import com.example.hpos.domain.SaveRawData -import com.example.hpos.domain.SaveRawDataTest -import com.example.hpos.domain.SickleFindResultCaluculationWithMaxImpl -import com.example.hpos.domain.TestRightResultCalculation -import com.example.hpos.util.MyUtils -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope +import com.example.hpostesting.data.DataHolder +import com.example.hpostesting.data.NetworkStatusLiveData +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.dao.UserDao +import com.example.hpostesting.data.model.CalculationVariableForTest +import com.example.hpostesting.data.model.ErrorMessage +import com.example.hpostesting.data.model.Response +import com.example.hpostesting.data.model.patient.UserData +import com.example.hpostesting.data.model.test.TestRightCalculationData +import com.example.hpostesting.data.model.test.TestRightDeviceConstants +import com.example.hpostesting.data.model.test.TestType +import com.example.hpostesting.data.repository.DatabaseRepository +import com.example.hpostesting.domain.ResultCalculationWithMaxImpl +import com.example.hpostesting.domain.SaveRawData +import com.example.hpostesting.domain.SaveRawDataTest +import com.example.hpostesting.domain.SickleFindResultCaluculationWithMaxImpl +import com.example.hpostesting.domain.TestRightResultCalculation +import com.example.hpostesting.util.MyUtils +import com.google.firebase.storage.FirebaseStorage +import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch +import kotlinx.coroutines.tasks.await +import java.io.File import java.text.SimpleDateFormat import java.util.Calendar import java.util.Date +import javax.inject.Inject import kotlin.math.log10 import kotlin.math.pow -class TestRightViewModel( +@HiltViewModel +class TestRightViewModel @Inject constructor( private val saveRawData: SaveRawData, private val saveRawDataTest: SaveRawDataTest, - private val repository: DatabaseRepository + private val repository: DatabaseRepository, + private val userDao: UserDao, + context: Context ) : ViewModel() { - private val TAG = "TestRightViewModel" - var isServiceConnected = false val progressBar = MutableLiveData(false) - // val errorTriggered = MutableLiveData("") val errorTriggered = MutableLiveData() var numberOfSampleRun = 0 -// lateinit var patientDetails: PatientData + val fireBaseUpload = MutableLiveData() val testDetails = DataHolder.selectedTest - // var deviceConstant: TestRightDeviceConstants? = null + private val _networkStatusLiveData = NetworkStatusLiveData(context) + val networkStatusLiveData: LiveData + get() = _networkStatusLiveData + + val allUserData = userDao.getAll() + private lateinit var calculationData: TestRightCalculationData /* (For exp sample) Contains pixel no. -> Intensity of light falling on that pixel */ @@ -79,8 +90,7 @@ class TestRightViewModel( // "Error 201: In processing the data from device" errorTriggered.postValue( ErrorMessage( - "Error 201: In processing the data from device", - Constants.ERROR_NORMAL + "Error 201: In processing the data from device", Constants.ERROR_NORMAL ) ) } @@ -89,8 +99,7 @@ class TestRightViewModel( // "Error 202: Unable to fetch data from device." errorTriggered.postValue( ErrorMessage( - "Error 202: Unable to fetch data from device.", - Constants.ERROR_NORMAL + "Error 202: Unable to fetch data from device.", Constants.ERROR_NORMAL ) ) } @@ -103,13 +112,9 @@ class TestRightViewModel( if (DataHolder.deviceConstant != null) { for (x in 1..Constants.TEST_RIGHT_TOTAL_PIXEL) { // val index = x - 1 - val wavelength: Double = - (DataHolder.deviceConstant!!.a.toDouble() * (x.toDouble() - .pow((3).toDouble()))) + - (DataHolder.deviceConstant!!.b.toDouble() * (x.toDouble() - .pow((2).toDouble()))) + - (DataHolder.deviceConstant!!.c.toDouble() * x) + - (DataHolder.deviceConstant!!.d.toDouble()) + val wavelength: Double = (DataHolder.deviceConstant!!.a.toDouble() * (x.toDouble() + .pow((3).toDouble()))) + (DataHolder.deviceConstant!!.b.toDouble() * (x.toDouble() + .pow((2).toDouble()))) + (DataHolder.deviceConstant!!.c.toDouble() * x) + (DataHolder.deviceConstant!!.d.toDouble()) DataHolder.wavelengthToPixelArray.add(wavelength) } @@ -118,8 +123,7 @@ class TestRightViewModel( // "Error 203: Unable to fetch data from device." errorTriggered.postValue( ErrorMessage( - "Error 203: Unable to fetch data from device.", - Constants.ERROR_NORMAL + "Error 203: Unable to fetch data from device.", Constants.ERROR_NORMAL ) ) @@ -136,22 +140,17 @@ class TestRightViewModel( val listOfString = fullString.split("\n") for (line in listOfString) { - if ("Buf" in line) { - /* Removing trailing spaces and "Buf" from the string then taking lhs & rhs of ':' */ - val numbers = line.trim() - .substring(3).split(":") + if ("Buf" in line) {/* Removing trailing spaces and "Buf" from the string then taking lhs & rhs of ':' */ + val numbers = line.trim().substring(3).split(":") if (numbers.size >= 2) { - if (isReference) - DataHolder.intensityReferenceArray.add(numbers[1].toDouble()) - else - intensitySampleArray.add(numbers[1].toDouble()) + if (isReference) DataHolder.intensityReferenceArray.add(numbers[1].toDouble()) + else intensitySampleArray.add(numbers[1].toDouble()) } else { // "Error 204: Unable to fetch data from device." errorTriggered.postValue( ErrorMessage( - "Error 204: Unable to fetch data from device.", - Constants.ERROR_NORMAL + "Error 204: Unable to fetch data from device.", Constants.ERROR_NORMAL ) ) @@ -265,7 +264,7 @@ class TestRightViewModel( testDetails?.result = calculationData.result testDetails?.resultRatio = calculationData.ratioValue - testDetails?.testStatus = Status.COMPLETED + testDetails?.testStatus = true } @@ -275,7 +274,7 @@ class TestRightViewModel( SickleFindResultCaluculationWithMaxImpl() calculationData = resultCalculation.getResults(wavelengthToAbsorbance) testDetails?.result = calculationData.result - testDetails?.testStatus = Status.COMPLETED + testDetails?.testStatus = true } @@ -369,10 +368,7 @@ class TestRightViewModel( if (DataHolder.isAppFolderCreated) { // SaveRawData().saveLogWithPatientData( saveRawData.saveLogWithPatientData( - folderPath!!, - fileName, - calculationData, - testDetails + folderPath!!, fileName, calculationData, testDetails ) } else { folderPath = MyUtils.createAppFolder(appContext) @@ -381,10 +377,7 @@ class TestRightViewModel( DataHolder.appFolderPath = folderPath // SaveRawData().saveLogWithPatientData( saveRawData.saveLogWithPatientData( - folderPath, - fileName, - calculationData, - testDetails + folderPath, fileName, calculationData, testDetails ) } else { // errorTriggered.postValue("Unable to save Log, Please try again") @@ -427,129 +420,112 @@ class TestRightViewModel( } fun getCSVFileName(): String { - val prefixCsv: String = if (DataHolder.selectedTestType == TestType.SICKLECERT) - "HPOSSC_${testDetails?.testID}" - else - "HPOSSF_${testDetails?.testID}" + val prefixCsv: String = + if (DataHolder.selectedTestType == TestType.SICKLECERT) "HPOSSC_${testDetails?._id}" + else "HPOSSF_${testDetails?._id}" val fileExtensionCsv = ".csv" return prefixCsv + fileExtensionCsv } - fun getDetailedCSVFileName(): String { - return "detailed_" + getCSVFileName() - } - fun getLogFileName(): String { - val prefixTxt = "log_${testDetails?.testID}" + val prefixTxt = "log_${testDetails?._id}" val fileExtensionTxt = ".txt" return prefixTxt + fileExtensionTxt } - fun addResultTestToDb() { + private fun addResultTestToDb() { + testDetails?.location = DataHolder.location + testDetails?.testTime = Calendar.getInstance().time.toString() viewModelScope.launch { - testDetails!!.uploadTime = Calendar.getInstance().time - repository.addTestToDatabase(testDetails) + testDetails!!.uploadTime = Calendar.getInstance().time.toString() + when (repository.addTestToDatabase(testDetails)) { + is Response.Success -> { + fireBaseUpload.postValue("Success") + } + + else -> {} + } } } - fun addFilesToQueue(context: Context) { - viewModelScope.launch { - val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName() - val pendingId = getCSVFileName().split(".")[0] - repository.addToPendingQueue( - PendingUploads( - pendingId, - DataHolder.mobileUniqueId!!, - testDetails!!.patientID, - csvFilePath, - Calendar.getInstance().time - ) - ) - } - viewModelScope.launch { - val detailedCsvFilePath = MyUtils.getAppFolderPath(context) + getDetailedCSVFileName() - val pendingId = getDetailedCSVFileName().split(".")[0] - repository.addToPendingQueue( - PendingUploads( - pendingId, - DataHolder.mobileUniqueId!!, - testDetails!!.patientID, - detailedCsvFilePath, - Calendar.getInstance().time - ) - ) - } - viewModelScope.launch { - val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName() - val pendingId = getLogFileName().split(".")[0] - repository.addToPendingQueue( - PendingUploads( - pendingId, - DataHolder.mobileUniqueId!!, - testDetails!!.patientID, - logTxtFilePath, - Calendar.getInstance().time - ) - ) + fun uploadResultToDatabase(context: Context, isOnline: Boolean) = viewModelScope.launch { + val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName() + val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName() + testDetails?.csvPath = csvFilePath + testDetails?.reportPath = logTxtFilePath + if (isOnline) { + val storageRef = FirebaseStorage.getInstance().reference + val storageTestDetailsRef = storageRef.child("${testDetails?._id}/") + + try { + val csvFileUri = Uri.fromFile(File(csvFilePath)) + val logTxtFileUri = Uri.fromFile(File(logTxtFilePath)) + + val csvUploadTask = + storageTestDetailsRef.child(csvFileUri.lastPathSegment!!).putFile(csvFileUri) + .await() + val logUploadTask = storageTestDetailsRef.child(logTxtFileUri.lastPathSegment!!) + .putFile(logTxtFileUri).await() + + val csvUri = csvUploadTask.storage.downloadUrl.await().toString() + val logUri = logUploadTask.storage.downloadUrl.await().toString() + + testDetails?.csvPath = csvUri + testDetails?.reportPath = logUri + + addResultTestToDb() + } catch (exception: Exception) { + // Handle the exception appropriately (e.g., log the error, display an error message) + } + } else { + testDetails?.testTime = Calendar.getInstance().time.toString() + userDao.insertAll(testDetails!!) } } - fun addFilesToCloud(context: Context) { - GlobalScope.launch(Dispatchers.IO) { - val csvFilePath = MyUtils.getAppFolderPath(context) + getCSVFileName() - val fileName = getCSVFileName().split(".")[0] - val response = repository.uploadFileToStorage(testDetails!!.patientID, csvFilePath) + fun bulkUploadResultToDatabase(userData: UserData) = viewModelScope.launch { + val storageRef = FirebaseStorage.getInstance().reference + val storageTestDetailsRef = storageRef.child("${testDetails?._id}/") + try { + val csvFileUri = Uri.fromFile(File(userData.csvPath)) + val logTxtFileUri = Uri.fromFile(File(userData.reportPath)) - when (response) { + val csvUploadTask = + storageTestDetailsRef.child(csvFileUri.lastPathSegment!!).putFile(csvFileUri) + .await() + val logUploadTask = + storageTestDetailsRef.child(logTxtFileUri.lastPathSegment!!).putFile(logTxtFileUri) + .await() + + val csvUri = csvUploadTask.storage.downloadUrl.await().toString() + val logUri = logUploadTask.storage.downloadUrl.await().toString() + + userData.csvPath = csvUri + userData.reportPath = logUri + + bulkAddResultTestToDb(userData) + } catch (exception: Exception) { + // Handle the exception appropriately (e.g., log the error, display an error message) + } + } + + private fun bulkAddResultTestToDb(userData: UserData) { + userData.location = DataHolder.location + viewModelScope.launch { + userData.uploadTime = Calendar.getInstance().time.toString() + when (repository.addTestToDatabase(userData)) { is Response.Success -> { - Log.d(TAG, "Uploaded $csvFilePath") - repository.removeFromPendingQueue(fileName) - } - - is Response.Error -> { - Log.d(TAG, response.exception.toString()) + fireBaseUpload.postValue("Success") } + else -> {} } } + } - GlobalScope.launch(Dispatchers.IO) { - val detailedCsvFilePath = - MyUtils.getAppFolderPath(context) + getDetailedCSVFileName() - val fileName = getDetailedCSVFileName().split(".")[0] - val response = - repository.uploadFileToStorage(testDetails!!.patientID, detailedCsvFilePath) - - when (response) { - is Response.Success -> { - Log.d(TAG, "Uploaded $detailedCsvFilePath") - repository.removeFromPendingQueue(fileName) - } - - is Response.Error -> { - Log.d(TAG, response.exception.toString()) - } - } - } - - GlobalScope.launch(Dispatchers.IO) { - val logTxtFilePath = MyUtils.getAppFolderPath(context) + getLogFileName() - val fileName = getLogFileName().split(".")[0] - val response = - repository.uploadFileToStorage(testDetails!!.patientID, logTxtFilePath) - - when (response) { - is Response.Success -> { - Log.d(TAG, "Uploaded $logTxtFilePath") - repository.removeFromPendingQueue(fileName) - } - - is Response.Error -> { - Log.d(TAG, response.exception.toString()) - } - } - } + fun deleteById(userId: String) = viewModelScope.launch { + userDao.deleteById(id = userId) } diff --git a/app/src/main/java/com/example/hpos/presentation/testRight/UsbService.kt b/app/src/main/java/com/example/hpostesting/presentation/testRight/UsbService.kt similarity index 94% rename from app/src/main/java/com/example/hpos/presentation/testRight/UsbService.kt rename to app/src/main/java/com/example/hpostesting/presentation/testRight/UsbService.kt index 0fd608b..b7aeb54 100644 --- a/app/src/main/java/com/example/hpos/presentation/testRight/UsbService.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/testRight/UsbService.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.testRight +package com.example.hpostesting.presentation.testRight import android.app.Service import android.content.Intent @@ -6,10 +6,9 @@ import android.hardware.usb.UsbDeviceConnection import android.os.Binder import android.os.IBinder import android.util.Log -import com.example.hpos.data.DataHolder -import com.example.hpos.data.constant.Constants -import com.example.hpos.data.constant.TestRightCommands -import com.example.hpos.presentation.UsbServiceListener +import com.example.hpostesting.data.constant.Constants +import com.example.hpostesting.data.constant.TestRightCommands +import com.example.hpostesting.presentation.UsbServiceListener import com.hoho.android.usbserial.driver.UsbSerialDriver import com.hoho.android.usbserial.driver.UsbSerialPort import com.hoho.android.usbserial.util.SerialInputOutputManager diff --git a/app/src/main/java/com/example/hpos/presentation/utils/MyDialogListener.kt b/app/src/main/java/com/example/hpostesting/presentation/utils/MyDialogListener.kt similarity index 64% rename from app/src/main/java/com/example/hpos/presentation/utils/MyDialogListener.kt rename to app/src/main/java/com/example/hpostesting/presentation/utils/MyDialogListener.kt index bdda75e..ec23247 100644 --- a/app/src/main/java/com/example/hpos/presentation/utils/MyDialogListener.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/utils/MyDialogListener.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.utils +package com.example.hpostesting.presentation.utils interface MyDialogListener { fun onClickNegativeButton() diff --git a/app/src/main/java/com/example/hpos/presentation/utils/UIUtils.kt b/app/src/main/java/com/example/hpostesting/presentation/utils/UIUtils.kt similarity index 94% rename from app/src/main/java/com/example/hpos/presentation/utils/UIUtils.kt rename to app/src/main/java/com/example/hpostesting/presentation/utils/UIUtils.kt index 1a970fd..e0672cd 100644 --- a/app/src/main/java/com/example/hpos/presentation/utils/UIUtils.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/utils/UIUtils.kt @@ -1,4 +1,4 @@ -package com.example.hpos.presentation.utils +package com.example.hpostesting.presentation.utils import android.content.Context import android.widget.Toast diff --git a/app/src/main/java/com/example/hpos/test.kt b/app/src/main/java/com/example/hpostesting/test.kt similarity index 87% rename from app/src/main/java/com/example/hpos/test.kt rename to app/src/main/java/com/example/hpostesting/test.kt index af9040c..1f51a81 100644 --- a/app/src/main/java/com/example/hpos/test.kt +++ b/app/src/main/java/com/example/hpostesting/test.kt @@ -1,4 +1,4 @@ -package com.example.hpos +package com.example.hpostesting import java.text.SimpleDateFormat import java.util.Date diff --git a/app/src/main/java/com/example/hpos/util/MyUtils.kt b/app/src/main/java/com/example/hpostesting/util/MyUtils.kt similarity index 94% rename from app/src/main/java/com/example/hpos/util/MyUtils.kt rename to app/src/main/java/com/example/hpostesting/util/MyUtils.kt index c7bf576..d4e39e9 100644 --- a/app/src/main/java/com/example/hpos/util/MyUtils.kt +++ b/app/src/main/java/com/example/hpostesting/util/MyUtils.kt @@ -1,12 +1,11 @@ -package com.example.hpos.util +package com.example.hpostesting.util import android.content.Context import android.os.Environment -import com.example.hpos.R -import com.example.hpos.data.model.patient.PatientDetails +import com.example.hpostesting.data.model.patient.PatientDetails +import `in`.sminnovations.hpostesting.R import java.io.File import java.io.IOException -import java.net.InetAddress import java.text.SimpleDateFormat import java.util.Date import java.util.Locale diff --git a/app/src/main/res/drawable/edit_text_background.xml b/app/src/main/res/drawable/edit_text_background.xml new file mode 100644 index 0000000..e622a59 --- /dev/null +++ b/app/src/main/res/drawable/edit_text_background.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/upload_data.xml b/app/src/main/res/drawable/upload_data.xml new file mode 100644 index 0000000..c990419 --- /dev/null +++ b/app/src/main/res/drawable/upload_data.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/font/inter_bold.xml b/app/src/main/res/font/inter_bold.xml deleted file mode 100644 index fc40af7..0000000 --- a/app/src/main/res/font/inter_bold.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/font/inter_medium.xml b/app/src/main/res/font/inter_medium.xml deleted file mode 100644 index 70a4c86..0000000 --- a/app/src/main/res/font/inter_medium.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/font/inter_regular.xml b/app/src/main/res/font/inter_regular.xml deleted file mode 100644 index ca1046d..0000000 --- a/app/src/main/res/font/inter_regular.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/font/poppins400.xml b/app/src/main/res/font/poppins400.xml deleted file mode 100644 index 6e147d1..0000000 --- a/app/src/main/res/font/poppins400.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/font/poppins500.xml b/app/src/main/res/font/poppins500.xml deleted file mode 100644 index 7084cda..0000000 --- a/app/src/main/res/font/poppins500.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/font/poppins600.xml b/app/src/main/res/font/poppins600.xml deleted file mode 100644 index 803c4d6..0000000 --- a/app/src/main/res/font/poppins600.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/font/poppins_bold.ttf b/app/src/main/res/font/poppins_bold.ttf new file mode 100644 index 0000000..b94d47f Binary files /dev/null and b/app/src/main/res/font/poppins_bold.ttf differ diff --git a/app/src/main/res/font/poppins_extra_bold.ttf b/app/src/main/res/font/poppins_extra_bold.ttf new file mode 100644 index 0000000..8f008c3 Binary files /dev/null and b/app/src/main/res/font/poppins_extra_bold.ttf differ diff --git a/app/src/main/res/font/poppins_light.ttf b/app/src/main/res/font/poppins_light.ttf new file mode 100644 index 0000000..2ab0221 Binary files /dev/null and b/app/src/main/res/font/poppins_light.ttf differ diff --git a/app/src/main/res/font/poppins_medium.ttf b/app/src/main/res/font/poppins_medium.ttf new file mode 100644 index 0000000..e90e87e Binary files /dev/null and b/app/src/main/res/font/poppins_medium.ttf differ diff --git a/app/src/main/res/font/poppins_regular.ttf b/app/src/main/res/font/poppins_regular.ttf new file mode 100644 index 0000000..be06e7f Binary files /dev/null and b/app/src/main/res/font/poppins_regular.ttf differ diff --git a/app/src/main/res/font/poppins_semi_bold.ttf b/app/src/main/res/font/poppins_semi_bold.ttf new file mode 100644 index 0000000..dabf7c2 Binary files /dev/null and b/app/src/main/res/font/poppins_semi_bold.ttf differ diff --git a/app/src/main/res/font/roboto.xml b/app/src/main/res/font/roboto.xml deleted file mode 100644 index 2641caf..0000000 --- a/app/src/main/res/font/roboto.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/font/roboto_medium.xml b/app/src/main/res/font/roboto_medium.xml deleted file mode 100644 index 59df90b..0000000 --- a/app/src/main/res/font/roboto_medium.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 0ec12a4..f05195a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -30,7 +30,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/my_toolbar" /> - - + - - + - - + - - + diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index e7d3f3b..55b1b1b 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -1,23 +1,90 @@ - + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent"> + android:layout_height="match_parent" + android:visibility="gone" + android:padding="24dp"> + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + - - - - - + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/radioGroup" + tools:listitem="@layout/user_item_view"/> - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_test_right_results.xml b/app/src/main/res/layout/fragment_test_right_results.xml index 67748f4..d1dcea9 100644 --- a/app/src/main/res/layout/fragment_test_right_results.xml +++ b/app/src/main/res/layout/fragment_test_right_results.xml @@ -253,7 +253,7 @@ app:layout_constraintTop_toBottomOf="@id/cv_sample_details" /> + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/dashboard_navigation.xml b/app/src/main/res/navigation/dashboard_navigation.xml index 4194ee1..91e4adf 100644 --- a/app/src/main/res/navigation/dashboard_navigation.xml +++ b/app/src/main/res/navigation/dashboard_navigation.xml @@ -7,14 +7,11 @@ - @@ -22,62 +19,17 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index bbb6efe..5af8330 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -14,4 +14,11 @@ #e5f3ff + #4daaff + #005db3 + #e5f3ff + #FF0000 + + + \ No newline at end of file diff --git a/app/src/main/res/values/preloaded_fonts.xml b/app/src/main/res/values/preloaded_fonts.xml deleted file mode 100644 index 87d1584..0000000 --- a/app/src/main/res/values/preloaded_fonts.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - @font/roboto - @font/roboto_medium - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ffc55f7..cb5af81 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -170,6 +170,15 @@ Baseline Instruction To be launched in next version of the app Invalid Kit Serial Number, correct example, SMI/SC/019/01/001 - + User List + User ID + Aadhar ID + Internet not available, please enter the user ID manually + User ID should be 18 digits + Upload DB Registration + Do you want to upload the local DB Registration to the cloud? + Upload + Cancel + Upload done successfully \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index c3b9ad6..da999a3 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -11,50 +11,43 @@ - - diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 131ce2c..e6a2c5d 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -37,6 +37,16 @@ true + +