Added new dashboard, scanning, registration UI & functionality.

This commit is contained in:
vsuryakumar
2023-05-30 08:48:59 +05:30
parent 30665be147
commit 0e5046d521
72 changed files with 2576 additions and 160 deletions

View File

@@ -1,8 +1,8 @@
package com.example.hpos.data
import androidx.lifecycle.MutableLiveData
import com.example.hpos.data.model.TestRightDeviceConstants
import com.example.hpos.data.model.TestType
import com.example.hpos.data.model.test.TestRightDeviceConstants
import com.example.hpos.data.model.test.TestType
object DataHolder {

View File

@@ -1,6 +1,6 @@
package com.example.hpos.data
import com.example.hpos.data.model.TestInfo
import com.example.hpos.data.model.test.TestInfo
interface Repository {
suspend fun saveToDatabase(info: TestInfo)

View File

@@ -1,6 +1,6 @@
package com.example.hpos.data
import com.example.hpos.data.model.TestInfo
import com.example.hpos.data.model.test.TestInfo
class RepositoryImpl : Repository {

View File

@@ -3,6 +3,8 @@ package com.example.hpos.data.constant
object Constants {
const val ACTION_USB_PERMISSION = "shanmukha.in.sickle_cell.USB_PERMISSION"
const val ABHA_APP_PACKAGE = "in.ndhm.phr"
const val WRITE_TIMEOUT_MILLIS = 30000 // 30 sec
const val READ_TIMEOUT_MILLIS = 60000 // 1 min
const val DELAY_BETWEEN_COMMANDS: Long = 1000

View File

@@ -0,0 +1,174 @@
package com.example.hpos.data.model;
import android.graphics.Bitmap;
public class AadharCard {
private String uuid;
private String name;
private String dateOfBirth;
private String gender;
private String careOf;
private String district;
private String landmark;
private String house;
private String location;
private String pinCode;
private String postOffice;
private String state;
private String street;
private String subDistrict;
private String vtc;
private Bitmap image;
private String email;
private String mobile;
private String signature;
public void setUuid(String aUuid){ name = aUuid; }
public void setName(String aName){ name = aName; }
public void setDateOfBirth(String aDateOfBirth){
dateOfBirth = aDateOfBirth;
}
public void setGender(String aGender){
gender = aGender;
}
public void setCareOf(String aCareOf){
careOf = aCareOf;
}
public void setDistrict(String aDistrict){
district = aDistrict;
}
public void setLandmark(String aLandmark){
landmark = aLandmark;
}
public void setHouse(String aHouse){
house = aHouse;
}
public void setLocation(String aLocation){ location = aLocation; }
public void setPinCode(String aPinCode){
pinCode = aPinCode;
}
public void setPostOffice(String aPostOffice){
postOffice = aPostOffice;
}
public void setState(String aState){
state = aState;
}
public void setStreet(String aStreet){
street = aStreet;
}
public void setSubDistrict(String aSubDistrict){
subDistrict = aSubDistrict;
}
public void setVtc(String aVtc){
vtc = aVtc;
}
public void setImage(Bitmap aImage){
image = aImage;
}
public void setEmail(String aEmail){
email = aEmail;
}
public void setMobile(String aMobile){
mobile = aMobile;
}
public void setSignature(String aSignature){
signature = aSignature;
}
public AadharCard(){
uuid = "";
name = "";
dateOfBirth = "";
gender = "";
careOf = "";
district = "";
landmark = "";
house = "";
location = "";
pinCode = "";
postOffice = "";
state = "";
street = "";
subDistrict = "";
vtc = "";
email = "";
mobile = "";
signature = "";
}
public String getName() {
return name;
}
public String getUuid() {
return uuid;
}
public String getDateOfBirth() {
return dateOfBirth;
}
public String getGender() {
return gender;
}
public String getCareOf() {
return careOf;
}
public String getDistrict() {
return district;
}
public String getLandmark() {
return landmark;
}
public String getHouse() {
return house;
}
public String getLocation() {
return location;
}
public String getPinCode() {
return pinCode;
}
public String getPostOffice() {
return postOffice;
}
public String getState() {
return state;
}
public String getStreet() {
return street;
}
public String getSubDistrict() {
return subDistrict;
}
public String getVtc() {
return vtc;
}
public Bitmap getImage() {
return image;
}
public String getEmail() {
return email;
}
public String getMobile() {
return mobile;
}
public String getSignature() {
return signature;
}
}

View File

@@ -1,41 +0,0 @@
package com.example.hpos.data.model
data class PatientAadhaarData(
val uuid: String?,
val name: String,
val gender: Gender,
val careOf: String,
val yob: String,
val address: Address,
val pinCode: String,
val mobile: String?,
val isMarried: Boolean?,
val bloodGroup: BloodGroup?,
) {
enum class Gender {
MALE,
FEMALE,
OTHER
}
enum class BloodGroup {
O_POSITIVE, O_NEGATIVE,
A_POSITIVE, A_NEGATIVE,
B_POSITIVE, B_NEGATIVE,
AB_POSITIVE, AB_NEGATIVE,
}
data class Address(
val house: String?,
val street: String?,
val location: String?,
val landMark: String?,
val postOffice: String?,
val district: String,
val subDistrict: String,
val state: String,
val vtc: String?,
val pinCode: Int,
)
}

View File

@@ -1,5 +1,7 @@
package com.example.hpos.data.model
import com.example.hpos.data.model.test.TestRightResultType
data class PatientData(
val name: String,
val age: Int,

View File

@@ -0,0 +1,76 @@
package com.example.hpos.data.model.patient
import java.util.Date
data class PatientDetails(
var id: String,
var isIdABHA: Boolean,
var name: String?,
var yob: Int?,
var gender: Gender?,
var mobile: String?,
var isUnderMedication: Boolean?,
var isUnderTransfusion: Boolean?,
val photoUrl: String?,
var careOf: String?,
var isMarried: Boolean?,
var bloodGroup: String?,
var address: Address?,
var category: Category?,
var registerDate: Date?,
val uploadDate: Date?
) {
constructor() : this(
"",
false,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null
)
enum class Gender {
MALE,
FEMALE,
OTHER
}
// enum class BloodGroup {
// O_POSITIVE, O_NEGATIVE,
// A_POSITIVE, A_NEGATIVE,
// B_POSITIVE, B_NEGATIVE,
// AB_POSITIVE, AB_NEGATIVE,
// }
data class Address(
var house: String?,
val street: String?,
var city: String?,
val landMark: String?,
var postOffice: String?,
var district: String?,
val subDistrict: String?,
var state: String?,
val vtc: String?,
var pinCode: Int?,
) {
constructor() : this(null, null, null, null, null, null, null, null, null, null)
}
enum class Category {
GENERAL,
OBC,
SC,
ST,
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,20 @@
package com.example.hpos.domain.AadhaarScanner;
/**
* QrCodeException wraps all the exceptions which occurs while scanning and decoding secure Aadharcard
* Qr Code
* @author Raj Deol
*/
public class QrCodeException extends Exception {
public QrCodeException(String message) {
super(message);
}
public QrCodeException(String message, Throwable cause) {
super(message, cause);
}
public QrCodeException(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,304 @@
package com.example.hpos.domain.AadhaarScanner;
import android.content.Context;
import android.util.Log;
import com.example.hpos.data.model.AadharCard;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.GZIPInputStream;
/**
* Class to decode scanned QRcode
*/
public class SecureQrCode {
protected Context mContext;
protected static final byte SEPARATOR_BYTE = (byte)255;
protected static final int REFERENCE_ID_INDEX = 1,
NAME_INDEX = 2,
DATE_OF_BIRTH_INDEX = 3,
GENDER_INDEX = 4,
CARE_OF_INDEX = 5,
DISTRICT_INDEX = 6,
LANDMARK_INDEX = 7,
HOUSE_INDEX = 8,
LOCATION_INDEX = 9,
PIN_CODE_INDEX = 10,
POST_OFFICE_INDEX = 11,
STATE_INDEX = 12,
STREET_INDEX = 13,
SUB_DISTRICT_INDEX = 14,
VTC_INDEX = 15;
protected int emailMobilePresent, imageStartIndex, imageEndIndex;
protected ArrayList<String> decodedData;
protected String signature,email,mobile;
protected AadharCard scannedAadharCard;
public SecureQrCode(Context activity, String scanData) throws QrCodeException{
mContext = activity;
scannedAadharCard = new AadharCard();
// 1. Convert Base10 to BigInt
final BigInteger bigIntScanData = new BigInteger(scanData,10);
// 2. Convert BigInt to Byte Array
final byte byteScanData[] = bigIntScanData.toByteArray();
// 3. Decompress Byte Array
final byte[] decompByteScanData = decompressData(byteScanData);
// 4. Split the byte array using delimiter
List<byte[]> parts = separateData(decompByteScanData);
// Throw error if there are no parts
if(parts.size() == 0){
throw new QrCodeException("Invalid QR Code Data, no parts found after splitting by delimiter");
}
// 5. decode extracted data to string
decodeData(parts);
// 6. Extract Signature
decodeSignature(decompByteScanData);
// 7. Email and Mobile number
decodeMobileEmail(decompByteScanData);
// 8. Extract Image
decodeImage(decompByteScanData);
Log.d("Rajdeol","Data Decoded");
}
/**
* Decompress the byte array, compression used is GZIP
* @param byteScanData compressed byte array
* @return uncompressed byte array
* @throws QrCodeException
*/
protected byte[] decompressData(byte[] byteScanData) throws QrCodeException {
ByteArrayOutputStream bos = new ByteArrayOutputStream(byteScanData.length);
ByteArrayInputStream bin = new ByteArrayInputStream(byteScanData);
GZIPInputStream gis = null;
try {
gis = new GZIPInputStream(bin);
} catch (IOException e) {
Log.e("Exception", "Decompressing QRcode, Opening byte stream failed: " + e.toString());
throw new QrCodeException("Error in opening Gzip byte stream while decompressing QRcode",e);
}
int size = 0;
byte[] buf = new byte[1024];
while (size >= 0) {
try {
size = gis.read(buf,0,buf.length);
if(size > 0){
bos.write(buf,0,size);
}
} catch (IOException e) {
Log.e("Exception", "Decompressing QRcode, writing byte stream failed: " + e.toString());
throw new QrCodeException("Error in writing byte stream while decompressing QRcode",e);
}
}
try {
gis.close();
bin.close();
} catch (IOException e) {
Log.e("Exception", "Decompressing QRcode, closing byte stream failed: " + e.toString());
throw new QrCodeException("Error in closing byte stream while decompressing QRcode",e);
}
return bos.toByteArray();
}
/**
* Function to split byte array with delimiter
* @param source source byte array
* @return list of separated byte arrays
*/
protected List<byte[]> separateData(byte[] source) {
List<byte[]> separatedParts = new LinkedList<>();
int begin = 0;
for (int i = 0; i < source.length; i++) {
if(source[i] == SEPARATOR_BYTE){
// skip if first or last byte is separator
if(i != 0 && i != (source.length -1)){
separatedParts.add(Arrays.copyOfRange(source, begin, i));
}
begin = i + 1;
// check if we have got all the parts of text data
if(separatedParts.size() == (VTC_INDEX + 1)){
// this is required to extract image data
imageStartIndex = begin;
break;
}
}
}
return separatedParts;
}
/**
* function to decode string values
* @param encodedData
* @throws QrCodeException
*/
protected void decodeData(List<byte[]> encodedData) throws QrCodeException{
Iterator<byte[]> i = encodedData.iterator();
decodedData = new ArrayList<String>();
while(i.hasNext()){
try {
decodedData.add(new String(i.next(), "ISO-8859-1"));
} catch (UnsupportedEncodingException e) {
Log.e("Exception", "Decoding QRcode, ISO-8859-1 not supported: " + e.toString());
throw new QrCodeException("Decoding QRcode, ISO-8859-1 not supported",e);
}
}
// set the value of email/mobile present flag
emailMobilePresent = Integer.parseInt(decodedData.get(0));
// populate decoded data
scannedAadharCard.setName(decodedData.get(2));
scannedAadharCard.setDateOfBirth(decodedData.get(3));
scannedAadharCard.setGender(decodedData.get(4));
scannedAadharCard.setCareOf(decodedData.get(5));
scannedAadharCard.setDistrict(decodedData.get(6));
scannedAadharCard.setLandmark(decodedData.get(7));
scannedAadharCard.setHouse(decodedData.get(8));
scannedAadharCard.setLocation(decodedData.get(9));
scannedAadharCard.setPinCode(decodedData.get(10));
scannedAadharCard.setPostOffice(decodedData.get(11));
scannedAadharCard.setState(decodedData.get(12));
scannedAadharCard.setStreet(decodedData.get(13));
scannedAadharCard.setSubDistrict(decodedData.get(14));
scannedAadharCard.setVtc(decodedData.get(15));
}
/**
* ref : https://uidai.gov.in/2-uncategorised/11320-aadhaar-paperless-offline-e-kyc-3.html
* Hashing logic for Email ID :
* Sha256(Sha256(Email+SharePhrase))*number of times last digit of Aadhaar number
* (Ref ID field contains last 4 digits).
*
* Example :
* Email: abc@gm.com
* Aadhaar Number:XXXX XXXX 3632
* Passcode : Lock@487
* Hash : Sha256(Sha256(abc@gm.comLock@487))*2
* In case of Aadhaar number ends with Zero we will hashed one time.
* **********************************************************************
* **********************************************************************
* Hashing logic for Mobile Number :
* Sha256(Sha256(Mobile+SharePhrase))*number of times last digit of Aadhaar number
* (Ref ID field contains last 4 digits).
*
* Example :
* Mobile: 1234567890
* Aadhaar Number:XXXX XXXX 3632
* Passcode : Lock@487
* Hash: Sha256(Sha256(1234567890Lock@487))*2
* In case of Aadhaar number ends with Zero we will hashed one time.
* @param decompressedData
* @throws QrCodeException
*/
protected void decodeMobileEmail(byte[] decompressedData) throws QrCodeException{
int mobileStartIndex = 0,mobileEndIndex = 0,emailStartIndex = 0,emailEndIndex = 0;
switch (emailMobilePresent){
case 3:
// both email mobile present
mobileStartIndex = decompressedData.length - 289; // length -1 -256 -32
mobileEndIndex = decompressedData.length - 257; // length -1 -256
emailStartIndex = decompressedData.length - 322;// length -1 -256 -32 -1 -32
emailEndIndex = decompressedData.length - 290;// length -1 -256 -32 -1
mobile = bytesToHex (Arrays.copyOfRange(decompressedData,mobileStartIndex,mobileEndIndex+1));
email = bytesToHex (Arrays.copyOfRange(decompressedData,emailStartIndex,emailEndIndex+1));
// set image end index, it will be used to extract image data
imageEndIndex = decompressedData.length - 323;
break;
case 2:
// only mobile
email = "";
mobileStartIndex = decompressedData.length - 289; // length -1 -256 -32
mobileEndIndex = decompressedData.length - 257; // length -1 -256
mobile = bytesToHex (Arrays.copyOfRange(decompressedData,mobileStartIndex,mobileEndIndex+1));
// set image end index, it will be used to extract image data
imageEndIndex = decompressedData.length - 290;
break;
case 1:
// only email
mobile = "";
emailStartIndex = decompressedData.length - 289; // length -1 -256 -32
emailEndIndex = decompressedData.length - 257; // length -1 -256
email = bytesToHex (Arrays.copyOfRange(decompressedData,emailStartIndex,emailEndIndex+1));
// set image end index, it will be used to extract image data
imageEndIndex = decompressedData.length - 290;
break;
default:
// no mobile or email
mobile = "";
email = "";
// set image end index, it will be used to extract image data
imageEndIndex = decompressedData.length - 257;
}
}
protected void decodeImage(byte[] decompressedData) throws QrCodeException{
// image start and end indexes are calculated in functions : separateData and decodeMobileEmail
byte[] imageBytes = Arrays.copyOfRange(decompressedData,imageStartIndex,imageEndIndex+1);
// Bitmap bmp = new JP2Decoder(imageBytes).decode();
// scannedAadharCard.setImage(bmp);
}
protected void decodeSignature(byte[] decompressedData) throws QrCodeException{
// extract 256 bytes from the end of the byte array
int startIndex = decompressedData.length - 257,
noOfBytes = 256;
try {
signature = new String (decompressedData,startIndex,noOfBytes,"ISO-8859-1");
} catch (UnsupportedEncodingException e) {
Log.e("Exception", "Decoding Signature of QRcode, ISO-8859-1 not supported: " + e.toString());
throw new QrCodeException("Decoding Signature of QRcode, ISO-8859-1 not supported",e);
}
}
public AadharCard getScannedAadharCard(){
return scannedAadharCard;
}
/**
* Convert byte array to hex string
* @param bytes
* @return
*/
public static String bytesToHex(byte[] bytes) {
final char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}

View File

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

View File

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

View File

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

View File

@@ -4,10 +4,7 @@ import android.util.Log
import com.example.hpos.data.LocalFileRepository
import com.example.hpos.data.constant.Constants
import com.example.hpos.data.model.PatientData
import com.example.hpos.data.model.TestRightCalculationData
import com.opencsv.CSVWriter
import java.io.File
import java.io.FileWriter
import com.example.hpos.data.model.test.TestRightCalculationData
import java.util.Collections.sort
class SaveRawData(private val localFileRepository: LocalFileRepository) {

View File

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

View File

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

View File

@@ -1,20 +0,0 @@
package com.example.hpos.presentation
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.hpos.R
class DashboardFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_dashboard, container, false)
}
}

View File

@@ -4,11 +4,9 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.util.Log
import android.view.Gravity
import android.view.Menu
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
@@ -18,7 +16,7 @@ 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.TestType
import com.example.hpos.data.model.test.TestType
import com.example.hpos.databinding.ActivityMainBinding
import com.example.hpos.presentation.testRight.TestRightActivity
import com.example.hpos.util.MyViewModelFactory
@@ -26,7 +24,6 @@ import com.hoho.android.usbserial.driver.UsbSerialProber
class MainActivity : AppCompatActivity()
// , SerialInputOutputManager.Listener
{
private lateinit var binding: ActivityMainBinding
@@ -67,6 +64,8 @@ class MainActivity : AppCompatActivity()
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
registerReceiver(mUsbReceiver, filter)
}
private fun checkAndUpdateUsbConnection() {
@@ -107,6 +106,13 @@ class MainActivity : AppCompatActivity()
myMenu?.get(0)?.icon = ContextCompat.getDrawable(this, R.drawable.ic_baseline_usb_off_24)
}
}
// TODO Scan: Remove this line
binding.cvItem3.setOnClickListener {
val i = Intent(applicationContext, TestRightActivity::class.java)
startActivity(i)
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {

View File

@@ -1,20 +0,0 @@
package com.example.hpos.presentation
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.hpos.R
class RegisterOneScanAbhaFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_register_one_scan_abha, container, false)
}
}

View File

@@ -8,32 +8,53 @@ import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.util.Log
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.hpos.data.DataHolder
import com.example.hpos.databinding.ActivitySplashBinding
import com.example.hpos.presentation.dashboard.DashboardActivity
import com.example.hpos.util.MyUtils
/**
* 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 permissionCamera = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySplashBinding.inflate(layoutInflater)
setContentView(binding.root)
checkForPermissions()
checkForStoragePermissions()
checkForLocationPermission()
// Keep this in last permission check, as checking all given or not after this
checkForCameraPermission()
// Log.d("surya_permission", "passed first")
checkAllPermissionsGiven()
}
private fun checkForPermissions() {
private fun checkAllPermissionsGiven() {
// Log.d("surya_permission", "inside checkAllPermissionsGiven")
if (permissionStorage && permissionCamera && permissionLocation)
moveToLandingPage()
}
private fun checkForStoragePermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
getPermissionsAboveAndroidR()
} else {
@@ -49,7 +70,8 @@ class SplashActivity : AppCompatActivity() {
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (Environment.isExternalStorageManager()) {
DataHolder.isStoragePermissionGranted = true
moveToLandingPage()
// moveToLandingPage()
permissionStorage = true
} else {
DataHolder.isStoragePermissionGranted = false
Toast.makeText(
@@ -66,7 +88,8 @@ class SplashActivity : AppCompatActivity() {
storagePermissionResultLauncher.launch(intent)
} else {
DataHolder.isStoragePermissionGranted = true
moveToLandingPage()
// moveToLandingPage()
permissionStorage = true
}
}
@@ -75,7 +98,8 @@ class SplashActivity : AppCompatActivity() {
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
if (isGranted) {
DataHolder.isStoragePermissionGranted = true
moveToLandingPage()
// moveToLandingPage()
permissionStorage = true
} else {
DataHolder.isStoragePermissionGranted = false
Toast.makeText(
@@ -97,19 +121,71 @@ class SplashActivity : AppCompatActivity() {
requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
} else {
DataHolder.isStoragePermissionGranted = true
moveToLandingPage()
// 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 moveToLandingPage() {
createAppFolder()
val i = Intent(applicationContext, MainActivity::class.java)
// 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){
if (folderPath != null) {
DataHolder.isAppFolderCreated = true
DataHolder.appFolderPath = folderPath
}

View File

@@ -0,0 +1,65 @@
package com.example.hpos.presentation.dashboard
import android.os.Bundle
import android.view.Menu
import com.google.android.material.navigation.NavigationView
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 androidx.drawerlayout.widget.DrawerLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import com.example.hpos.R
import com.example.hpos.databinding.ActivityDashboardBinding
import com.example.hpos.presentation.testRight.TestRightViewModel
import com.example.hpos.util.MyViewModelFactory
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)
binding = ActivityDashboardBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.appBarDashboard.toolbar)
val drawerLayout: DrawerLayout = binding.drawerLayout
val navView: NavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_content_dashboard)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_home, R.id.nav_profile, R.id.nav_settings
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
// val i = Intent(applicationContext, MainActivity::class.java)
// startActivity(i)
viewModel = ViewModelProvider(
this,
MyViewModelFactory(this.applicationContext)
)[DashboardViewModel::class.java]
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.dashboard, menu)
return true
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_dashboard)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}

View File

@@ -0,0 +1,55 @@
package com.example.hpos.presentation.dashboard
import androidx.lifecycle.ViewModel
import com.example.hpos.data.model.AadharCard
import com.example.hpos.data.model.patient.PatientDetails
import com.example.hpos.util.MyUtils.fetchYOBFromDOB
import com.example.hpos.util.MyUtils.mapToGender
class DashboardViewModel : ViewModel() {
lateinit var aadharCard: AadharCard
lateinit var patientDetails: PatientDetails
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()
}
}
// ------- Cloud Actions ------------------------------------------
fun pushPatientDetailsToCloud() {
// Synchronous Call Require
TODO("Not yet implemented")
}
fun createTest() {
TODO("Not yet implemented")
}
}

View File

@@ -0,0 +1,43 @@
package com.example.hpos.presentation.dashboard
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.example.hpos.databinding.FragmentGalleryBinding
import com.example.hpos.presentation.dashboard.ui.gallery.GalleryViewModel
class GalleryFragment : Fragment() {
private var _binding: FragmentGalleryBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val galleryViewModel =
ViewModelProvider(this).get(GalleryViewModel::class.java)
_binding = FragmentGalleryBinding.inflate(inflater, container, false)
val root: View = binding.root
val textView: TextView = binding.textGallery
galleryViewModel.text.observe(viewLifecycleOwner) {
textView.text = it
}
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,47 @@
package com.example.hpos.presentation.dashboard
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.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import com.example.hpos.R
import com.example.hpos.data.model.patient.PatientDetails
import com.example.hpos.databinding.FragmentHomeBinding
import com.example.hpos.presentation.dashboard.ui.home.HomeViewModel
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
private val viewModel: DashboardViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.btnAdd.setOnClickListener {
viewModel.initializePatientDetails(PatientDetails())
findNavController().navigate(R.id.action_nav_home_to_registerOneScanAbhaFragment)
}
binding.btnTest.setOnClickListener {
findNavController().navigate(R.id.action_nav_home_to_mainActivity)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,43 @@
package com.example.hpos.presentation.dashboard
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.example.hpos.databinding.FragmentSlideshowBinding
import com.example.hpos.presentation.dashboard.ui.slideshow.SlideshowViewModel
class SlideshowFragment : Fragment() {
private var _binding: FragmentSlideshowBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val slideshowViewModel =
ViewModelProvider(this).get(SlideshowViewModel::class.java)
_binding = FragmentSlideshowBinding.inflate(inflater, container, false)
val root: View = binding.root
val textView: TextView = binding.textSlideshow
slideshowViewModel.text.observe(viewLifecycleOwner) {
textView.text = it
}
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,70 @@
package com.example.hpos.presentation.dashboard.register
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import com.example.hpos.R
import com.example.hpos.data.constant.Constants
import com.example.hpos.databinding.FragmentRegisterOneCreateAbhaBinding
import com.example.hpos.presentation.dashboard.DashboardViewModel
class RegisterOneCreateAbha : Fragment() {
private val TAG = "RegisterOneCreateAbha"
private lateinit var binding: FragmentRegisterOneCreateAbhaBinding
private val viewModel: DashboardViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentRegisterOneCreateAbhaBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.btnRedirect.setOnClickListener {
redirectApp()
}
binding.tvSkip.setOnClickListener {
// Taking to aadhaar page if ABHA is skipped
findNavController().navigate(R.id.action_registerOneCreateAbha_to_registerTwoAadhaarFragment)
}
}
private fun redirectApp() {
val launchIntent: Intent? = requireActivity().packageManager
.getLaunchIntentForPackage(Constants.ABHA_APP_PACKAGE)
if (launchIntent != null) {
startActivity(launchIntent)
} else {
try {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=${Constants.ABHA_APP_PACKAGE}")))
} catch (e: ActivityNotFoundException) {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=${Constants.ABHA_APP_PACKAGE}")))
}
}
}
// private fun appInstalledOrNot(uri: String): Boolean {
// val pm: PackageManager = requireActivity().packageManager
// try {
// pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
// return true
// } catch (e: PackageManager.NameNotFoundException) {
// }
// return false
// }
}

View File

@@ -0,0 +1,172 @@
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.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
import java.lang.Exception
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)
binding.btnScanNow.setOnClickListener {
// Todo: Remove this, add later
// viewModel.patientDetails.name = "Surya"
// viewModel.patientDetails.gender = PatientDetails.Gender.MALE
// moveToRegisterThree()
startScanningNow()
}
binding.btnGo.setOnClickListener {
val abhaID = validateAndReturnId()
if (abhaID == null) {
Toast.makeText(requireContext(), "Invalid ID Entered", Toast.LENGTH_SHORT).show()
} else {
viewModel.patientDetails.id = abhaID
viewModel.patientDetails.isIdABHA = true
// Scan aadhaar card to get more details
moveToRegisterTwo()
}
}
binding.btnClickHere.setOnClickListener {
findNavController().navigate(R.id.action_registerOneScanAbhaFragment_to_registerOneCreateAbha)
}
}
private fun validateAndReturnId(): String? {
if (binding.nameEditText.text.isNullOrEmpty() || binding.nameEditText.text?.length != 14){
return null
}
return binding.nameEditText.text.toString()
}
private fun startScanningNow() {
val options = ScanOptions()
options.setDesiredBarcodeFormats(ScanOptions.QR_CODE)
options.setPrompt("Scan a barcode")
options.setCameraId(0) // Use a specific camera of the device
options.setBeepEnabled(true)
options.setBarcodeImageEnabled(true)
options.setPrompt("Start Scanning")
options.setOrientationLocked(false)
// options.setTimeout(10000) // in ms
barcodeLauncher.launch(options)
}
private fun processScannedData(contents: String) {
try {
val obj = JSONObject(contents)
// Log.d(TAG, obj.get("hidn").toString())
// Log.d(TAG, obj.get("name").toString())
// Log.d(TAG, obj.get("address").toString())
// Details mapping
viewModel.patientDetails.id = obj.get("hidn").toString().replace("-", "")
viewModel.patientDetails.isIdABHA = true
viewModel.patientDetails.name = obj.get("name").toString()
viewModel.patientDetails.gender = obj.get("gender").toString().mapToGender()
viewModel.patientDetails.yob = obj.get("dob").toString().fetchYOBFromDOB()
viewModel.patientDetails.mobile = obj.get("mobile").toString()
// Address mapping
viewModel.patientDetails.address = PatientDetails.Address()
viewModel.patientDetails.address!!.state = obj.get("state name").toString()
viewModel.patientDetails.address!!.district = obj.get("district_name").toString()
viewModel.patientDetails.address!!.house = obj.get("address").toString()
moveToRegisterThree()
} catch (e: Exception) {
Log.e(TAG, "Unable to parse json")
e.printStackTrace()
}
}
private fun moveToRegisterThree() {
findNavController().navigate(R.id.action_registerOneScanAbhaFragment_to_registerThreeEnterPatientDetails)
}
private fun moveToRegisterTwo() {
findNavController().navigate(R.id.action_registerOneScanAbhaFragment_to_registerTwoAadhaarFragment)
}
// fun String.mapToGender(): PatientDetails.Gender {
// if (this.lowercase() == "m"|| this.lowercase() == "male") {
// return PatientDetails.Gender.MALE
// } else if (this.lowercase() == "f"|| this.lowercase() == "female") {
// return PatientDetails.Gender.FEMALE
// } else {
// return PatientDetails.Gender.OTHER
// }
// }
private fun startScanningNow2() {
val options = GmsBarcodeScannerOptions.Builder()
.setBarcodeFormats(Barcode.FORMAT_QR_CODE)
.build()
val scanner = GmsBarcodeScanning.getClient(requireActivity(), options)
scanner.startScan()
.addOnSuccessListener { barcode ->
Log.d(TAG, barcode.rawValue!!)
}
.addOnCanceledListener {
// Task canceled
Log.d(TAG, "cancelled")
}
.addOnFailureListener { e ->
Log.d(TAG, "failed")
e.printStackTrace()
}
}
}

View File

@@ -0,0 +1,168 @@
package com.example.hpos.presentation.dashboard.register
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import com.example.hpos.R
import com.example.hpos.data.model.PatientData
import com.example.hpos.data.model.patient.PatientDetails
import com.example.hpos.databinding.FragmentRegisterOneScanAbhaBinding
import com.example.hpos.databinding.FragmentRegisterThreeEnterPatientDetailsBinding
import com.example.hpos.presentation.dashboard.DashboardViewModel
import com.example.hpos.util.MyUtils
import com.example.hpos.util.MyUtils.mapToCategory
import com.example.hpos.util.MyUtils.mapToGender
import com.example.hpos.util.MyUtils.mapYesNoStringToBool
import java.util.Calendar
class RegisterThreeEnterPatientDetails : Fragment() {
private val TAG = "RegisterThreeEnterPatientDetails"
private lateinit var binding: FragmentRegisterThreeEnterPatientDetailsBinding
private val viewModel: DashboardViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentRegisterThreeEnterPatientDetailsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
prefillTexts()
binding.btnSubmit.setOnClickListener {
val mPatient = validateAndReturnPatientData()
if(mPatient != null){
viewModel.patientDetails = mPatient
viewModel.pushPatientDetailsToCloud()
viewModel.createTest()
moveToNextPage()
} else {
Toast.makeText(requireContext(), "Fields can't be empty", Toast.LENGTH_SHORT).show()
}
}
}
private fun moveToNextPage() {
findNavController().navigate(R.id.action_registerThreeEnterPatientDetails_to_mainActivity)
}
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 {
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 {
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
}
}

View File

@@ -0,0 +1,124 @@
package com.example.hpos.presentation.dashboard.register
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
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 try again!!", Toast.LENGTH_SHORT).show()
}
}
private fun checkForIdThenMove() {
Log.d(TAG, "Inside: checkForIdThenMove()")
Log.d(TAG, "ID is ${viewModel.patientDetails.id}")
if (viewModel.patientDetails.id.isNullOrEmpty()){
binding.etAbhaId.error = getString(R.string.please_enter_aadhaar)
binding.btnScanNow.alpha = 0.2f
binding.btnScanNow.isEnabled = false
} else {
moveToRegisterThree()
}
}
private fun moveToRegisterThree() {
findNavController().navigate(R.id.action_registerTwoAadhaarFragment_to_registerThreeEnterPatientDetails)
}
}

View File

@@ -0,0 +1,13 @@
package com.example.hpos.presentation.dashboard.ui.gallery
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class GalleryViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is gallery Fragment"
}
val text: LiveData<String> = _text
}

View File

@@ -0,0 +1,13 @@
package com.example.hpos.presentation.dashboard.ui.home
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class HomeViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is home Fragment"
}
val text: LiveData<String> = _text
}

View File

@@ -0,0 +1,13 @@
package com.example.hpos.presentation.dashboard.ui.slideshow
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class SlideshowViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is slideshow Fragment"
}
val text: LiveData<String> = _text
}

View File

@@ -79,8 +79,13 @@ class TestRightActivity : AppCompatActivity() {
setSupportActionBar(binding.myToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
// TODO Scan: Remove this line
// supportFragmentManager.beginTransaction()
// .replace(binding.flMain.id, TestRightExpScanner()).commit()
setupListener()
// TODO Scan: uncomment this line
connectUsb(false)
}
@@ -149,7 +154,7 @@ class TestRightActivity : AppCompatActivity() {
this,
0,
Intent(Constants.ACTION_USB_PERMISSION),
PendingIntent.FLAG_ONE_SHOT
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
)
}

View File

@@ -16,8 +16,8 @@ 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.PatientData
import com.example.hpos.data.model.TestRightResultType
import com.example.hpos.data.model.TestType
import com.example.hpos.data.model.test.TestRightResultType
import com.example.hpos.data.model.test.TestType
import com.example.hpos.databinding.FragmentTestRightExpSampleBinding
import com.example.hpos.presentation.UsbServiceListener
import com.example.hpos.presentation.utils.MyDialogListener

View File

@@ -13,11 +13,10 @@ 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.TestRightResultType
import com.example.hpos.data.model.TestType
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.MainActivity
import com.example.hpos.util.MyUtils
import java.text.SimpleDateFormat
import java.util.*

View File

@@ -5,14 +5,14 @@ import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.hpos.data.DataHolder
import com.example.hpos.data.LocalFileRepository
import com.example.hpos.data.constant.Constants
import com.example.hpos.data.model.*
import com.example.hpos.data.model.test.TestRightCalculationData
import com.example.hpos.data.model.test.TestRightDeviceConstants
import com.example.hpos.domain.*
import com.example.hpos.util.MyUtils
import java.text.SimpleDateFormat
import java.util.*
import java.util.Collections.sort
import kotlin.collections.ArrayList
import kotlin.math.log10
import kotlin.math.pow

View File

@@ -3,7 +3,10 @@ package com.example.hpos.util
import android.content.Context
import android.os.Environment
import com.example.hpos.R
import com.example.hpos.data.model.patient.PatientDetails
import java.io.File
import java.net.InetAddress
object MyUtils {
@@ -22,4 +25,43 @@ object MyUtils {
}
}
fun isInternetConnected(): Boolean {
return try {
val ipAddr: InetAddress = InetAddress.getByName("google.com")
ipAddr.equals("hpos")
} catch (e: Exception) {
false
}
}
fun String.mapToGender(): PatientDetails.Gender {
return if (this.lowercase() == "m"|| this.lowercase() == "male") {
PatientDetails.Gender.MALE
} else if (this.lowercase() == "f"|| this.lowercase() == "female") {
PatientDetails.Gender.FEMALE
} else {
PatientDetails.Gender.OTHER
}
}
fun String.mapToCategory(): PatientDetails.Category {
return when (this.lowercase()){
"gen" -> PatientDetails.Category.GENERAL
"general" -> PatientDetails.Category.GENERAL
"obc" -> PatientDetails.Category.OBC
"sc" -> PatientDetails.Category.SC
"st" -> PatientDetails.Category.ST
else -> {PatientDetails.Category.GENERAL}
}
}
fun String.fetchYOBFromDOB(): Int {
val startIndex = if (this.length >= 4) this.length - 4 else 0
return this.substring(startIndex).toInt()
}
fun String.mapYesNoStringToBool(): Boolean {
return this.lowercase() == "yes"
}
}

View File

@@ -8,6 +8,7 @@ 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(private val context: Context) : ViewModelProvider.Factory {
@@ -18,8 +19,10 @@ class MyViewModelFactory(private val context: Context) : ViewModelProvider.Facto
else if (modelClass.isAssignableFrom(TestRightViewModel::class.java)) {
val repository = LocalFileRepository(LocalFileDataSource())
return TestRightViewModel(SaveRawData(repository), SaveRawDataTest(repository)) as T
}
else
} else if (modelClass.isAssignableFrom(DashboardViewModel::class.java)) {
// val repository = LocalFileRepository(LocalFileDataSource())
return DashboardViewModel() as T
} else
throw IllegalArgumentException("Unknown ViewModel class");
}
}