This commit is contained in:
2023-10-13 20:50:37 +05:30
parent 713fb528dc
commit 5deecc06fa
14 changed files with 512 additions and 143 deletions

View File

@@ -6,13 +6,13 @@
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\adity\.android\avd\Samsung_Z3_flip_API_34.avd" />
<type value="SERIAL_NUMBER" />
<value value="RZCT807SYMH" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-10-12T14:59:34.371632800Z" />
<timeTargetWasSelectedWithDropDown value="2023-10-13T14:30:49.604916400Z" />
<runningDeviceTargetsSelectedWithDialog>
<Target>
<type value="RUNNING_DEVICE_TARGET" />

View File

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

View File

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

View File

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

View File

@@ -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<Intent> 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<Location>() {
@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<Address> addresses = geocoder.getFromLocation(mLatLng.latitude, mLatLng.longitude, 1);
List<Address> 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<String, String> 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();
}

View File

@@ -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<String> finePermissionLauncher;
protected ActivityResultLauncher<String> 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);
}
}
}
}

View File

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

View File

@@ -68,7 +68,7 @@ public class ChatFragment extends Fragment implements SocketHelper.Callback<Mess
if (patient_id != null){
SocketHelper socketHelper = SocketHelper.getInstance();
socketHelper.establishConnection();
socketHelper.establishConnection(null);
socketHelper.getMessage(this, patient_id, nick_name,
receiver_image,

View File

@@ -1,8 +1,10 @@
package com.app.simplitend.patient_dashboard.chats;
import android.location.Location;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.app.simplitend.patient_dashboard.chats.mvvm.Author;
import com.app.simplitend.patient_dashboard.chats.mvvm.Message;
@@ -16,10 +18,11 @@ public class SocketHelper {
private static final String TAG = "SOCKET_CHAT_TAG";
private static final String kHost = "http://77.68.102.23:3002/";
public static final String kHost = "http://77.68.102.23:3002/";
private static SocketHelper instance;
private Socket mSocket;
private SockCallBack socketCallback;
private SocketHelper() {
try {
@@ -32,6 +35,9 @@ public class SocketHelper {
@Override
public void call(Object... args) {
Log.d(TAG, "Socket connected ");
if (socketCallback != null){
socketCallback.onSocketConnected();
}
}
});
@@ -39,6 +45,9 @@ public class SocketHelper {
@Override
public void call(Object... args) {
Log.d(TAG, "Socket disconnected ");
if (socketCallback != null){
socketCallback.onDisconnected();
}
}
});
@@ -47,6 +56,9 @@ public class SocketHelper {
public void call(Object... args) {
Exception e = (Exception) args[0];
Log.e(TAG, "call: ", e);
if (socketCallback != null){
socketCallback.onConnectionError(e);
}
}
});
} catch (Exception e) {
@@ -62,7 +74,8 @@ public class SocketHelper {
return instance;
}
public void establishConnection() {
public void establishConnection(@Nullable SockCallBack sockCallBack) {
this.socketCallback = sockCallBack;
if (!mSocket.connected()) {
mSocket.connect();
}
@@ -118,10 +131,67 @@ public class SocketHelper {
mSocket.emit("chatMessage", nickname, message, patient_id);
}
private static final String LOCATION_EVENT_PREFIX = "patientCurrentLocation";
public void sendLocationUpdates(Location location, String patient_id){
mSocket.emit("currentLocationUpdate", location.getLatitude() + "", location.getLongitude() + "",
LOCATION_EVENT_PREFIX + patient_id);
}
public void getLocationUpdates(String patient_id, Callback<Location> 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<T> {
void onMessageReceived(T result);
void onMessageSentSuccessfully();
void onError(Exception e);
}
public interface SockCallBack{
void onSocketConnected();
void onConnectionError(Exception e);
void onDisconnected();
}
}

View File

@@ -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<String, String> 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<CallResponse<Object>>() {
@Override
public void onResponse(Call<CallResponse<Object>> call, Response<CallResponse<Object>> 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<CallResponse<Object>> 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<Location, Void, Void>{
@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<Location>() {
@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;
}
}
}

View File

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

View File

@@ -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">
<TextView
android:id="@+id/away"
android:id="@+id/distance_away_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -128,7 +129,8 @@
/>
<TextView
android:layout_below="@id/away"
android:id="@+id/home_address"
android:layout_below="@id/distance_away_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -493,9 +493,10 @@
</LinearLayout>
<LinearLayout
android:id="@+id/fua"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:visibility="visible"
android:orientation="horizontal">
<LinearLayout

View File

@@ -316,8 +316,8 @@
<string name="there_are_no_contacts_added_in_your_contact_directory_please_click_on_the_create_new_contact_button_above">There are no contacts added in your contact directory. Please click on the "Create New Contact" button above.</string>
<string name="geofencing">Geofencing</string>
<string name="set_specific_geographic_areas_and_receive_instant_alerts_when_your_loved_one_leaves_the_geofenced_zone">Set specific geographic areas and receive instant alerts when your loved one leaves the geofenced zone.</string>
<string name="destination_0_5m_away">Destination 0.5m away</string>
<string name="_165_hasley_st_newark_nj_07102">165 Hasley St. Newark, NJ 07102</string>
<string name="destination_0_5m_away">Unknown location</string>
<string name="_165_hasley_st_newark_nj_07102">Couldn\'t load address</string>
<string name="enter_your_location">Enter your location</string>
<string name="location">Location</string>
<string name="radius">Radius</string>