From 5deecc06fa47d0d54c6e673227717e315e138781 Mon Sep 17 00:00:00 2001 From: Aditya_WDI Date: Fri, 13 Oct 2023 20:50:37 +0530 Subject: [PATCH] . --- .idea/deploymentTargetDropDown.xml | 6 +- .../activities/CgProfileProgressActivity.java | 13 +- .../fragments/CgDashBoardFragment.java | 4 +- .../fragments/MyPatientFragment.java | 4 +- .../cg_geofencing/CgGeoFencingActivity.java | 230 +++++++++++++----- .../patient_dashboard/DashBoardActivity.java | 104 ++++---- .../PatientMainViewModel.java | 17 +- .../patient_dashboard/chats/ChatFragment.java | 2 +- .../patient_dashboard/chats/SocketHelper.java | 74 +++++- .../PatientLocationUpdatesReceiver.java | 127 +++++++++- .../ProfileProgressFragment.java | 61 ++++- .../res/layout/activity_cg_geofencing.xml | 6 +- .../layout/activity_cg_profile_progress.xml | 3 +- app/src/main/res/values/strings.xml | 4 +- 14 files changed, 512 insertions(+), 143 deletions(-) diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 7bd9a47..dc561cd 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -6,13 +6,13 @@ - - + + - + diff --git a/app/src/main/java/com/app/simplitend/caregiverdashboard/activities/CgProfileProgressActivity.java b/app/src/main/java/com/app/simplitend/caregiverdashboard/activities/CgProfileProgressActivity.java index cf0597c..c42e9ca 100644 --- a/app/src/main/java/com/app/simplitend/caregiverdashboard/activities/CgProfileProgressActivity.java +++ b/app/src/main/java/com/app/simplitend/caregiverdashboard/activities/CgProfileProgressActivity.java @@ -87,8 +87,8 @@ public class CgProfileProgressActivity extends AppCompatActivity implements CgHo progressDialog.setCancelable(false); progressDialog.show(); - viewModel.getGeoFenceDetails("", - careGiverData.caregiver_xid + "", + viewModel.getGeoFenceDetails(careGiverData.patientId + "", + "", "Bearer " + AppUtil.getCgToken(this), this); }); @@ -109,6 +109,15 @@ public class CgProfileProgressActivity extends AppCompatActivity implements CgHo gotoProfileShower(ACTIVITY_F); }); + binding.fua.setOnClickListener(v -> { + AppUtil.showAlert(this, + "App Whitelist", + "You can whitelist app from the patients device.", + getString(R.string.ok), + ((dialogInterface, i) -> {}), + null, null); + }); + } private void initViews() { diff --git a/app/src/main/java/com/app/simplitend/caregiverdashboard/fragments/CgDashBoardFragment.java b/app/src/main/java/com/app/simplitend/caregiverdashboard/fragments/CgDashBoardFragment.java index f10a015..294512e 100644 --- a/app/src/main/java/com/app/simplitend/caregiverdashboard/fragments/CgDashBoardFragment.java +++ b/app/src/main/java/com/app/simplitend/caregiverdashboard/fragments/CgDashBoardFragment.java @@ -336,8 +336,8 @@ public class CgDashBoardFragment extends Fragment implements progressDialog.setCancelable(false); progressDialog.show(); - viewModel.getGeoFenceDetails("", - careGiverData.caregiver_xid + "", + viewModel.getGeoFenceDetails(careGiverData.patientId + "", + "", "Bearer " + AppUtil.getCgToken(requireContext()), this); diff --git a/app/src/main/java/com/app/simplitend/caregiverdashboard/fragments/MyPatientFragment.java b/app/src/main/java/com/app/simplitend/caregiverdashboard/fragments/MyPatientFragment.java index 6addfc9..7328025 100644 --- a/app/src/main/java/com/app/simplitend/caregiverdashboard/fragments/MyPatientFragment.java +++ b/app/src/main/java/com/app/simplitend/caregiverdashboard/fragments/MyPatientFragment.java @@ -123,8 +123,8 @@ public class MyPatientFragment extends Fragment implements CgHomeContracts.GetGe progressDialog.setCancelable(false); progressDialog.show(); - viewModel.getGeoFenceDetails("", - careGiverData.caregiver_xid + "", + viewModel.getGeoFenceDetails(careGiverData.patientId + "", + "", "Bearer " + AppUtil.getCgToken(requireContext()), this); diff --git a/app/src/main/java/com/app/simplitend/cg_geofencing/CgGeoFencingActivity.java b/app/src/main/java/com/app/simplitend/cg_geofencing/CgGeoFencingActivity.java index c04da7b..8adc02e 100644 --- a/app/src/main/java/com/app/simplitend/cg_geofencing/CgGeoFencingActivity.java +++ b/app/src/main/java/com/app/simplitend/cg_geofencing/CgGeoFencingActivity.java @@ -1,13 +1,17 @@ package com.app.simplitend.cg_geofencing; +import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_REQUEST_TAG; + import android.app.Activity; -import android.app.PendingIntent; import android.app.ProgressDialog; import android.content.Intent; import android.graphics.Color; import android.location.Address; import android.location.Geocoder; +import android.location.Location; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.util.Log; import android.view.View; import android.widget.Toast; @@ -26,6 +30,7 @@ import com.app.simplitend.caregiverdashboard.mvvm.CgHomeContracts; import com.app.simplitend.caregiverdashboard.mvvm.models.GeoFenceDetails; import com.app.simplitend.databinding.ActivityCgGeofencingBinding; import com.app.simplitend.databinding.GeofenceBottomSheetBinding; +import com.app.simplitend.patient_dashboard.chats.SocketHelper; import com.app.simplitend.welcome.welcomecg.mvvm.CareGiverData; import com.app.simplitend.welcome.welcomepatient.mvvm.models.PatientData; import com.google.android.gms.maps.CameraUpdateFactory; @@ -33,8 +38,10 @@ import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; +import com.google.android.gms.maps.model.Circle; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.libraries.places.api.Places; import com.google.android.libraries.places.api.model.Place; @@ -74,11 +81,15 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead private GoogleMap mMap; - private LatLng mLatLng, pat_cur_latLng; + private LatLng mHomeLatLng, pat_cur_latLng; private ActivityResultLauncher startAutocompleteMapSearch; private ProgressDialog progressDialog; + private Marker curr_loc_marker; + private Marker home_loc_marker; + + private Circle radius_circle; @Override protected void onCreate(Bundle savedInstanceState) { @@ -96,7 +107,7 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead try { pat_cur_latLng = new LatLng(Double.parseDouble(geoFenceDetails.patient_radius_location.lat), Double.parseDouble(geoFenceDetails.patient_radius_location.lng)); - }catch (Exception e){ + } catch (Exception e) { pat_cur_latLng = null; } } catch (Exception e) { @@ -126,6 +137,58 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead clickEvents(); + updatePatientCurrentLocationDetails(); + + establishSocketConnection(); + + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (careGiverData != null) { + SocketHelper.getInstance().removeLocationUpdateListener(careGiverData.patientId+""); + } + + SocketHelper.getInstance().closeConnection(); + } + + private void establishSocketConnection() { + CaregiverDataCache.getCaregiverData(this, (careGiverData1 -> { + if (careGiverData1 != null){ + this.careGiverData = careGiverData1; + + SocketHelper socketHelper = SocketHelper.getInstance(); + socketHelper.establishConnection(null); + + Log.d(LOCATION_REQUEST_TAG, "CG STARTED LISTENING TO LOCATION UPDATES"); + socketHelper.getLocationUpdates(careGiverData1.patientId+"", new SocketHelper.Callback() { + @Override + public void onMessageReceived(Location result) { + Log.d(LOCATION_REQUEST_TAG, "LOCATION RECEIVED: " + result); + if (result != null){ + pat_cur_latLng = new LatLng(result.getLatitude(), result.getLongitude()); + + // running on main thread + new Handler(Looper.getMainLooper()).post(()-> { + updateCurrentLocationPatientMarker(); + updatePatientCurrentLocationDetails(); + }); + } + } + + @Override + public void onMessageSentSuccessfully() { + + } + + @Override + public void onError(Exception e) { + Log.e(LOCATION_REQUEST_TAG, "CG LISTENING TO LOCATION UPDATES", e); + } + }); + } + }), false); } private void initBottomSheet() { @@ -137,18 +200,18 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead if (geoFenceDetails == null) return; float radius = 0.0f; - if (geoFenceDetails.radius != null){ + if (geoFenceDetails.radius != null) { try { radius = Float.parseFloat(geoFenceDetails.radius); - }catch (Exception e){ + } catch (Exception e) { // do nothing } } - if (MILES.equals(geoFenceDetails.type)){ + if (MILES.equals(geoFenceDetails.type)) { geofence_bs_binding.unitSpinner.selectItemByIndex(1); radius = radius / 1609.34f; - }else{ + } else { geofence_bs_binding.unitSpinner.selectItemByIndex(0); radius = radius / 1000f; } @@ -156,7 +219,7 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead geofence_bs_binding.unitSpinner.setLifecycleOwner(this); geofence_bs_binding.unitSpinner.setIsFocusable(true); - if (radius != 0){ + if (radius != 0) { geofence_bs_binding.radius.setText("" + radius); } geofence_bs_binding.message.setText(geoFenceDetails.message); @@ -187,7 +250,7 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead }); geofence_bs_binding.save.setOnClickListener(v -> { - if (allOkay()){ + if (allOkay()) { saveGeoFence(); } }); @@ -208,21 +271,54 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead }); binding.updateBtn.setOnClickListener(v -> { - if (careGiverData != null){ + if (careGiverData != null) { updatePatientAddress(); - }else{ + } else { Toast.makeText(this, "Cannot update address.", Toast.LENGTH_SHORT).show(); } }); } + private void updatePatientCurrentLocationDetails() { + if (patientData == null) return; + + try { + if (pat_cur_latLng != null){ + // calculating distance + LatLng homeLatLng = new LatLng(Double.parseDouble(patientData.lat), + Double.parseDouble(patientData.lng)); + + Location homeL = new Location("homeL"); + homeL.setLatitude(homeLatLng.latitude); + homeL.setLongitude(homeLatLng.longitude); + + Location currL = new Location("currL"); + currL.setLatitude(pat_cur_latLng.latitude); + currL.setLongitude(pat_cur_latLng.longitude); + + double distance = homeL.distanceTo(currL); + distance /= 1000; // converting to KMs + if (distance <= 0.015){ + binding.distanceAwayTxt.setText(patientData.first_name + " is at Home"); + }else{ + binding.distanceAwayTxt.setText(String.format(patientData.first_name + " is %.2f Kms away", distance)); + } + } + } catch (NumberFormatException e) { + // do nothing + } + + String address = patientData.address_line1; + binding.homeAddress.setText(address); + } + private void updatePatientAddress() { - if (this.mLatLng == null) return; + if (this.mHomeLatLng == null) return; try { // fetching address from the lag lng Geocoder geocoder = new Geocoder(this, Locale.getDefault()); - List
addresses = geocoder.getFromLocation(mLatLng.latitude, mLatLng.longitude, 1); + List
addresses = geocoder.getFromLocation(mHomeLatLng.latitude, mHomeLatLng.longitude, 1); if (addresses != null && addresses.size() > 0 && addresses.get(0) != null) { Address address = addresses.get(0); @@ -234,18 +330,18 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead Map body = new HashMap<>(); - body.put("town", (address.getSubLocality() != null?address.getSubLocality():address.getLocality())); - body.put("street", (address.getSubThoroughfare() != null?address.getSubThoroughfare():address.getThoroughfare())); + body.put("town", (address.getSubLocality() != null ? address.getSubLocality() : address.getLocality())); + body.put("street", (address.getSubThoroughfare() != null ? address.getSubThoroughfare() : address.getThoroughfare())); body.put("state", address.getAdminArea()); body.put("country", address.getCountryName()); - body.put("zip_code",address.getPostalCode()); - body.put("lat", this.mLatLng.latitude + ""); - body.put("lng", this.mLatLng.longitude + ""); + body.put("zip_code", address.getPostalCode()); + body.put("lat", this.mHomeLatLng.latitude + ""); + body.put("lng", this.mHomeLatLng.longitude + ""); viewModel.updatePatientAddress(careGiverData.patientId, body, "Bearer " + AppUtil.getCgToken(this), this); - }else { + } else { Toast.makeText(this, "Couldn't load address.", Toast.LENGTH_SHORT).show(); } @@ -260,12 +356,12 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead geofence_bs_binding.location.setError(null); boolean allOkay = true; - if (geofence_bs_binding.message.getText().toString().trim().isEmpty()){ + if (geofence_bs_binding.message.getText().toString().trim().isEmpty()) { allOkay = false; geofence_bs_binding.message.setError("Required"); } - if (geofence_bs_binding.location.getText().toString().trim().isEmpty()){ + if (geofence_bs_binding.location.getText().toString().trim().isEmpty()) { allOkay = false; geofence_bs_binding.location.setError("Required"); } @@ -298,7 +394,7 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead if (radius < 1000) { Toast.makeText(this, "Radius should be minimum 1 KM.", Toast.LENGTH_SHORT).show(); return; - }else if (radius > 10_000){ + } else if (radius > 10_000) { Toast.makeText(this, "Radius should be maximum 10 KM.", Toast.LENGTH_SHORT).show(); return; } @@ -306,7 +402,7 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead geoFenceDetails.message = geofence_bs_binding.message.getText().toString(); geoFenceDetails.location_name = geofence_bs_binding.location.getText().toString(); geoFenceDetails.radius = "" + radius; - geoFenceDetails.type = geofence_bs_binding.unitSpinner.getSelectedIndex() == 0?KMS:MILES; + geoFenceDetails.type = geofence_bs_binding.unitSpinner.getSelectedIndex() == 0 ? KMS : MILES; geoFenceDetails.patient_xid = "" + careGiverData.patientId; geoFenceDetails.caregiver_xid = "" + careGiverData.caregiver_xid; @@ -321,16 +417,18 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead } - private void addCircle(float radius) { + private void addRadius(float radius) { if (mMap == null) return; CircleOptions circleOptions = new CircleOptions(); - circleOptions.center(mLatLng); + circleOptions.center(mHomeLatLng); circleOptions.radius(radius); circleOptions.strokeWidth(0); circleOptions.fillColor(Color.argb(150, 167, 205, 242)); - mMap.addCircle(circleOptions); + if (radius_circle != null) radius_circle.remove(); + + radius_circle = mMap.addCircle(circleOptions); bottomSheetDialog.dismiss(); } @@ -353,18 +451,37 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead loadPatientsLocation(); + updateCurrentLocationPatientMarker(); + mMap.setOnMapClickListener(latLng1 -> { - this.mLatLng = latLng1; + this.mHomeLatLng = latLng1; binding.updateBtnsView.setVisibility(View.VISIBLE); - addMarker(this.mLatLng); - addCircle(); + updateHomeMarker(this.mHomeLatLng); + addRadius(); }); } + private void updateCurrentLocationPatientMarker() { + if (pat_cur_latLng != null){ + String name; + if (patientData != null) name = patientData.first_name; + else name = "Senior's location"; + + MarkerOptions options = new MarkerOptions() + .position(pat_cur_latLng) + .icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location)) + .title(name) + .draggable(false); + + if (curr_loc_marker != null) curr_loc_marker.remove(); + curr_loc_marker = mMap.addMarker(options); + } + } + private void loadPatientsLocation() { - LatLng latLng; + LatLng home_lat_lng; // loading patient's location try { @@ -373,54 +490,44 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead double lat = Double.parseDouble(patientData.lat); double lng = Double.parseDouble(patientData.lng); - latLng = new LatLng(lat, lng); - addMarker(latLng); - addCircle(); + home_lat_lng = new LatLng(lat, lng); + updateHomeMarker(home_lat_lng); + addRadius(); + + mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home_lat_lng, 13)); } catch (Exception e) { // near marine drive - latLng = new LatLng(18.93294274664527, 72.82806102186441); + Toast.makeText(this, "Couldn't load home location", Toast.LENGTH_SHORT).show(); } - - mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 13)); } - private void addCircle() { + private void addRadius() { try { - if (geoFenceDetails.radius != null){ + if (geoFenceDetails.radius != null) { float radius = Float.parseFloat(geoFenceDetails.radius); - addCircle(radius); + addRadius(radius); } - }catch (Exception e){ + } catch (Exception e) { Log.e(TAG, "onMapReady: ", e); Toast.makeText(this, "Couldn't load geofence.", Toast.LENGTH_SHORT).show(); } } - private void addMarker(@NonNull LatLng latLng) { + private void updateHomeMarker(@NonNull LatLng home_latLng) { if (mMap == null || patientData == null) return; - this.mLatLng = latLng; - mMap.clear(); + this.mHomeLatLng = home_latLng; MarkerOptions markerOptions = new MarkerOptions() - .position(latLng) + .position(home_latLng) .draggable(false) .icon(BitmapDescriptorFactory.fromResource(R.drawable.img_home_marker)) .title("Home location"); - mMap.addMarker(markerOptions); + if (home_loc_marker != null) home_loc_marker.remove(); - if (pat_cur_latLng != null){ - MarkerOptions pat_cur_marker = new MarkerOptions() - .position(pat_cur_latLng) - .draggable(false) - .icon(BitmapDescriptorFactory.fromResource(R.drawable.img_pat_curr_location)) - .title(patientData.first_name + ""); - - mMap.addMarker(pat_cur_marker); - } - - mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 13)); + home_loc_marker = mMap.addMarker(markerOptions); + mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(home_latLng, 13)); } private void registerMapSearchResultLauncher() { @@ -440,12 +547,12 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead if (place.getLatLng() == null) return; - this.mLatLng = place.getLatLng(); + this.mHomeLatLng = place.getLatLng(); binding.updateBtnsView.setVisibility(View.VISIBLE); - addMarker(this.mLatLng); - addCircle(); + updateHomeMarker(this.mHomeLatLng); + addRadius(); } } }); @@ -458,8 +565,8 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead bottomSheetDialog.dismiss(); - addMarker(mLatLng); - addCircle(); + updateHomeMarker(mHomeLatLng); + addRadius(); } @Override @@ -475,6 +582,7 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead this.patientData = patientData; CaregiverDataCache.setCareGiverData(this.careGiverData); progressDialog.dismiss(); + updatePatientCurrentLocationDetails(); Toast.makeText(this, "Patient's location updated.", Toast.LENGTH_SHORT).show(); } diff --git a/app/src/main/java/com/app/simplitend/patient_dashboard/DashBoardActivity.java b/app/src/main/java/com/app/simplitend/patient_dashboard/DashBoardActivity.java index 6ee5e1c..645974b 100644 --- a/app/src/main/java/com/app/simplitend/patient_dashboard/DashBoardActivity.java +++ b/app/src/main/java/com/app/simplitend/patient_dashboard/DashBoardActivity.java @@ -1,16 +1,18 @@ package com.app.simplitend.patient_dashboard; import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG; -import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_REQUEST_TAG; import android.Manifest; import android.app.role.RoleManager; import android.content.Intent; import android.content.pm.PackageManager; +import android.os.Build; import android.os.Bundle; import android.telecom.TelecomManager; import android.util.Log; +import android.widget.Toast; +import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; @@ -26,10 +28,9 @@ import com.app.simplitend.caregiverdashboard.mvvm.models.GeoFenceDetails; public class DashBoardActivity extends AppCompatActivity implements CgHomeContracts.GetGeoFenceCallback { protected PatientMainViewModel viewModel; - public static final int LOCATION_REQUEST_CODE = 1001; - public static final int LOCATION_REQUEST_CODE_2 = 2002; - private GeoFenceDetails geoFenceDetails; + protected ActivityResultLauncher finePermissionLauncher; + protected ActivityResultLauncher backgroundPermissionLauncher; @Override protected void onCreate(Bundle savedInstanceState) { @@ -38,17 +39,56 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra viewModel = new ViewModelProvider(this).get(PatientMainViewModel.class); + finePermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), + isGranted -> { + if (isGranted) { + // fine location permission is granted + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + if (checkSelfPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED){ + AppUtil.showSOSDecision(this, + "To enable caregivers to receive notifications even when the app is closed, go to the settings menu and select allow all the time", + "Settings", "No thanks", view -> { + // Settings click + backgroundPermissionLauncher.launch(Manifest.permission.ACCESS_BACKGROUND_LOCATION); + }, view -> { + // No thanks click + Toast.makeText(this, "Geofencing is off.", Toast.LENGTH_SHORT).show(); + }); + }else{ + setGeofenceAndLocationUpdates(); + } + } else { + setGeofenceAndLocationUpdates(); + } + } else { + // permission denied + AppUtil.showAlert(this, + "We understand your privacy", + "To connect you with your guardian allow SimpliTend to access your location", + "Allow", + ((dialogInterface, i) -> { + finePermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION); + }), null, null); + } + }); + + backgroundPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), + isGranted -> { + if (isGranted) { + setGeofenceAndLocationUpdates(); + } + }); + registerForActivityResult(new ActivityResultContracts.RequestPermission(), result -> { // reigstering geofencing - viewModel.getGeoFenceDetails(AppUtil.getPatientUid(this) + "", - "", "Bearer " + AppUtil.getPatientToken(this), - this); + // thus, asking for permission + finePermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION); if (result) { // permission granted - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { RoleManager roleManager = getSystemService(RoleManager.class); Intent i = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_SCREENING); startActivityForResult(i, 1214, null); @@ -61,6 +101,19 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra }).launch(Manifest.permission.READ_CONTACTS); } + private void setGeofenceAndLocationUpdates() { + // retrieving geofence + viewModel.getGeoFenceDetails(AppUtil.getPatientUid(this) + "", + "", "Bearer " + AppUtil.getPatientToken(this), + this); + + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + + viewModel.addLocationUpdates(this); + } + private void validateAndAddGeofence(GeoFenceDetails geoFenceDetails) { if (geoFenceDetails.radius != null && geoFenceDetails.type != null) { PatientDataCache.getPatientData(this, (patientData -> { @@ -76,22 +129,10 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra }), false); } - if (geoFenceDetails.patient_radius_location != null) { - if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { - Log.d(LOCATION_REQUEST_TAG, "addLocationUpdates: REQUESTING FINE LOCATION PERMISSION"); - ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE_2); - return; - } - - viewModel.addLocationUpdates(this); - } - - } @Override public void onGeofenceDetailsFetched(@NonNull GeoFenceDetails geoFenceDetails) { - this.geoFenceDetails = geoFenceDetails; validateAndAddGeofence(geoFenceDetails); } @@ -100,27 +141,4 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra Log.d(GEOFENCE_TAG, "onGeofenceDetailsFetchFailed: " + message); } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - if (requestCode == LOCATION_REQUEST_CODE) { - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - Log.d(GEOFENCE_TAG, "onRequestPermissionsResult: PERMISSION GRANTED"); - if (geoFenceDetails != null) { - validateAndAddGeofence(geoFenceDetails); - } - } - } else if (requestCode == LOCATION_REQUEST_CODE_2) { - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - Log.d(LOCATION_REQUEST_TAG, "onRequestPermissionsResult: PERMISSION GRANTED"); - - if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { - return; - } - - viewModel.addLocationUpdates(this); - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/app/simplitend/patient_dashboard/PatientMainViewModel.java b/app/src/main/java/com/app/simplitend/patient_dashboard/PatientMainViewModel.java index a477898..90d3de2 100644 --- a/app/src/main/java/com/app/simplitend/patient_dashboard/PatientMainViewModel.java +++ b/app/src/main/java/com/app/simplitend/patient_dashboard/PatientMainViewModel.java @@ -1,6 +1,5 @@ package com.app.simplitend.patient_dashboard; -import static com.app.simplitend.patient_dashboard.DashBoardActivity.LOCATION_REQUEST_CODE; import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_ID; import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG; import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_REQUEST_TAG; @@ -15,7 +14,6 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.util.Log; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.RequiresPermission; @@ -91,8 +89,7 @@ public class PatientMainViewModel extends ViewModel { if (latLng != null && radius != 0) { if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { - Log.d(GEOFENCE_TAG, "setGeofence: REQUESTING FINE LOCATION PERMISSION" ); - ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); + Log.d(GEOFENCE_TAG, "setGeofence: NO FINE LOCATION PERMISSION" ); return; } @@ -146,17 +143,7 @@ public class PatientMainViewModel extends ViewModel { // checking for background location updates for API level 29 and above if (Build.VERSION.SDK_INT >= 29) { if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) { - Log.d(GEOFENCE_TAG, "setGeofence: REQUESTING BACKGROUND LOCATION PERMISSION" ); - AppUtil.showSOSDecision(activity, - "To enable caregivers to receive notifications even when the app is closed, go to the settings menu and select allow all the time", - "Settings", "No thanks", view -> { - // No thanks click - ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, LOCATION_REQUEST_CODE); - }, view -> { - // Settings click - Toast.makeText(activity, "Geofencing is off.", Toast.LENGTH_SHORT).show(); - Log.d(GEOFENCE_TAG, "setGeofence: User chose not to allow background location."); - }); + Log.d(GEOFENCE_TAG, "setGeofence: NO BACKGROUND PERMISSION" ); return; } } diff --git a/app/src/main/java/com/app/simplitend/patient_dashboard/chats/ChatFragment.java b/app/src/main/java/com/app/simplitend/patient_dashboard/chats/ChatFragment.java index 609e28f..ff07a28 100644 --- a/app/src/main/java/com/app/simplitend/patient_dashboard/chats/ChatFragment.java +++ b/app/src/main/java/com/app/simplitend/patient_dashboard/chats/ChatFragment.java @@ -68,7 +68,7 @@ public class ChatFragment extends Fragment implements SocketHelper.Callback callback){ + mSocket.on(LOCATION_EVENT_PREFIX + patient_id, new Emitter.Listener() { + @Override + public void call(Object... args) { + try { + if (args.length >= 2) { + String received_lat = (String) args[0]; + String received_lng = (String) args[1]; + + try { + Location location = new Location("received_location"); + location.setLatitude(Double.parseDouble(received_lat)); + location.setLongitude(Double.parseDouble(received_lng)); + + if (callback != null){ + callback.onMessageReceived(location); + } + }catch (Exception e){ + if (callback != null){ + callback.onError(e); + } + } + + if (callback != null) { + callback.onMessageSentSuccessfully(); + } + }else{ + if (callback != null) { + callback.onError(new Exception("LOCATION UPDATES RECEIVED WITH INVALID ARGS " + args)); + } + } + } catch (Exception e) { + if (callback != null){ + callback.onError(e); + } + } + } + }); + } + + public void removeLocationUpdateListener(String patientId) { + mSocket.off(LOCATION_EVENT_PREFIX+patientId); + } + public interface Callback { void onMessageReceived(T result); void onMessageSentSuccessfully(); void onError(Exception e); } + + public interface SockCallBack{ + void onSocketConnected(); + void onConnectionError(Exception e); + void onDisconnected(); + } } diff --git a/app/src/main/java/com/app/simplitend/patientgeofencing/PatientLocationUpdatesReceiver.java b/app/src/main/java/com/app/simplitend/patientgeofencing/PatientLocationUpdatesReceiver.java index 4d797f0..cb1678d 100644 --- a/app/src/main/java/com/app/simplitend/patientgeofencing/PatientLocationUpdatesReceiver.java +++ b/app/src/main/java/com/app/simplitend/patientgeofencing/PatientLocationUpdatesReceiver.java @@ -4,17 +4,29 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.location.Location; -import android.location.LocationManager; -import android.os.Bundle; +import android.os.AsyncTask; import android.util.Log; +import androidx.annotation.NonNull; + +import com.app.simplitend.apputils.AppUtil; +import com.app.simplitend.apputils.RetrofitHelper; +import com.app.simplitend.patient_dashboard.chats.SocketHelper; +import com.app.simplitend.patientprofile.PatientProfileAPIService; +import com.app.simplitend.welcome.welcomepatient.mvvm.models.CallResponse; import com.google.maps.model.LatLng; +import java.util.HashMap; +import java.util.Map; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + public class PatientLocationUpdatesReceiver extends BroadcastReceiver { public static final String LOCATION_REQUEST_TAG = "LOCATION_REQUEST_TAG"; private static final String LOCATION_EXTRA_KEY = "com.google.android.location.LOCATION"; - public static final int LOCATION_UPDATES_REQUEST_CODE = 1010; @Override @@ -22,9 +34,116 @@ public class PatientLocationUpdatesReceiver extends BroadcastReceiver { Log.d(LOCATION_REQUEST_TAG, "LOCATION UPDATE RECEIVED"); Location location = intent.getParcelableExtra(LOCATION_EXTRA_KEY); if (location != null) { - Log.d(LOCATION_REQUEST_TAG, new LatLng(location.getLatitude(), location.getLongitude()).toString()); + LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); + Log.d(LOCATION_REQUEST_TAG, "lat/lng: " + latLng); + + int patient_id = AppUtil.getPatientUid(context); + String token = AppUtil.getPatientToken(context); + if (patient_id != -1 && token != null){ + updateRemoteCurrLocation(location, patient_id, + "Bearer " + token); + }else{ + Log.e(LOCATION_REQUEST_TAG, "CANNOT UPDATE REMOTE LOCATION AS PATIENT_ID OR TOKEN IS -1 OR NULL RESP." ); + } }else{ Log.e(LOCATION_REQUEST_TAG, "LOCATION RECEIVED IS NULL"); } } + + private void updateRemoteCurrLocation(@NonNull Location location, int patient_id, + @NonNull String token) { + PatientProfileAPIService apiService = RetrofitHelper.getRetrofit().create(PatientProfileAPIService.class); + + Map body = new HashMap<>(); + body.put("patient_id", patient_id+""); + body.put("lat", location.getLatitude() + ""); + body.put("lng", location.getLongitude() + ""); + + apiService.updatePatientCurrLocation(body, token) + .enqueue(new Callback>() { + @Override + public void onResponse(Call> call, Response> response) { + if (response.body() != null){ + if (response.code() == 200 && response.body().error_code == 0){ + Log.d(LOCATION_REQUEST_TAG, "LOCATION REMOTE UPDATED."); + }else{ + Log.e(LOCATION_REQUEST_TAG, "LOCATION REMOTE UPDATE FAILED" + response.body().message); + } + }else{ + Log.e(LOCATION_REQUEST_TAG, "LOCATION REMOTE UPDATE FAILED" + response.message()); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + Log.e(LOCATION_REQUEST_TAG, "LOCATION REMOTE UPDATE FAILED", t); + } + }); + + new UpdateRemoteLocationTask(patient_id + "").execute(location); + } + + public static class UpdateRemoteLocationTask extends AsyncTask{ + @NonNull + private final String patientId; + + public UpdateRemoteLocationTask(@NonNull String patientId){ + this.patientId = patientId; + } + + @Override + protected Void doInBackground(Location... locations) { + SocketHelper socketHelper = SocketHelper.getInstance(); + + if (socketHelper.isConnected()){ + Log.d(LOCATION_REQUEST_TAG, "doInBackground: ALREADY CONNECTED TO SOCKET"); + socketHelper.getLocationUpdates(patientId, null); + socketHelper.sendLocationUpdates(locations[0], patientId); + }else{ + Log.d(LOCATION_REQUEST_TAG, "doInBackground: CONNECTING TO SOCKET"); + socketHelper.getLocationUpdates(patientId, new SocketHelper.Callback() { + @Override + public void onMessageReceived(Location result) { + Log.d(LOCATION_REQUEST_TAG, "LOCATION SENT " + result); + socketHelper.removeLocationUpdateListener(patientId); + socketHelper.closeConnection(); + } + + @Override + public void onMessageSentSuccessfully() { + socketHelper.removeLocationUpdateListener(patientId); + socketHelper.closeConnection(); + } + + @Override + public void onError(Exception e) { + Log.e(LOCATION_REQUEST_TAG, "LOCATION SENDING PROBLEM", e); + socketHelper.removeLocationUpdateListener(patientId); + socketHelper.closeConnection(); + } + }); + + socketHelper.establishConnection(new SocketHelper.SockCallBack() { + @Override + public void onSocketConnected() { + Log.d(LOCATION_REQUEST_TAG, "doInBackground: SOCKET CONNECTED"); + socketHelper.sendLocationUpdates(locations[0], patientId); + } + + @Override + public void onConnectionError(Exception e) { + Log.d(LOCATION_REQUEST_TAG, "doInBackground: SOCKET CONNECTION ERROR"); + } + + @Override + public void onDisconnected() { + Log.d(LOCATION_REQUEST_TAG, "doInBackground: SOCKET DISCONNECTED"); + } + }); + + } + + return null; + } + } } diff --git a/app/src/main/java/com/app/simplitend/patientprofile/ProfileProgressFragment.java b/app/src/main/java/com/app/simplitend/patientprofile/ProfileProgressFragment.java index a76c6a5..7d5d4e2 100644 --- a/app/src/main/java/com/app/simplitend/patientprofile/ProfileProgressFragment.java +++ b/app/src/main/java/com/app/simplitend/patientprofile/ProfileProgressFragment.java @@ -6,6 +6,9 @@ import static com.app.simplitend.patientprofile.RegisterCompleteFragment.PROFILE import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; +import android.provider.Settings; +import android.text.TextUtils; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -18,6 +21,7 @@ import androidx.navigation.Navigation; import com.app.simplitend.R; import com.app.simplitend.appblocking.FUAActivity; +import com.app.simplitend.appblocking.TopAppDetectionService; import com.app.simplitend.apputils.AppUtil; import com.app.simplitend.apputils.RetrofitHelper; import com.app.simplitend.databinding.ProfileProgressFragmentBinding; @@ -35,7 +39,7 @@ public class ProfileProgressFragment extends Fragment implements ProfileContract private ProgressDialog progressDialog; - int profile_progress, is_connected_to_caregiver; + private int profile_progress, is_connected_to_caregiver; public ProfileProgressFragment() { // required empty const. @@ -46,6 +50,8 @@ public class ProfileProgressFragment extends Fragment implements ProfileContract public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = ProfileProgressFragmentBinding.inflate(inflater, container, false); + profile_progress = 0; + initProgress(); clickEvents(); @@ -53,6 +59,22 @@ public class ProfileProgressFragment extends Fragment implements ProfileContract return binding.getRoot(); } + @Override + public void onResume() { + super.onResume(); + try { + if (isAccessibilityAppBlockingEnabled()){ + profile_progress++; + + binding.freqApps.setImageResource(0); + binding.freqApps.setBackgroundResource(R.drawable.ic_done); + binding.freqApps.setPadding(15, 15, 15, 15); + } + } catch (Exception e) { + // do nothing + } + } + private void initProgress() { progressDialog = new ProgressDialog(requireContext()); @@ -107,6 +129,7 @@ public class ProfileProgressFragment extends Fragment implements ProfileContract ); binding.proceed.setOnClickListener(v -> { + Bundle bundle = new Bundle(); bundle.putInt(PROFILE_PROGRESS, profile_progress); bundle.putInt(IS_CONNECTED_TO_CG, is_connected_to_caregiver); @@ -178,10 +201,42 @@ public class ProfileProgressFragment extends Fragment implements ProfileContract }); } + private boolean isAccessibilityAppBlockingEnabled() { + int accessibilityEnabled = 0; + final String service = requireActivity().getPackageName() + "/" + TopAppDetectionService.class.getCanonicalName(); + + try { + accessibilityEnabled = Settings.Secure.getInt( + requireActivity().getContentResolver(), + Settings.Secure.ACCESSIBILITY_ENABLED); + + } catch (Settings.SettingNotFoundException e) { + Log.e("TAG", "Error finding setting, default accessibility to not found: " + + e.getMessage()); + } + + TextUtils.SimpleStringSplitter colonSplitter = new TextUtils.SimpleStringSplitter(':'); + + if (accessibilityEnabled == 1) { + String settingValue = Settings.Secure.getString( + requireActivity().getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); + if (settingValue != null) { + colonSplitter.setString(settingValue); + while (colonSplitter.hasNext()) { + String accessibilityService = colonSplitter.next(); + if (accessibilityService.equalsIgnoreCase(service)) { + return true; + } + } + } + } + + return false; + } + @Override public void onProfileProgressFetched(@NonNull PatientData patientData) { - - profile_progress = 0; is_connected_to_caregiver = patientData.isCareGiverConnectedWithPatient; if (patientData.isCareGiverLink == 1) { diff --git a/app/src/main/res/layout/activity_cg_geofencing.xml b/app/src/main/res/layout/activity_cg_geofencing.xml index d34f608..25f7f0f 100644 --- a/app/src/main/res/layout/activity_cg_geofencing.xml +++ b/app/src/main/res/layout/activity_cg_geofencing.xml @@ -3,6 +3,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:background="@color/white"> @@ -113,7 +114,7 @@ android:layout_height="match_parent"> There are no contacts added in your contact directory. Please click on the "Create New Contact" button above. Geofencing Set specific geographic areas and receive instant alerts when your loved one leaves the geofenced zone. - Destination 0.5m away - 165 Hasley St. Newark, NJ 07102 + Unknown location + Couldn\'t load address Enter your location Location Radius