diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 05b941e..7c5e32e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,6 +5,7 @@
+
+
+
appList = mySharedPref.getArrayList("APP_LIST");
- if (appList != null) {
- appList.clear();
- mySharedPref.setArrayList("APP_LIST", appList);
- }
- }
-
- public static void saveCgData(String token, int patient_id, Context context){
- SharedPreferences sp = context.getSharedPreferences(CAREGIVER_DETAILS, Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = sp.edit();
-
- editor.putString(CAREGIVER_TOKEN, token);
-
- editor.apply();
-
- // now saving patient data
- // This is important as there are instances where patient data such as patient id and patient_token is required
- savePatientData(token, patient_id, context, false);
-
- Log.d(TAG, "saveToken: caregiver token saved successful");
-
- }
-
- public static String getCgToken(Context context){
- SharedPreferences sp = context.getSharedPreferences(CAREGIVER_DETAILS, Context.MODE_PRIVATE);
- return sp.getString(CAREGIVER_TOKEN, null);
- }
-
- public static void setWantSecurityFlag(Context context, int watSecurity){
- SharedPreferences sp = context.getSharedPreferences(CAREGIVER_DETAILS, Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = sp.edit();
-
- editor.putInt(CG_APP_SECURITY, watSecurity);
-
- editor.apply();
- }
-
- public static int getWantSecurityFlag(Context context){
- SharedPreferences sp = context.getSharedPreferences(CAREGIVER_DETAILS, Context.MODE_PRIVATE);
- return sp.getInt(CG_APP_SECURITY, NOT_ASKED_CG_SECURITY);
- }
-
- public static void cgSignOut(Context context){
- saveCgData(null, -1, context);
- setWantSecurityFlag(context, NOT_ASKED_CG_SECURITY);
- }
-
public static void dialPhone(Context activity, String phone_number) {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel",
phone_number, null));
@@ -382,4 +313,180 @@ public abstract class AppUtil {
binding.btn.setText(btn_text);
binding.btn.setOnClickListener(btn_clickListener);
}
+
+
+ // ********************* USER DATA UTILS ******************************************
+
+ public static void savePatientData(String token, int patient_uid, Context context, boolean isLoggedIn){
+ SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sp.edit();
+
+ editor.putString(PATIENT_TOKEN, token);
+ editor.putInt(PATIENT_UID, patient_uid);
+ editor.putBoolean(IS_PATIENT_LOGGED_IN, isLoggedIn);
+
+ editor.apply();
+
+ Log.d(TAG, "saveToken: user token saved successful");
+
+ }
+
+ public static String getPatientToken(Context context){
+ SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
+ return sp.getString(PATIENT_TOKEN, "");
+ }
+
+ public static int getPatientUid(Context context){
+ SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
+ return sp.getInt(PATIENT_UID, -1);
+ }
+
+ public static boolean isPatientLoggedIn(Context context) {
+ SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
+ return sp.getBoolean(IS_PATIENT_LOGGED_IN, false);
+ }
+
+ public static void patientSignOut(Context context){
+ AppUtil.savePatientData(null, -1, context, false);
+
+ // app block list clear
+ MySharedPref mySharedPref = new MySharedPref(context);
+ Set appList = mySharedPref.getArrayList("APP_LIST");
+ if (appList != null) {
+ appList.clear();
+ mySharedPref.setArrayList("APP_LIST", appList);
+ }
+
+ // geofence details clear
+ updatePatientGeofence(context, null, null, null, null);
+ // removing geofence
+ GeofencingClient geofencingClient = LocationServices.getGeofencingClient(context);
+ geofencingClient.removeGeofences(Collections.singletonList(GEOFENCE_ID)).addOnSuccessListener(v -> {
+ Log.d(GEOFENCE_TAG, "patientSignOut: GEOFENCE REMOVED");
+ }).addOnFailureListener(v -> {
+ Log.d(GEOFENCE_TAG, "patientSignOut: GEOFENCE COULDN'T BE REMOVE " + v);
+ });
+
+ // closing notifications
+ OneSignal.getUser().getPushSubscription().optOut();
+ }
+
+ public static void saveCgData(String token, int patient_id, Context context){
+ SharedPreferences sp = context.getSharedPreferences(CAREGIVER_DETAILS, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sp.edit();
+
+ editor.putString(CAREGIVER_TOKEN, token);
+
+ editor.apply();
+
+ // now saving patient data
+ // This is important as there are instances where patient data such as patient id and patient_token is required
+ savePatientData(token, patient_id, context, false);
+
+ Log.d(TAG, "saveToken: caregiver token saved successful");
+
+ }
+
+ public static String getCgToken(Context context){
+ SharedPreferences sp = context.getSharedPreferences(CAREGIVER_DETAILS, Context.MODE_PRIVATE);
+ return sp.getString(CAREGIVER_TOKEN, null);
+ }
+
+ public static void setWantSecurityFlag(Context context, int watSecurity){
+ SharedPreferences sp = context.getSharedPreferences(CAREGIVER_DETAILS, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sp.edit();
+
+ editor.putInt(CG_APP_SECURITY, watSecurity);
+
+ editor.apply();
+ }
+
+ public static int getWantSecurityFlag(Context context){
+ SharedPreferences sp = context.getSharedPreferences(CAREGIVER_DETAILS, Context.MODE_PRIVATE);
+ return sp.getInt(CG_APP_SECURITY, NOT_ASKED_CG_SECURITY);
+ }
+
+ public static void cgSignOut(Context context){
+ saveCgData(null, -1, context);
+ setWantSecurityFlag(context, NOT_ASKED_CG_SECURITY);
+
+ // closing notification
+ OneSignal.getUser().getPushSubscription().optOut();
+ }
+
+ // patient geofencing
+ private static final String PATIENT_GEOFENCE_RADIUS = "patient_geofence_radius";
+ private static final String PATIENT_GEOFENCE_RADIUS_UNIT = "patient_geofence_radius_unit";
+ private static final String PATIENT_GEOFENCE_LATITUDE = "patient_geofence_latitude";
+ private static final String PATIENT_GEOFENCE_LONGITUDE = "patient_geofence_longitude";
+
+ public static void updatePatientGeofence(Context context, String lat, String lng, String radius, String radius_unit){
+ SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sp.edit();
+
+ editor.putString(PATIENT_GEOFENCE_LATITUDE, lat);
+ editor.putString(PATIENT_GEOFENCE_LONGITUDE, lng);
+ editor.putString(PATIENT_GEOFENCE_RADIUS, radius);
+ editor.putString(PATIENT_GEOFENCE_RADIUS_UNIT, radius_unit);
+
+ editor.apply();
+ Log.d(GEOFENCE_TAG, "updatePatientGeofence: UPDATED");
+ }
+
+ public static String[] getPatientLatLng(Context context){
+ SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
+ return new String[]{sp.getString(PATIENT_GEOFENCE_LATITUDE, null), sp.getString(PATIENT_GEOFENCE_LONGITUDE, null)};
+ }
+
+ public static String getPatientGeofenceRadius(Context context){
+ SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
+ return sp.getString(PATIENT_GEOFENCE_RADIUS, null);
+ }
+
+ public static String getPatientGeofenceRadiusUnit(Context context){
+ SharedPreferences sp = context.getSharedPreferences(PATIENT_DETAILS, Context.MODE_PRIVATE);
+ return sp.getString(PATIENT_GEOFENCE_RADIUS_UNIT, null);
+ }
+
+ public static boolean shouldAddPatientGeofence(@NonNull Context context,
+ @NonNull String remote_radius,
+ @NonNull String remote_radius_unit,
+ @NonNull PatientData data) {
+
+ String local_radius = getPatientGeofenceRadius(context);
+
+ if (local_radius != null){
+ try {
+ float local_radius_f = Float.parseFloat(local_radius);
+ float remote_radius_f = Float.parseFloat(remote_radius);
+
+ if (local_radius_f != remote_radius_f){
+ // radius' are different
+ // thus, should add geofence
+ return true;
+ }
+ }catch (Exception e){
+ // do nothing
+ }
+ }
+
+ // radius is equal thus, checking for unit of the radius
+ String local_radius_unit = getPatientGeofenceRadiusUnit(context);
+ if (!remote_radius_unit.equals(local_radius_unit)){
+ // remote radius units are different
+ // thus, should add geofence
+ return true;
+ }
+
+ // checking for lat lng
+ String[] local_lat_lng = getPatientLatLng(context);
+ if (data.lat != null && data.lng != null) {
+ if (!data.lat.equals(local_lat_lng[0]) || !data.lng.equals(local_lat_lng[1])){
+ // remote lat lng has changed
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/app/src/main/java/com/ssb/simplitend/apputils/NotificationService.java b/app/src/main/java/com/ssb/simplitend/apputils/NotificationService.java
index 4acf48e..62bce52 100644
--- a/app/src/main/java/com/ssb/simplitend/apputils/NotificationService.java
+++ b/app/src/main/java/com/ssb/simplitend/apputils/NotificationService.java
@@ -1,11 +1,29 @@
package com.ssb.simplitend.apputils;
+import static com.ssb.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_ID;
+import static com.ssb.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
+
+import android.Manifest;
+import android.app.PendingIntent;
+import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+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 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.notifications.INotificationReceivedEvent;
import com.onesignal.notifications.INotificationServiceExtension;
+import com.ssb.simplitend.patientgeofencing.GeoFenceHelper;
import org.json.JSONException;
import org.json.JSONObject;
@@ -20,7 +38,7 @@ public class NotificationService implements INotificationServiceExtension {
public void onNotificationReceived(@NonNull INotificationReceivedEvent iNotificationReceivedEvent) {
JSONObject extras = iNotificationReceivedEvent.getNotification().getAdditionalData();
String content_type = null;
- if (extras != null){
+ if (extras != null) {
try {
content_type = extras.getString("content_type");
} catch (JSONException e) {
@@ -34,5 +52,49 @@ public class NotificationService implements INotificationServiceExtension {
intent.putExtra(NOTIFICATION_TITLE_KEY, iNotificationReceivedEvent.getNotification().getTitle());
iNotificationReceivedEvent.getContext().sendBroadcast(intent);
+
+ if (Constants.GEOFENCING_RADIUS_UPDATED.equals(content_type) || Constants.HOME_LOCATION_UPDATED.equals(content_type)) {
+ if (AppUtil.isPatientLoggedIn(iNotificationReceivedEvent.getContext())){
+ // Either Geofence radius or Patient's location has changed.
+ Log.d(GEOFENCE_TAG, "Adding geo fence...");
+ if (ActivityCompat.checkSelfPermission(iNotificationReceivedEvent.getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ Log.d(GEOFENCE_TAG, "No location permission");
+ return;
+ }
+
+// addGeoFence(new LatLng(18.933154827942843, 72.82790520714602),
+// 200, iNotificationReceivedEvent.getContext());
+ }else{
+ Log.d(GEOFENCE_TAG, "onNotificationReceived of PATIENT GEOFENCE CHANGED. BUT PATIENT IS LOGGED OUT.");
+ }
+ }
+ }
+
+ @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION)
+ private void addGeoFence(@NonNull LatLng latLng, float GEOFENCING_RADIUS , Context context) {
+ GeoFenceHelper geoFenceHelper = new GeoFenceHelper(context);
+ GeofencingClient geofencingClient = LocationServices.getGeofencingClient(context);
+
+ // checking for background location updates for API level 29 and above
+ if (Build.VERSION.SDK_INT >= 29) {
+ if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ Log.d(GEOFENCE_TAG, "addGeoFence: No background location permission");
+ return;
+ }
+ }
+
+ 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.");
+ AppUtil.updatePatientGeofence(context, latLng.latitude+"", latLng.longitude+"",
+ GEOFENCING_RADIUS+"", "kms");
+ })
+ .addOnFailureListener(e -> Log.d(GEOFENCE_TAG, "onFailure: Geofence couldn't be added: " + e.getLocalizedMessage()));
+
}
}
diff --git a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/activities/CaregiverDashActivity.java b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/activities/CaregiverDashActivity.java
index d0d0fda..0fe0409 100644
--- a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/activities/CaregiverDashActivity.java
+++ b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/activities/CaregiverDashActivity.java
@@ -199,6 +199,8 @@ public class CaregiverDashActivity extends AppCompatActivity implements
// initializing dashboard fragment
replaceFragment(new CgDashBoardFragment(), "dashboard");
+ OneSignal.getUser().getPushSubscription().optIn();
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
// requestPermission will show the native Android notification permission prompt.
OneSignal.getNotifications().requestPermission(true, Continue.with(r -> {
diff --git a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/fragments/CgDashBoardFragment.java b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/fragments/CgDashBoardFragment.java
index 305130f..ab36518 100644
--- a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/fragments/CgDashBoardFragment.java
+++ b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/fragments/CgDashBoardFragment.java
@@ -32,6 +32,7 @@ import com.google.android.gms.maps.model.MarkerOptions;
import com.ssb.simplitend.R;
import com.ssb.simplitend.apputils.AppUtil;
import com.ssb.simplitend.apputils.CaregiverDataCache;
+import com.ssb.simplitend.apputils.Constants;
import com.ssb.simplitend.articles.ArticleContracts;
import com.ssb.simplitend.articles.ArticleResult;
import com.ssb.simplitend.articles.ArticleShowerActivity;
@@ -94,14 +95,12 @@ public class CgDashBoardFragment extends Fragment implements
@Override
public void onReceive(Context context, Intent intent) {
String content_type = intent.getStringExtra(CONTENT_TYPE_KEY);
-
- loadReminders();
- loadActivities();
-// if (Constants.ACTIVITY_TIME.equals(content_type)){
-// loadArticles();
-// }else if (Constants.MEDICINE_TIME.equals(content_type)){
-// loadReminders();
-// }
+
+ if (Constants.ACTIVITY_TIME.equals(content_type)){
+ loadActivities();
+ }else if (Constants.MEDICINE_TIME.equals(content_type)){
+ loadReminders();
+ }
}
};
@@ -317,7 +316,8 @@ public class CgDashBoardFragment extends Fragment implements
progressDialog.setCancelable(false);
progressDialog.show();
- viewModel.getGeoFenceDetails(careGiverData.caregiver_xid,
+ viewModel.getGeoFenceDetails("",
+ careGiverData.caregiver_xid + "",
"Bearer " + AppUtil.getCgToken(requireContext()),
this);
@@ -354,6 +354,7 @@ public class CgDashBoardFragment extends Fragment implements
.position(latLng)
.title(patient_name);
+ mGoogleMap.clear();
mGoogleMap.addMarker(markerOptions);
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16));;
}
diff --git a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/fragments/MyPatientFragment.java b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/fragments/MyPatientFragment.java
index 2ffe7cc..e37aeb0 100644
--- a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/fragments/MyPatientFragment.java
+++ b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/fragments/MyPatientFragment.java
@@ -118,7 +118,8 @@ public class MyPatientFragment extends Fragment implements CgHomeContracts.GetGe
progressDialog.setCancelable(false);
progressDialog.show();
- viewModel.getGeoFenceDetails(careGiverData.caregiver_xid,
+ viewModel.getGeoFenceDetails("",
+ careGiverData.caregiver_xid + "",
"Bearer " + AppUtil.getCgToken(requireContext()),
this);
diff --git a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/CaregiverMainViewModel.java b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/CaregiverMainViewModel.java
index e3e49fa..0a98e07 100644
--- a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/CaregiverMainViewModel.java
+++ b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/CaregiverMainViewModel.java
@@ -64,10 +64,11 @@ public class CaregiverMainViewModel extends ViewModel {
cgHomeRepository.saveGeoFenceDetails(geoFenceDetails, token, geoFenceCallback);
}
- public void getGeoFenceDetails(int cg_xid,
+ public void getGeoFenceDetails(String p_id,
+ String cg_xid,
@NonNull String token,
@NonNull CgHomeContracts.GetGeoFenceCallback getGeoFenceCallback){
- cgHomeRepository.getGeoFenceDetails(cg_xid, token, getGeoFenceCallback);
+ cgHomeRepository.getGeoFenceDetails(p_id, cg_xid, token, getGeoFenceCallback);
}
public void updateCaregiverData(int cg_xid,
diff --git a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/CgDashboardApiService.java b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/CgDashboardApiService.java
index 8cf0e33..a45372d 100644
--- a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/CgDashboardApiService.java
+++ b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/CgDashboardApiService.java
@@ -18,11 +18,13 @@ import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.PartMap;
import retrofit2.http.Path;
+import retrofit2.http.Query;
public interface CgDashboardApiService {
- @GET("api/get-caregiver-patient-location-link/{id}")
- Call> getGeofenceDetails(@Path("id") int id,
+ @GET("api/get-caregiver-patient-location-link")
+ Call> getGeofenceDetails(@Query("patientId") String p_id,
+ @Query("caregiverId") String c_id,
@Header("Authorization") String token);
@POST("api/caregiver-patient-location-link")
diff --git a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/CgHomeRepository.java b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/CgHomeRepository.java
index b3ebb8d..86fc3cf 100644
--- a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/CgHomeRepository.java
+++ b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/CgHomeRepository.java
@@ -28,44 +28,45 @@ public class CgHomeRepository {
private final CgDashboardApiService dash_apiService;
- private CgHomeRepository(){
+ private CgHomeRepository() {
dash_apiService = RetrofitHelper.getRetrofit().create(CgDashboardApiService.class);
}
- public static synchronized CgHomeRepository getHomeRepository(){
- if (cgHomeRepository == null){
+ public static synchronized CgHomeRepository getHomeRepository() {
+ if (cgHomeRepository == null) {
cgHomeRepository = new CgHomeRepository();
}
return cgHomeRepository;
}
- public void getArticles(@NonNull ArticleContracts.GetArticleCallback getArticleCallback){
+ public void getArticles(@NonNull ArticleContracts.GetArticleCallback getArticleCallback) {
ArticlePresenter articlePresenter = ArticlePresenter.getArticlePresenter();
articlePresenter.getArticles(getArticleCallback);
}
- public void getGeoFenceDetails(int cg_xid,
+ public void getGeoFenceDetails(String p_id,
+ String cg_xid,
@NonNull String token,
- @NonNull CgHomeContracts.GetGeoFenceCallback getGeoFenceCallback){
+ @NonNull CgHomeContracts.GetGeoFenceCallback getGeoFenceCallback) {
- dash_apiService.getGeofenceDetails(cg_xid, token)
+ dash_apiService.getGeofenceDetails(p_id, cg_xid, token)
.enqueue(new Callback>() {
@Override
public void onResponse(Call> call, Response> response) {
- if (response.body() != null){
- if (response.body().status != 200){
+ if (response.body() != null) {
+ if (response.body().status != 200) {
getGeoFenceCallback.onGeofenceDetailsFetchFailed(new Exception(), response.body().message);
return;
}
- if (response.body().result == null){
+ if (response.body().result == null) {
getGeoFenceCallback.onGeofenceDetailsFetched(new GeoFenceDetails());
- }else{
+ } else {
getGeoFenceCallback.onGeofenceDetailsFetched(response.body().result);
}
- }else{
+ } else {
getGeoFenceCallback.onGeofenceDetailsFetchFailed(new Exception(), "Couldn't load GeoFence.");
}
}
@@ -80,20 +81,20 @@ public class CgHomeRepository {
public void saveGeoFenceDetails(@NonNull GeoFenceDetails geoFenceDetails,
@NonNull String token,
- @NonNull CgHomeContracts.SaveGeoFenceCallback geoFenceCallback){
+ @NonNull CgHomeContracts.SaveGeoFenceCallback geoFenceCallback) {
dash_apiService.saveGeoFenceDetails(geoFenceDetails, token)
.enqueue(new Callback>() {
@Override
public void onResponse(Call> call, Response> response) {
- if (response.body() != null){
- if (response.body().status != 200 || response.body().result == null){
+ if (response.body() != null) {
+ if (response.body().status != 200 || response.body().result == null) {
geoFenceCallback.onGeofenceDetailsSaveFailed(new Exception(), response.body().message);
return;
}
geoFenceCallback.onGeofenceDetailsSaved(response.body().result);
- }else{
+ } else {
geoFenceCallback.onGeofenceDetailsSaveFailed(new Exception(), "Please try again later.");
}
}
@@ -110,19 +111,19 @@ public class CgHomeRepository {
Map body,
MultipartBody.Part photo,
@NonNull String token,
- @NonNull CgHomeContracts.UpdateCaregiverDataCallback updateCaregiverDataCallback){
+ @NonNull CgHomeContracts.UpdateCaregiverDataCallback updateCaregiverDataCallback) {
dash_apiService.updateCaregiverData(cg_xid, body, photo, token)
.enqueue(new Callback>() {
@Override
public void onResponse(Call> call, Response> response) {
- if (response.body() != null){
- if (response.body().status != 200 || response.body().result == null){
+ if (response.body() != null) {
+ if (response.body().status != 200 || response.body().result == null) {
updateCaregiverDataCallback.onCaregiverDateUpdateFailed(new Exception(), response.body().message);
return;
}
updateCaregiverDataCallback.onCaregiverDataUpdated(response.body().result);
- }else{
+ } else {
updateCaregiverDataCallback.onCaregiverDateUpdateFailed(new Exception(), "Please try again later.");
}
}
@@ -138,19 +139,19 @@ public class CgHomeRepository {
Map body,
MultipartBody.Part photo,
String token,
- @NonNull CgHomeContracts.UpdatePatientDataCallback patientDataCallback){
+ @NonNull CgHomeContracts.UpdatePatientDataCallback patientDataCallback) {
dash_apiService.updatePatientData(patient_xid, body, photo, token)
.enqueue(new Callback>() {
@Override
public void onResponse(Call> call, Response> response) {
- if (response.body() != null){
- if (response.body().status != 200 || response.body().result == null){
+ if (response.body() != null) {
+ if (response.body().status != 200 || response.body().result == null) {
patientDataCallback.onPatientDataUpdateFailed(new Exception(), response.body().message);
return;
}
patientDataCallback.onPatientDataUpdated(response.body().result);
- }else{
+ } else {
patientDataCallback.onPatientDataUpdateFailed(new Exception(), "Please try again later.");
}
}
@@ -165,19 +166,19 @@ public class CgHomeRepository {
public void updatePatientAddress(int pat_id,
Map body,
@NonNull String token,
- @NonNull CgHomeContracts.UpdatePatientAddressCallback patientAddressCallback){
+ @NonNull CgHomeContracts.UpdatePatientAddressCallback patientAddressCallback) {
dash_apiService.updatePatientAddress(pat_id, body, token)
.enqueue(new Callback>() {
@Override
public void onResponse(Call> call, Response> response) {
- if (response.body() != null){
- if (response.body().status != 200 || response.body().result == null){
+ if (response.body() != null) {
+ if (response.body().status != 200 || response.body().result == null) {
patientAddressCallback.onPatientAddressUpdateFailed(new Exception(), response.body().message);
return;
}
patientAddressCallback.onPatientAddressUpdated(response.body().result);
- }else{
+ } else {
patientAddressCallback.onPatientAddressUpdateFailed(new Exception(), "Please try again later.");
}
}
@@ -190,22 +191,22 @@ public class CgHomeRepository {
}
public void updateCgPassword(int cg_xid,
- Map body,
- @NonNull String token,
- @NonNull CgHomeContracts.UpdateCgPasswordCallback passwordCallback){
+ Map body,
+ @NonNull String token,
+ @NonNull CgHomeContracts.UpdateCgPasswordCallback passwordCallback) {
dash_apiService.updateCgPassword(cg_xid, body, token)
.enqueue(new Callback>() {
@Override
public void onResponse(Call> call, Response> response) {
- if (response.body() != null){
- if (response.body().status != 200 || response.body().result == null){
+ if (response.body() != null) {
+ if (response.body().status != 200 || response.body().result == null) {
passwordCallback.onPasswordUpdateFailed(new Exception(), response.body().message);
return;
}
passwordCallback.onPasswordUpdated(response.body().result);
- }else{
+ } else {
passwordCallback.onPasswordUpdateFailed(new Exception(), "Please try again later.");
}
}
@@ -219,19 +220,19 @@ public class CgHomeRepository {
}
public void signOut(String token,
- @NonNull CgHomeContracts.SignOutCallback signOutCallback){
+ @NonNull CgHomeContracts.SignOutCallback signOutCallback) {
dash_apiService.signOut(token)
.enqueue(new Callback>() {
@Override
public void onResponse(Call> call, Response> response) {
- if (response.body() != null){
- if (response.body().status != 200){
+ if (response.body() != null) {
+ if (response.body().status != 200) {
signOutCallback.onSignOutFailed(new Exception(), response.body().message);
return;
}
signOutCallback.onSignOutSuccess();
- }else{
+ } else {
signOutCallback.onSignOutFailed(new Exception(), "Please try again later.");
}
}
diff --git a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/NotificationApiService.java b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/NotificationApiService.java
new file mode 100644
index 0000000..6cdd978
--- /dev/null
+++ b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/NotificationApiService.java
@@ -0,0 +1,18 @@
+package com.ssb.simplitend.caregiverdashboard.mvvm;
+
+import com.ssb.simplitend.welcome.welcomepatient.mvvm.models.CallResponse;
+
+import java.util.Map;
+
+import retrofit2.Call;
+import retrofit2.http.Body;
+import retrofit2.http.Header;
+import retrofit2.http.POST;
+
+public interface NotificationApiService {
+
+ @POST("api/send-out-of-geofence-notification")
+ Call> notifyOutOfGeoFence(@Body Map body,
+ @Header("Authorization") String token);
+
+}
diff --git a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/models/GeoFenceDetails.java b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/models/GeoFenceDetails.java
index 887d978..a3cbb83 100644
--- a/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/models/GeoFenceDetails.java
+++ b/app/src/main/java/com/ssb/simplitend/caregiverdashboard/mvvm/models/GeoFenceDetails.java
@@ -14,4 +14,19 @@ public class GeoFenceDetails implements Serializable {
public String updated_at;
public GeoFenceDetails(){}
+
+ @Override
+ public String toString() {
+ return "GeoFenceDetails{" +
+ "id=" + id +
+ ", caregiver_xid='" + caregiver_xid + '\'' +
+ ", patient_xid='" + patient_xid + '\'' +
+ ", location_name='" + location_name + '\'' +
+ ", radius='" + radius + '\'' +
+ ", type='" + type + '\'' +
+ ", message='" + message + '\'' +
+ ", created_at='" + created_at + '\'' +
+ ", updated_at='" + updated_at + '\'' +
+ '}';
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/ssb/simplitend/cg_geofencing/CgGeoFencingActivity.java b/app/src/main/java/com/ssb/simplitend/cg_geofencing/CgGeoFencingActivity.java
index 7c8c69a..b184025 100644
--- a/app/src/main/java/com/ssb/simplitend/cg_geofencing/CgGeoFencingActivity.java
+++ b/app/src/main/java/com/ssb/simplitend/cg_geofencing/CgGeoFencingActivity.java
@@ -450,6 +450,7 @@ public class CgGeoFencingActivity extends AppCompatActivity implements OnMapRead
public void onPatientAddressUpdated(@NonNull PatientData patientData) {
binding.updateBtnsView.setVisibility(View.GONE);
this.careGiverData.patientDetails = patientData;
+ this.patientData = patientData;
CaregiverDataCache.setCareGiverData(this.careGiverData);
progressDialog.dismiss();
Toast.makeText(this, "Patient's location updated.", Toast.LENGTH_SHORT).show();
diff --git a/app/src/main/java/com/ssb/simplitend/patient_dashboard/DashBoardActivity.java b/app/src/main/java/com/ssb/simplitend/patient_dashboard/DashBoardActivity.java
index fe53fc0..58125c9 100644
--- a/app/src/main/java/com/ssb/simplitend/patient_dashboard/DashBoardActivity.java
+++ b/app/src/main/java/com/ssb/simplitend/patient_dashboard/DashBoardActivity.java
@@ -1,33 +1,104 @@
package com.ssb.simplitend.patient_dashboard;
+import static com.ssb.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
+
+import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
+import android.util.Log;
+import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.lifecycle.ViewModelProvider;
import com.onesignal.Continue;
import com.onesignal.OneSignal;
import com.ssb.simplitend.R;
+import com.ssb.simplitend.apputils.AppUtil;
+import com.ssb.simplitend.apputils.PatientDataCache;
+import com.ssb.simplitend.caregiverdashboard.mvvm.CgHomeContracts;
+import com.ssb.simplitend.caregiverdashboard.mvvm.models.GeoFenceDetails;
+
+public class DashBoardActivity extends AppCompatActivity implements CgHomeContracts.GetGeoFenceCallback {
+
+ protected PatientMainViewModel viewModel;
+ public static final int LOCATION_REQUEST_CODE = 1001;
+
+ private GeoFenceDetails geoFenceDetails;
+
+ private boolean geofencing_verified = false;
-public class DashBoardActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dash_board_cp);
+ viewModel = new ViewModelProvider(this).get(PatientMainViewModel.class);
+
// requestPermission will show the native Android notification permission prompt.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU){
// requestPermission will show the native Android notification permission prompt.
+ geofencing_verified = false;
OneSignal.getNotifications().requestPermission(true, Continue.with(r -> {
+ geofencing_verified = true;
if (r.isSuccess()) {
- if (r.getData() != null) {
- // `requestPermission` completed successfully and the user has accepted permission
- }
- else {
- // `requestPermission` completed successfully but the user has rejected permission
- }
+ viewModel.getGeoFenceDetails("" + AppUtil.getPatientUid(this),
+ "", "Bearer " + AppUtil.getPatientToken(this),
+ this);
}
}));
+
+ if (!geofencing_verified){
+ viewModel.getGeoFenceDetails("" + AppUtil.getPatientUid(this),
+ "", "Bearer " + AppUtil.getPatientToken(this),
+ this);
+ }
+
+ }else{
+ viewModel.getGeoFenceDetails("" + AppUtil.getPatientUid(this),
+ "", "Bearer " + AppUtil.getPatientToken(this),
+ this);
+ }
+
+ }
+
+ private 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
+ viewModel.setGeofence(this, geoFenceDetails, patientData);
+ }else{
+ Log.d(GEOFENCE_TAG, "onGeofenceDetailsFetched: should not add patient geofence because GEOFENCE DETAILS: " + geoFenceDetails + " PATIENT DETAILS: " + patientData);
+ }
+ }
+ }), false);
+ }
+ }
+
+ @Override
+ public void onGeofenceDetailsFetched(@NonNull GeoFenceDetails geoFenceDetails) {
+ this.geoFenceDetails = geoFenceDetails;
+ validateAndAddGeofence(geoFenceDetails);
+ }
+
+ @Override
+ public void onGeofenceDetailsFetchFailed(Throwable throwable, String message) {
+ 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);
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/ssb/simplitend/patient_dashboard/PatientMainViewModel.java b/app/src/main/java/com/ssb/simplitend/patient_dashboard/PatientMainViewModel.java
new file mode 100644
index 0000000..910d052
--- /dev/null
+++ b/app/src/main/java/com/ssb/simplitend/patient_dashboard/PatientMainViewModel.java
@@ -0,0 +1,107 @@
+package com.ssb.simplitend.patient_dashboard;
+
+import static com.ssb.simplitend.patient_dashboard.DashBoardActivity.LOCATION_REQUEST_CODE;
+import static com.ssb.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_ID;
+import static com.ssb.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.util.Log;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresPermission;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+import androidx.lifecycle.ViewModel;
+
+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.ssb.simplitend.apputils.AppUtil;
+import com.ssb.simplitend.caregiverdashboard.mvvm.CgHomeContracts;
+import com.ssb.simplitend.caregiverdashboard.mvvm.CgHomeRepository;
+import com.ssb.simplitend.caregiverdashboard.mvvm.models.GeoFenceDetails;
+import com.ssb.simplitend.patientgeofencing.GeoFenceHelper;
+import com.ssb.simplitend.welcome.welcomepatient.mvvm.models.PatientData;
+
+public class PatientMainViewModel extends ViewModel {
+
+ private final CgHomeRepository cgHomeRepository;
+
+ public PatientMainViewModel() {
+ cgHomeRepository = CgHomeRepository.getHomeRepository();
+ }
+
+ public void setGeofence(Activity 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: REQUESTING FINE LOCATION PERMISSION" );
+ ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE);
+ return;
+ }
+
+ addGeoFence(latLng, radius, activity, geoFenceDetails.type);
+ }
+ }
+
+ public void getGeoFenceDetails(String p_id,
+ String cg_xid,
+ @NonNull String token,
+ @NonNull CgHomeContracts.GetGeoFenceCallback getGeoFenceCallback){
+ cgHomeRepository.getGeoFenceDetails(p_id, cg_xid, token, getGeoFenceCallback);
+ }
+
+ @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION)
+ private void addGeoFence(@NonNull LatLng latLng, float GEOFENCING_RADIUS , Activity activity, String unit) {
+ GeoFenceHelper geoFenceHelper = new GeoFenceHelper(activity);
+ GeofencingClient geofencingClient = LocationServices.getGeofencingClient(activity);
+
+ // 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,
+ "We understand your privacy.\nTo enable Geofencing we need to access your location while the app is closed.\nKindly click on the Settings button below 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.");
+ });
+ return;
+ }
+ }
+
+ 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.");
+ AppUtil.updatePatientGeofence(activity, latLng.latitude+"", latLng.longitude+"",
+ GEOFENCING_RADIUS+"", unit);
+ })
+ .addOnFailureListener(e -> Log.d(GEOFENCE_TAG, "onFailure: Geofence couldn't be added: " + e.getLocalizedMessage()));
+
+ }
+}
diff --git a/app/src/main/java/com/ssb/simplitend/patientgeofencing/GeoFenceBroadcastReceiver.java b/app/src/main/java/com/ssb/simplitend/patientgeofencing/GeoFenceBroadcastReceiver.java
new file mode 100644
index 0000000..7288028
--- /dev/null
+++ b/app/src/main/java/com/ssb/simplitend/patientgeofencing/GeoFenceBroadcastReceiver.java
@@ -0,0 +1,77 @@
+package com.ssb.simplitend.patientgeofencing;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.google.android.gms.location.Geofence;
+import com.google.android.gms.location.GeofencingEvent;
+import com.ssb.simplitend.apputils.AppUtil;
+import com.ssb.simplitend.apputils.RetrofitHelper;
+import com.ssb.simplitend.caregiverdashboard.mvvm.NotificationApiService;
+import com.ssb.simplitend.welcome.welcomepatient.mvvm.models.CallResponse;
+
+import static com.ssb.simplitend.patientgeofencing.GeoFenceHelper.GEOFENCE_TAG;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class GeoFenceBroadcastReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
+
+ if (geofencingEvent == null || geofencingEvent.hasError()) {
+ Log.d(GEOFENCE_TAG, "onReceive: Couldn't add geofence");
+ return;
+ }
+
+ int transition_type = geofencingEvent.getGeofenceTransition();
+
+ switch (transition_type) {
+ case Geofence.GEOFENCE_TRANSITION_DWELL:
+ Log.d(GEOFENCE_TAG, "onReceive: DWELL");
+ break;
+ case Geofence.GEOFENCE_TRANSITION_ENTER:
+ Log.d(GEOFENCE_TAG, "onReceive: ENTER");
+ break;
+ case Geofence.GEOFENCE_TRANSITION_EXIT:
+ Log.d(GEOFENCE_TAG, "onReceive: EXIT");
+ notifyOutOfGeofence(context);
+ break;
+ }
+ }
+
+ private void notifyOutOfGeofence(Context context) {
+ Log.d(GEOFENCE_TAG, "Sending notification to patient");
+ NotificationApiService apiService = RetrofitHelper.getRetrofit().create(NotificationApiService.class);
+
+ Map body = new HashMap<>();
+ body.put("patient_id", AppUtil.getPatientUid(context) + "");
+
+ apiService.notifyOutOfGeoFence(body, "Bearer " + AppUtil.getPatientToken(context))
+ .enqueue(new Callback>() {
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ if (response.code() == 200){
+ Log.d(GEOFENCE_TAG, "OUT OF GEOFENCE NOTIFICATION SENT SUCCESSFULLY.");
+ }else{
+ Log.d(GEOFENCE_TAG, "Couldn't notify patient " + response.message());
+ }
+ }
+
+ @Override
+ public void onFailure(Call> call, Throwable t) {
+ Log.d(GEOFENCE_TAG, "Couldn't notify patient due to " + t);
+ }
+ });
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ssb/simplitend/patientgeofencing/GeoFenceHelper.java b/app/src/main/java/com/ssb/simplitend/patientgeofencing/GeoFenceHelper.java
new file mode 100644
index 0000000..9eb819f
--- /dev/null
+++ b/app/src/main/java/com/ssb/simplitend/patientgeofencing/GeoFenceHelper.java
@@ -0,0 +1,63 @@
+package com.ssb.simplitend.patientgeofencing;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+
+import com.google.android.gms.location.Geofence;
+import com.google.android.gms.location.GeofencingRequest;
+import com.google.android.gms.maps.model.LatLng;
+
+public class GeoFenceHelper extends ContextWrapper {
+
+ public static final String GEOFENCE_TAG = "PATIENT_GEOFENCE";
+ private PendingIntent pendingIntent;
+
+ public static final int BROADCAST_REQUEST_CODE = 10001;
+ public static final String GEOFENCE_ACTION = "com.simplitend.ACTION_GEOFENCE";
+
+ public static final String GEOFENCE_ID = "com.simplitent.PATIENT_GEOFENCE";
+
+ public GeoFenceHelper(Context base) {
+ super(base);
+ }
+
+ public GeofencingRequest getGeoFencingRequest(Geofence geofence){
+ return new GeofencingRequest.Builder()
+ .addGeofence(geofence)
+ .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_EXIT)
+ .build();
+ }
+
+ public Geofence getGeoFence(@NonNull String GEOFENCE_ID,
+ @NonNull LatLng latLng, float radius, int transitionType){
+ return new Geofence.Builder()
+ .setCircularRegion(latLng.latitude, latLng.longitude, radius)
+ .setRequestId(GEOFENCE_ID)
+ .setTransitionTypes(transitionType)
+ .setExpirationDuration(Geofence.NEVER_EXPIRE)
+ .setLoiteringDelay(5000) // This does nothing if the transition is not DWELL
+ .build();
+ }
+
+ public synchronized PendingIntent getPendingIntent(){
+ if (pendingIntent != null){
+ return pendingIntent;
+ }
+
+ Intent intent = new Intent(this, GeoFenceBroadcastReceiver.class);
+ intent.setAction(GEOFENCE_ACTION);
+
+ if(Build.VERSION.SDK_INT > 30){
+ pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
+ } else{
+ pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+
+ return pendingIntent;
+ }
+}