Compare commits
4 Commits
master
...
geofence_o
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17b7f693a8 | ||
|
|
02f98bc824 | ||
|
|
8ca784f7b8 | ||
|
|
2a5799b711 |
@@ -6,6 +6,7 @@
|
|||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- For app blocking -> open new window over other apps to deny access -->
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- For app blocking -> open new window over other apps to deny access -->
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||||
@@ -239,6 +240,12 @@
|
|||||||
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
<receiver android:name=".patientgeofencing.GeoFenceBroadcastReceiver"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.simplitend.ACTION_GEOFENCE"/>
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
|||||||
@@ -2,30 +2,15 @@ package com.app.simplitend.apputils;
|
|||||||
|
|
||||||
import static com.app.simplitend.locationupdates.LocationService.LOCATION_INTERVAL_BASE_TIME;
|
import static com.app.simplitend.locationupdates.LocationService.LOCATION_INTERVAL_BASE_TIME;
|
||||||
import static com.app.simplitend.locationupdates.LocationService.LOCATION_UPDATE_MIN_INTERVAL;
|
import static com.app.simplitend.locationupdates.LocationService.LOCATION_UPDATE_MIN_INTERVAL;
|
||||||
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_ID;
|
|
||||||
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
|
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.RequiresPermission;
|
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import com.app.simplitend.locationupdates.LocationService;
|
import com.app.simplitend.locationupdates.LocationService;
|
||||||
import com.app.simplitend.patientgeofencing.GeoFenceHelper;
|
|
||||||
import com.google.android.gms.location.Geofence;
|
|
||||||
import com.google.android.gms.location.GeofencingClient;
|
|
||||||
import com.google.android.gms.location.GeofencingRequest;
|
|
||||||
import com.google.android.gms.location.LocationServices;
|
|
||||||
import com.google.android.gms.maps.model.LatLng;
|
|
||||||
|
|
||||||
public class BootCompleteReceiver extends BroadcastReceiver {
|
public class BootCompleteReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
@@ -45,6 +30,10 @@ public class BootCompleteReceiver extends BroadcastReceiver {
|
|||||||
context.startService(locationUpdateIntent);
|
context.startService(locationUpdateIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// starting geofence
|
||||||
|
Intent geofenceIntent = new Intent(context, LocationService.class);
|
||||||
|
geofenceIntent.setAction(LocationService.ACTION_START_GEOFENCE);
|
||||||
|
ContextCompat.startForegroundService(context, geofenceIntent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,30 +4,17 @@ import static android.content.Context.NOTIFICATION_SERVICE;
|
|||||||
import static com.app.simplitend.apputils.AppUtil.NOTIFICATION_ACTION;
|
import static com.app.simplitend.apputils.AppUtil.NOTIFICATION_ACTION;
|
||||||
import static com.app.simplitend.apputils.Constants.ACTIVITY_TIME;
|
import static com.app.simplitend.apputils.Constants.ACTIVITY_TIME;
|
||||||
import static com.app.simplitend.apputils.Constants.MEDICINE_TIME;
|
import static com.app.simplitend.apputils.Constants.MEDICINE_TIME;
|
||||||
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_ID;
|
|
||||||
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
|
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.service.notification.StatusBarNotification;
|
import android.service.notification.StatusBarNotification;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.RequiresPermission;
|
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import com.app.simplitend.patientgeofencing.GeoFenceHelper;
|
import com.app.simplitend.locationupdates.LocationService;
|
||||||
import com.google.android.gms.location.Geofence;
|
|
||||||
import com.google.android.gms.location.GeofencingClient;
|
|
||||||
import com.google.android.gms.location.GeofencingRequest;
|
|
||||||
import com.google.android.gms.location.LocationServices;
|
|
||||||
import com.google.android.gms.maps.model.LatLng;
|
|
||||||
import com.onesignal.OneSignal;
|
import com.onesignal.OneSignal;
|
||||||
import com.onesignal.notifications.INotificationReceivedEvent;
|
import com.onesignal.notifications.INotificationReceivedEvent;
|
||||||
import com.onesignal.notifications.INotificationServiceExtension;
|
import com.onesignal.notifications.INotificationServiceExtension;
|
||||||
@@ -36,7 +23,6 @@ import org.json.JSONException;
|
|||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class NotificationService implements INotificationServiceExtension {
|
public class NotificationService implements INotificationServiceExtension {
|
||||||
@@ -61,7 +47,7 @@ public class NotificationService implements INotificationServiceExtension {
|
|||||||
{
|
{
|
||||||
List<StatusBarNotification> active_notifications = Arrays.asList(notificationManager.getActiveNotifications());
|
List<StatusBarNotification> active_notifications = Arrays.asList(notificationManager.getActiveNotifications());
|
||||||
|
|
||||||
int minPostTime = Integer.MAX_VALUE;
|
long minPostTime = Long.MAX_VALUE;
|
||||||
StatusBarNotification notification = null;
|
StatusBarNotification notification = null;
|
||||||
for (StatusBarNotification not: active_notifications){
|
for (StatusBarNotification not: active_notifications){
|
||||||
if (not.getPostTime() < minPostTime){
|
if (not.getPostTime() < minPostTime){
|
||||||
@@ -167,9 +153,9 @@ public class NotificationService implements INotificationServiceExtension {
|
|||||||
if (radius >= 0){
|
if (radius >= 0){
|
||||||
AppUtil.updateSeniorOutOfGeofence(iNotificationReceivedEvent.getContext(), false);
|
AppUtil.updateSeniorOutOfGeofence(iNotificationReceivedEvent.getContext(), false);
|
||||||
|
|
||||||
AppUtil.updatePatientGeofence(iNotificationReceivedEvent.getContext(),
|
Intent geofenceIntent = new Intent(iNotificationReceivedEvent.getContext(), LocationService.class);
|
||||||
lat+"", lng+"",
|
geofenceIntent.setAction(LocationService.ACTION_START_GEOFENCE);
|
||||||
radius+"", "kms", message);
|
ContextCompat.startForegroundService(iNotificationReceivedEvent.getContext(), geofenceIntent);
|
||||||
}
|
}
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
Log.e(GEOFENCE_TAG, "COULDN'T UPDATE GEOFENCE DETAILS FROM THE NOTIFICATION: " + e);
|
Log.e(GEOFENCE_TAG, "COULDN'T UPDATE GEOFENCE DETAILS FROM THE NOTIFICATION: " + e);
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ public class DefaultLocationClient implements LocationClient{
|
|||||||
}
|
}
|
||||||
|
|
||||||
locationRequest = new LocationRequest.Builder(PRIORITY_HIGH_ACCURACY, interval)
|
locationRequest = new LocationRequest.Builder(PRIORITY_HIGH_ACCURACY, interval)
|
||||||
.setMinUpdateDistanceMeters(50) // receive updates only if user has moved over 100 meters
|
.setMinUpdateDistanceMeters(100) // receive updates only if user has moved over 100 meters
|
||||||
|
.setMinUpdateIntervalMillis(10_000) // fastest update to receive every 10 secs
|
||||||
.setPriority(PRIORITY_HIGH_ACCURACY)
|
.setPriority(PRIORITY_HIGH_ACCURACY)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
package com.app.simplitend.locationupdates;
|
package com.app.simplitend.locationupdates;
|
||||||
|
|
||||||
import static android.content.Intent.ACTION_BATTERY_CHANGED;
|
import static android.content.Intent.ACTION_BATTERY_CHANGED;
|
||||||
|
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_ID;
|
||||||
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
|
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
|
||||||
import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_EXTRA_KEY;
|
import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_EXTRA_KEY;
|
||||||
import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_REQUEST_TAG;
|
import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_REQUEST_TAG;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -19,17 +23,29 @@ import android.util.Log;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresPermission;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
|
|
||||||
import com.app.simplitend.BuildConfig;
|
import com.app.simplitend.BuildConfig;
|
||||||
import com.app.simplitend.R;
|
import com.app.simplitend.R;
|
||||||
import com.app.simplitend.apputils.AppUtil;
|
import com.app.simplitend.apputils.AppUtil;
|
||||||
|
import com.app.simplitend.apputils.PatientDataCache;
|
||||||
import com.app.simplitend.apputils.RetrofitHelper;
|
import com.app.simplitend.apputils.RetrofitHelper;
|
||||||
|
import com.app.simplitend.caregiverdashboard.mvvm.CgHomeContracts;
|
||||||
|
import com.app.simplitend.caregiverdashboard.mvvm.CgHomeRepository;
|
||||||
import com.app.simplitend.caregiverdashboard.mvvm.NotificationApiService;
|
import com.app.simplitend.caregiverdashboard.mvvm.NotificationApiService;
|
||||||
|
import com.app.simplitend.caregiverdashboard.mvvm.models.GeoFenceDetails;
|
||||||
import com.app.simplitend.chats.SocketHelper;
|
import com.app.simplitend.chats.SocketHelper;
|
||||||
|
import com.app.simplitend.patientgeofencing.GeoFenceHelper;
|
||||||
import com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver;
|
import com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver;
|
||||||
import com.app.simplitend.welcome.welcomepatient.mvvm.models.CallResponse;
|
import com.app.simplitend.welcome.welcomepatient.mvvm.models.CallResponse;
|
||||||
|
import com.app.simplitend.welcome.welcomepatient.mvvm.models.PatientData;
|
||||||
|
import com.google.android.gms.location.Geofence;
|
||||||
|
import com.google.android.gms.location.GeofencingClient;
|
||||||
|
import com.google.android.gms.location.GeofencingRequest;
|
||||||
import com.google.android.gms.location.LocationServices;
|
import com.google.android.gms.location.LocationServices;
|
||||||
|
import com.google.android.gms.maps.model.LatLng;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -42,15 +58,16 @@ import retrofit2.Call;
|
|||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
import retrofit2.Response;
|
import retrofit2.Response;
|
||||||
|
|
||||||
public class LocationService extends Service implements LocationClient.DefaultLocationUpdates {
|
public class LocationService extends Service implements LocationClient.DefaultLocationUpdates, CgHomeContracts.GetGeoFenceCallback {
|
||||||
|
|
||||||
public static final String ACTION_START_LOCATION_UPDATES = "com.simplitent.action_start_lu";
|
public static final String ACTION_START_LOCATION_UPDATES = "com.simplitent.action_start_lu";
|
||||||
public static final String ACTION_STOP_LOCATION_UPDATES = "com.simplitent.action.stop_lu";
|
public static final String ACTION_STOP_LOCATION_UPDATES = "com.simplitent.action.stop_lu";
|
||||||
|
public static final String ACTION_START_GEOFENCE = "com.simplitent.action.start_geofence";
|
||||||
public static final String LOCATION_NOTIFICATION_CHANNEL_ID = "location";
|
public static final String LOCATION_NOTIFICATION_CHANNEL_ID = "location";
|
||||||
|
|
||||||
public static final String LOCATION_UPDATE_MIN_INTERVAL = "min_interval";
|
public static final String LOCATION_UPDATE_MIN_INTERVAL = "min_interval";
|
||||||
|
|
||||||
public static final int LOCATION_INTERVAL_BASE_TIME = 25 * 1000;
|
public static final int LOCATION_INTERVAL_BASE_TIME = 2 * 60 * 1000;
|
||||||
|
|
||||||
private static final int LOCATION_UPDATES_NOTIFICATION_ID = 112;
|
private static final int LOCATION_UPDATES_NOTIFICATION_ID = 112;
|
||||||
|
|
||||||
@@ -62,6 +79,18 @@ public class LocationService extends Service implements LocationClient.DefaultLo
|
|||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
Log.d(LOCATION_REQUEST_TAG, "onCreate: SERVICE STARTED");
|
Log.d(LOCATION_REQUEST_TAG, "onCreate: SERVICE STARTED");
|
||||||
|
|
||||||
|
Notification notification = new NotificationCompat.Builder(this, LOCATION_NOTIFICATION_CHANNEL_ID)
|
||||||
|
.setContentTitle("Your phone is connected to your caregiver")
|
||||||
|
.setSmallIcon(R.mipmap.ic_launcher_round)
|
||||||
|
.setPriority(Notification.PRIORITY_HIGH)
|
||||||
|
.setOngoing(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
startForeground(LOCATION_UPDATES_NOTIFICATION_ID, notification);
|
||||||
|
notificationManager.notify(LOCATION_UPDATES_NOTIFICATION_ID, notification);
|
||||||
|
|
||||||
locationClient = new DefaultLocationClient(this,
|
locationClient = new DefaultLocationClient(this,
|
||||||
LocationServices.getFusedLocationProviderClient(this));
|
LocationServices.getFusedLocationProviderClient(this));
|
||||||
|
|
||||||
@@ -91,8 +120,11 @@ public class LocationService extends Service implements LocationClient.DefaultLo
|
|||||||
if (intent != null && intent.getAction() != null) {
|
if (intent != null && intent.getAction() != null) {
|
||||||
switch (intent.getAction()) {
|
switch (intent.getAction()) {
|
||||||
case ACTION_START_LOCATION_UPDATES:
|
case ACTION_START_LOCATION_UPDATES:
|
||||||
|
int minInterval = intent.getIntExtra(LOCATION_UPDATE_MIN_INTERVAL, 0);
|
||||||
|
if (minInterval != 0){
|
||||||
removeLocationUpdates();
|
removeLocationUpdates();
|
||||||
startLocationUpdates(10_000); // 10 seconds interval
|
startLocationUpdates(minInterval);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_STOP_LOCATION_UPDATES:
|
case ACTION_STOP_LOCATION_UPDATES:
|
||||||
stopLocationUpdates();
|
stopLocationUpdates();
|
||||||
@@ -100,6 +132,9 @@ public class LocationService extends Service implements LocationClient.DefaultLo
|
|||||||
// setting that senior is at home for start
|
// setting that senior is at home for start
|
||||||
AppUtil.updateSeniorOutOfGeofence(this, false);
|
AppUtil.updateSeniorOutOfGeofence(this, false);
|
||||||
break;
|
break;
|
||||||
|
case ACTION_START_GEOFENCE:
|
||||||
|
setGeofence();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,23 +151,11 @@ public class LocationService extends Service implements LocationClient.DefaultLo
|
|||||||
private void startLocationUpdates(int minInterval) {
|
private void startLocationUpdates(int minInterval) {
|
||||||
SocketHelper.getInstance().establishConnection(null);
|
SocketHelper.getInstance().establishConnection(null);
|
||||||
|
|
||||||
Notification notification = new NotificationCompat.Builder(this, LOCATION_NOTIFICATION_CHANNEL_ID)
|
|
||||||
.setContentTitle("Your phone is connected to your caregiver")
|
|
||||||
.setSmallIcon(R.mipmap.ic_launcher_round)
|
|
||||||
.setPriority(Notification.PRIORITY_HIGH)
|
|
||||||
.setOngoing(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
locationClient.getLocationUpdates(minInterval, this);
|
locationClient.getLocationUpdates(minInterval, this);
|
||||||
} catch (LocationClient.LocationException e) {
|
} catch (LocationClient.LocationException e) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
startForeground(LOCATION_UPDATES_NOTIFICATION_ID, notification);
|
|
||||||
notificationManager.notify(LOCATION_UPDATES_NOTIFICATION_ID, notification);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -324,4 +347,85 @@ public class LocationService extends Service implements LocationClient.DefaultLo
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// geofence functions
|
||||||
|
private void setGeofence() {
|
||||||
|
// retrieving geofence
|
||||||
|
CgHomeRepository.getHomeRepository().getGeoFenceDetails(AppUtil.getPatientUid(this) + "",
|
||||||
|
"", "Bearer " + AppUtil.getPatientToken(this),
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validateAndAddGeofence(GeoFenceDetails geoFenceDetails) {
|
||||||
|
if (geoFenceDetails.radius != null && geoFenceDetails.type != null) {
|
||||||
|
PatientDataCache.setPatientData(null); // for fresh data
|
||||||
|
PatientDataCache.getPatientData(this, (patientData -> {
|
||||||
|
if (patientData != null) {
|
||||||
|
if (AppUtil.shouldAddPatientGeofence(this,
|
||||||
|
geoFenceDetails.radius, geoFenceDetails.type, patientData)) {
|
||||||
|
// should add a geofence
|
||||||
|
setGeofence(this, geoFenceDetails, patientData);
|
||||||
|
} else {
|
||||||
|
Log.d(GEOFENCE_TAG, "onGeofenceDetailsFetched: should not add patient geofence because GEOFENCE DETAILS: " + geoFenceDetails + " PATIENT DETAILS: " + patientData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGeofence(Context activity, GeoFenceDetails geoFenceDetails, PatientData patientData) {
|
||||||
|
LatLng latLng;
|
||||||
|
float radius;
|
||||||
|
try {
|
||||||
|
latLng = new LatLng(Double.parseDouble(patientData.lat), Double.parseDouble(patientData.lng));
|
||||||
|
radius = Float.parseFloat(geoFenceDetails.radius);
|
||||||
|
} catch (Exception e) {
|
||||||
|
latLng = null;
|
||||||
|
radius = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (latLng != null && radius != 0) {
|
||||||
|
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
Log.d(GEOFENCE_TAG, "setGeofence: NO FINE LOCATION PERMISSION" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addGeoFence(latLng, radius, activity, geoFenceDetails.type, geoFenceDetails.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION)
|
||||||
|
private void addGeoFence(@NonNull LatLng latLng, float GEOFENCING_RADIUS , Context activity, String unit, String message) {
|
||||||
|
AppUtil.removeGeofence(activity);
|
||||||
|
|
||||||
|
GeoFenceHelper geoFenceHelper = new GeoFenceHelper(activity);
|
||||||
|
GeofencingClient geofencingClient = LocationServices.getGeofencingClient(activity);
|
||||||
|
|
||||||
|
Geofence geofence = geoFenceHelper.getGeoFence(GEOFENCE_ID, latLng, GEOFENCING_RADIUS,
|
||||||
|
Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT);
|
||||||
|
GeofencingRequest geofencingRequest = geoFenceHelper.getGeoFencingRequest(geofence);
|
||||||
|
PendingIntent pendingIntent = geoFenceHelper.getPendingIntent();
|
||||||
|
|
||||||
|
geofencingClient.addGeofences(geofencingRequest, pendingIntent)
|
||||||
|
.addOnSuccessListener(aVoid -> {
|
||||||
|
Log.d(GEOFENCE_TAG, "Geofence added successfully. " + latLng + " Radius: " + GEOFENCING_RADIUS + " meters");
|
||||||
|
AppUtil.updatePatientGeofence(activity, latLng.latitude+"", latLng.longitude+"",
|
||||||
|
GEOFENCING_RADIUS+"", unit, message);
|
||||||
|
})
|
||||||
|
.addOnFailureListener(e -> {
|
||||||
|
Log.d(GEOFENCE_TAG, "onFailure: Geofence couldn't be added: " + e.getLocalizedMessage() + " " + latLng + " Radius: " + GEOFENCING_RADIUS);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGeofenceDetailsFetched(@NonNull GeoFenceDetails geoFenceDetails) {
|
||||||
|
validateAndAddGeofence(geoFenceDetails);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onGeofenceDetailsFetchFailed(Throwable throwable, String message) {
|
||||||
|
Log.d(GEOFENCE_TAG, "onGeofenceDetailsFetchFailed: " + message);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package com.app.simplitend.patient_dashboard;
|
package com.app.simplitend.patient_dashboard;
|
||||||
|
|
||||||
import static com.app.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
|
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.app.role.RoleManager;
|
import android.app.role.RoleManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -11,45 +9,69 @@ import android.content.res.Configuration;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.telecom.TelecomManager;
|
import android.telecom.TelecomManager;
|
||||||
import android.util.Log;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import com.app.simplitend.R;
|
import com.app.simplitend.R;
|
||||||
import com.app.simplitend.apputils.AppUtil;
|
import com.app.simplitend.apputils.AppUtil;
|
||||||
import com.app.simplitend.apputils.PatientDataCache;
|
import com.app.simplitend.locationupdates.LocationService;
|
||||||
import com.app.simplitend.caregiverdashboard.mvvm.CgHomeContracts;
|
|
||||||
import com.app.simplitend.caregiverdashboard.mvvm.models.GeoFenceDetails;
|
|
||||||
|
|
||||||
public class DashBoardActivity extends AppCompatActivity implements CgHomeContracts.GetGeoFenceCallback {
|
public class DashBoardActivity extends AppCompatActivity {
|
||||||
|
|
||||||
protected PatientMainViewModel viewModel;
|
protected PatientMainViewModel viewModel;
|
||||||
|
|
||||||
protected ActivityResultLauncher<String> finePermissionLauncher;
|
protected ActivityResultLauncher<String> finePermissionLauncher;
|
||||||
|
protected ActivityResultLauncher<String> backgroundPermissionLauncher;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_dash_board_cp);
|
setContentView(R.layout.activity_dash_board_cp);
|
||||||
|
|
||||||
|
Toast.makeText(this, "Testing geofencing feature", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
viewModel = new ViewModelProvider(this).get(PatientMainViewModel.class);
|
viewModel = new ViewModelProvider(this).get(PatientMainViewModel.class);
|
||||||
|
|
||||||
updateGeofenceDetails();
|
backgroundPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(),
|
||||||
|
isGranted -> {
|
||||||
|
if (isGranted) {
|
||||||
|
setGeofenceAndLocationUpdates();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
finePermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(),
|
finePermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(),
|
||||||
isGranted -> {
|
isGranted -> {
|
||||||
if (isGranted) {
|
if (isGranted) {
|
||||||
// getting location updates
|
// getting location updates
|
||||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
|
||||||
return;
|
viewModel.addLocationUpdates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.addLocationUpdates(this);
|
|
||||||
} else {
|
} else {
|
||||||
// permission denied
|
// permission denied
|
||||||
AppUtil.showAlert(this,
|
AppUtil.showAlert(this,
|
||||||
@@ -62,6 +84,8 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
registerForActivityResult(new ActivityResultContracts.RequestPermission(),
|
registerForActivityResult(new ActivityResultContracts.RequestPermission(),
|
||||||
result -> {
|
result -> {
|
||||||
|
|
||||||
@@ -86,6 +110,12 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setGeofenceAndLocationUpdates() {
|
||||||
|
Intent intent = new Intent(this, LocationService.class);
|
||||||
|
intent.setAction(LocationService.ACTION_START_GEOFENCE);
|
||||||
|
ContextCompat.startForegroundService(this, intent);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void attachBaseContext(Context newBase) {
|
protected void attachBaseContext(Context newBase) {
|
||||||
final Configuration configuration = new Configuration(newBase.getResources().getConfiguration());
|
final Configuration configuration = new Configuration(newBase.getResources().getConfiguration());
|
||||||
@@ -93,41 +123,4 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra
|
|||||||
applyOverrideConfiguration(configuration);
|
applyOverrideConfiguration(configuration);
|
||||||
super.attachBaseContext(newBase);
|
super.attachBaseContext(newBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
// saves the geofence details
|
|
||||||
private void updateGeofenceDetails() {
|
|
||||||
// retrieving geofence
|
|
||||||
viewModel.getGeoFenceDetails(AppUtil.getPatientUid(this) + "",
|
|
||||||
"", "Bearer " + AppUtil.getPatientToken(this),
|
|
||||||
this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void validateAndAddGeofence(GeoFenceDetails geoFenceDetails) {
|
|
||||||
if (geoFenceDetails.radius != null && geoFenceDetails.type != null) {
|
|
||||||
PatientDataCache.getPatientData(this, (patientData -> {
|
|
||||||
if (patientData != null) {
|
|
||||||
if (AppUtil.shouldAddPatientGeofence(this,
|
|
||||||
geoFenceDetails.radius, geoFenceDetails.type, patientData)) {
|
|
||||||
// should add a geofence
|
|
||||||
AppUtil.updatePatientGeofence(this, patientData.lat, patientData.lng,
|
|
||||||
geoFenceDetails.radius, geoFenceDetails.type, geoFenceDetails.message);
|
|
||||||
} else {
|
|
||||||
Log.d(GEOFENCE_TAG, "onGeofenceDetailsFetched: GEOFENCE DATA UP TO DATE");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGeofenceDetailsFetched(@NonNull GeoFenceDetails geoFenceDetails) {
|
|
||||||
validateAndAddGeofence(geoFenceDetails);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGeofenceDetailsFetchFailed(Throwable throwable, String message) {
|
|
||||||
Log.d(GEOFENCE_TAG, "onGeofenceDetailsFetchFailed: " + message);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
package com.app.simplitend.patient_dashboard;
|
package com.app.simplitend.patient_dashboard;
|
||||||
|
|
||||||
import static android.content.Context.ACTIVITY_SERVICE;
|
|
||||||
import static com.app.simplitend.locationupdates.LocationService.LOCATION_INTERVAL_BASE_TIME;
|
import static com.app.simplitend.locationupdates.LocationService.LOCATION_INTERVAL_BASE_TIME;
|
||||||
import static com.app.simplitend.locationupdates.LocationService.LOCATION_UPDATE_MIN_INTERVAL;
|
import static com.app.simplitend.locationupdates.LocationService.LOCATION_UPDATE_MIN_INTERVAL;
|
||||||
import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_REQUEST_TAG;
|
import static com.app.simplitend.patientgeofencing.PatientLocationUpdatesReceiver.LOCATION_REQUEST_TAG;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
|||||||
@@ -79,41 +79,22 @@ public class GeoFenceBroadcastReceiver extends BroadcastReceiver {
|
|||||||
break;
|
break;
|
||||||
case Geofence.GEOFENCE_TRANSITION_ENTER:
|
case Geofence.GEOFENCE_TRANSITION_ENTER:
|
||||||
Log.d(GEOFENCE_TAG, "onReceive: ENTER");
|
Log.d(GEOFENCE_TAG, "onReceive: ENTER");
|
||||||
Notification notification = new NotificationCompat.Builder(context, LOCATION_NOTIFICATION_CHANNEL_ID)
|
|
||||||
.setSmallIcon(R.mipmap.ic_launcher_round)
|
|
||||||
.setContentTitle("Geofence entered")
|
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH).build();
|
|
||||||
|
|
||||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
AppUtil.updateSeniorOutOfGeofence(context, false);
|
||||||
|
|
||||||
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
notificationManager.notify(1023, notification);
|
|
||||||
|
|
||||||
Intent locationServiceIntent = new Intent(context, LocationService.class);
|
|
||||||
locationServiceIntent.setAction(LocationService.ACTION_START_LOCATION_UPDATES);
|
|
||||||
locationServiceIntent.putExtra(LOCATION_UPDATE_MIN_INTERVAL, LOCATION_INTERVAL_BASE_TIME);
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
context.startForegroundService(locationServiceIntent);
|
|
||||||
} else {
|
|
||||||
context.startService(locationServiceIntent);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Geofence.GEOFENCE_TRANSITION_EXIT:
|
case Geofence.GEOFENCE_TRANSITION_EXIT:
|
||||||
Log.d(GEOFENCE_TAG, "onReceive: EXIT");
|
Log.d(GEOFENCE_TAG, "onReceive: EXIT");
|
||||||
|
|
||||||
Notification notification1 = new NotificationCompat.Builder(context, LOCATION_NOTIFICATION_CHANNEL_ID)
|
if (AppUtil.isSeniorOutOfGeofence(context)){
|
||||||
.setSmallIcon(R.mipmap.ic_launcher_round)
|
// already out of geofence
|
||||||
.setContentTitle("Geofence exited")
|
// meaning the location updates were received early than the geofence trigger
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH).build();
|
// and the caregiver has already been sent notifications
|
||||||
|
// thus, not sending them again
|
||||||
NotificationManagerCompat notificationManager1 = NotificationManagerCompat.from(context);
|
break;
|
||||||
|
|
||||||
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
notificationManager1.notify(1032, notification1);
|
|
||||||
|
AppUtil.updateSeniorOutOfGeofence(context, true);
|
||||||
|
|
||||||
notifyOutOfGeofence(context, String.format(Locale.getDefault(), "%.2f", distance));
|
notifyOutOfGeofence(context, String.format(Locale.getDefault(), "%.2f", distance));
|
||||||
|
|
||||||
@@ -221,7 +202,7 @@ public class GeoFenceBroadcastReceiver extends BroadcastReceiver {
|
|||||||
// getting faster location updates as patient is out of geofence
|
// getting faster location updates as patient is out of geofence
|
||||||
Intent intent = new Intent(context, LocationService.class);
|
Intent intent = new Intent(context, LocationService.class);
|
||||||
intent.setAction(LocationService.ACTION_START_LOCATION_UPDATES);
|
intent.setAction(LocationService.ACTION_START_LOCATION_UPDATES);
|
||||||
intent.putExtra(LOCATION_UPDATE_MIN_INTERVAL, 5 * 1000); // every 5 seconds
|
intent.putExtra(LOCATION_UPDATE_MIN_INTERVAL, 10 * 1000); // every 10 seconds
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
context.startForegroundService(intent);
|
context.startForegroundService(intent);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ public class GeoFenceHelper extends ContextWrapper {
|
|||||||
.setRequestId(GEOFENCE_ID)
|
.setRequestId(GEOFENCE_ID)
|
||||||
.setTransitionTypes(transitionType)
|
.setTransitionTypes(transitionType)
|
||||||
.setExpirationDuration(Geofence.NEVER_EXPIRE)
|
.setExpirationDuration(Geofence.NEVER_EXPIRE)
|
||||||
.setLoiteringDelay(5000) // This does nothing if the transition is not DWELL
|
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user