Skip to content

Commit 349fdec

Browse files
committed
Add background location support for api 29
* Add new background permission request * Request for background permission after fine or coarse is granted, for android 11
1 parent 93922da commit 349fdec

File tree

6 files changed

+64
-13
lines changed

6 files changed

+64
-13
lines changed

Examples/OneSignalDemo/app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ dependencies {
4545
// manifest merger conflicts
4646
// implementation 'com.onesignal:OneSignal:3.12.6'
4747

48+
implementation 'com.google.android.gms:play-services-location:[17.0.0, 17.99.99]'
4849
// glide:4.9.0 is the last version before going to AndroidX
4950
// glide:4.10.0 is the first version using AndroidX
5051
implementation 'com.github.bumptech.glide:glide:[4.10.0, 4.99.99]'

Examples/OneSignalDemo/app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
99
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
10+
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
1011

1112
<application
1213
android:name=".application.MainApplication"

Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/MainActivityViewModel.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ public void onClick(View v) {
436436
locationSharedSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
437437
@Override
438438
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
439+
SharedPreferenceUtil.cacheLocationSharedStatus(context, isChecked);
439440
OneSignal.setLocationShared(isChecked);
440441
}
441442
});

OneSignalSDK/onesignal/src/main/java/com/onesignal/GMSLocationController.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ private static void initGoogleLocation() {
6969

7070
GMSLocationController.googleApiClient = new GoogleApiClientCompatProxy(googleApiClient);
7171
GMSLocationController.googleApiClient.connect();
72-
} else if (lastLocation != null)
72+
} else {
7373
fireCompleteForLocation(lastLocation);
74+
}
7475
}
7576
}
7677

@@ -124,13 +125,15 @@ public void onConnected(Bundle bundle) {
124125
synchronized (syncLock) {
125126
PermissionsActivity.answered = false;
126127

127-
if (googleApiClient == null || googleApiClient.realInstance() == null)
128+
if (googleApiClient == null || googleApiClient.realInstance() == null) {
129+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "GMSLocationController GoogleApiClientListener onConnected googleApiClient not available, returning");
128130
return;
131+
}
129132

130-
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "LocationController GoogleApiClientListener onConnected lastLocation: " + lastLocation);
133+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "GMSLocationController GoogleApiClientListener onConnected lastLocation: " + lastLocation);
131134
if (lastLocation == null) {
132135
lastLocation = FusedLocationApiWrapper.getLastLocation(googleApiClient.realInstance());
133-
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "LocationController GoogleApiClientListener lastLocation: " + lastLocation);
136+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "GMSLocationController GoogleApiClientListener lastLocation: " + lastLocation);
134137
if (lastLocation != null)
135138
fireCompleteForLocation(lastLocation);
136139
}
@@ -141,11 +144,13 @@ public void onConnected(Bundle bundle) {
141144

142145
@Override
143146
public void onConnectionSuspended(int i) {
147+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "GMSLocationController GoogleApiClientListener onConnectionSuspended i: " + i);
144148
fireFailedComplete();
145149
}
146150

147151
@Override
148152
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
153+
OneSignal.Log(OneSignal.LOG_LEVEL.DEBUG, "GMSLocationController GoogleApiClientListener onConnectionSuspended connectionResult: " + connectionResult);
149154
fireFailedComplete();
150155
}
151156
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/LocationController.java

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,18 @@ void onAnswered(OneSignal.PromptActionResult result) {}
111111
}
112112

113113
static boolean scheduleUpdate(Context context) {
114-
if (!hasLocationPermission(context) || !OneSignal.isLocationShared())
114+
if (!hasLocationPermission(context)) {
115+
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "LocationController scheduleUpdate not possible, location permission not enabled");
115116
return false;
116-
117+
}
118+
if (!OneSignal.isLocationShared()) {
119+
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "LocationController scheduleUpdate not possible, location shared not enabled");
120+
return false;
121+
}
117122
long lastTime = OneSignal.getTime().getCurrentTimeMillis() - getLastLocationTime();
118123
long minTime = 1_000 * (OneSignal.isInForeground() ? TIME_FOREGROUND_SEC : TIME_BACKGROUND_SEC);
124+
125+
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "LocationController scheduleUpdate lastTime: " + lastTime + " minTime: " + minTime);
119126
long scheduleTime = minTime - lastTime;
120127

121128
OneSignalSyncServiceUtils.scheduleLocationUpdateTask(context, scheduleTime);
@@ -124,7 +131,7 @@ static boolean scheduleUpdate(Context context) {
124131

125132
private static void setLastLocationTime(long time) {
126133
OneSignalPrefs.saveLong(OneSignalPrefs.PREFS_ONESIGNAL,
127-
OneSignalPrefs.PREFS_OS_LAST_LOCATION_TIME,time);
134+
OneSignalPrefs.PREFS_OS_LAST_LOCATION_TIME, time);
128135
}
129136

130137
private static long getLastLocationTime() {
@@ -192,13 +199,16 @@ static void getLocation(Context context, boolean promptLocation, boolean fallbac
192199
return;
193200
}
194201

202+
int locationBackgroundPermission = PackageManager.PERMISSION_DENIED;
195203
int locationCoarsePermission = PackageManager.PERMISSION_DENIED;
196204

197205
int locationFinePermission = ContextCompat.checkSelfPermission(context, "android.permission.ACCESS_FINE_LOCATION");
198206
if (locationFinePermission == PackageManager.PERMISSION_DENIED) {
199207
locationCoarsePermission = ContextCompat.checkSelfPermission(context, "android.permission.ACCESS_COARSE_LOCATION");
200208
locationCoarse = true;
201209
}
210+
if (Build.VERSION.SDK_INT >= 29)
211+
locationBackgroundPermission = ContextCompat.checkSelfPermission(context, "android.permission.ACCESS_BACKGROUND_LOCATION");
202212

203213
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
204214
if (locationFinePermission != PackageManager.PERMISSION_GRANTED && locationCoarsePermission != PackageManager.PERMISSION_GRANTED) {
@@ -210,22 +220,25 @@ static void getLocation(Context context, boolean promptLocation, boolean fallbac
210220
}
211221
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.PERMISSION_GRANTED);
212222
startGetLocation();
213-
}
214-
else { // Android 6.0+
223+
} else { // Android 6.0+
215224
if (locationFinePermission != PackageManager.PERMISSION_GRANTED) {
216225
try {
217226
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
218227
List<String> permissionList = Arrays.asList(packageInfo.requestedPermissions);
219228
OneSignal.PromptActionResult result = OneSignal.PromptActionResult.PERMISSION_DENIED;
220-
if (permissionList.contains("android.permission.ACCESS_FINE_LOCATION"))
229+
230+
if (permissionList.contains("android.permission.ACCESS_FINE_LOCATION")) {
221231
// ACCESS_FINE_LOCATION permission defined on Manifest, prompt for permission
222232
// If permission already given prompt will return positive, otherwise will prompt again or show settings
223233
requestPermission = "android.permission.ACCESS_FINE_LOCATION";
224-
else if (permissionList.contains("android.permission.ACCESS_COARSE_LOCATION")) {
234+
} else if (permissionList.contains("android.permission.ACCESS_COARSE_LOCATION")) {
225235
if (locationCoarsePermission != PackageManager.PERMISSION_GRANTED) {
226236
// ACCESS_COARSE_LOCATION permission defined on Manifest, prompt for permission
227237
// If permission already given prompt will return positive, otherwise will prompt again or show settings
228238
requestPermission = "android.permission.ACCESS_COARSE_LOCATION";
239+
} else if (Build.VERSION.SDK_INT >= 29 && permissionList.contains("android.permission.ACCESS_BACKGROUND_LOCATION")) {
240+
// ACCESS_BACKGROUND_LOCATION permission defined on Manifest, prompt for permission
241+
requestPermission = "android.permission.ACCESS_BACKGROUND_LOCATION";
229242
}
230243
} else {
231244
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.INFO, "Location permissions not added on AndroidManifest file");
@@ -252,11 +265,40 @@ else if (permissionList.contains("android.permission.ACCESS_COARSE_LOCATION")) {
252265
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.ERROR);
253266
e.printStackTrace();
254267
}
268+
} else if (Build.VERSION.SDK_INT >= 29 && locationBackgroundPermission != PackageManager.PERMISSION_GRANTED) {
269+
backgroundLocationPermissionLogic(context, promptLocation, fallbackToSettings);
270+
} else {
271+
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.PERMISSION_GRANTED);
272+
startGetLocation();
255273
}
256-
else {
274+
}
275+
}
276+
277+
/**
278+
* On Android 10 background location permission is needed
279+
* On Android 11 and greater, background location should be asked after fine and coarse permission
280+
* If background permission is asked at the same time as fine and coarse then both permission request are ignored
281+
* */
282+
private static void backgroundLocationPermissionLogic(Context context, boolean promptLocation, boolean fallbackToSettings) {
283+
try {
284+
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
285+
List<String> permissionList = Arrays.asList(packageInfo.requestedPermissions);
286+
287+
if (permissionList.contains("android.permission.ACCESS_BACKGROUND_LOCATION")) {
288+
// ACCESS_BACKGROUND_LOCATION permission defined on Manifest, prompt for permission
289+
requestPermission = "android.permission.ACCESS_BACKGROUND_LOCATION";
290+
}
291+
292+
if (requestPermission != null && promptLocation) {
293+
PermissionsActivity.startPrompt(fallbackToSettings);
294+
} else {
295+
// Fine permission already granted
257296
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.PERMISSION_GRANTED);
258297
startGetLocation();
259298
}
299+
} catch (PackageManager.NameNotFoundException e) {
300+
sendAndClearPromptHandlers(promptLocation, OneSignal.PromptActionResult.ERROR);
301+
e.printStackTrace();
260302
}
261303
}
262304

@@ -270,6 +312,7 @@ static void startGetLocation() {
270312
} else if (isHMSAvailable()) {
271313
HMSLocationController.startGetLocation();
272314
} else {
315+
OneSignal.Log(OneSignal.LOG_LEVEL.WARN, "LocationController startGetLocation not possible, no location dependency found");
273316
fireFailedComplete();
274317
}
275318
} catch (Throwable t) {

OneSignalSDK/onesignal/src/main/java/com/onesignal/PermissionsActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public void run() {
113113
if (granted) {
114114
LocationController.startGetLocation();
115115
} else {
116-
attemptToShowLocationPermissionSettings();
116+
attemptToShowLocationPermissionSettings();
117117
LocationController.fireFailedComplete();
118118
}
119119
}

0 commit comments

Comments
 (0)