Skip to content

Commit 018a330

Browse files
committed
Update logic for detecting when to show fallback settings for requesting permissions. Detection requires persistence to preferences, which allows the addition of INotificationsManager.canRequestPermission.
1 parent fde36dc commit 018a330

File tree

8 files changed

+68
-10
lines changed

8 files changed

+68
-10
lines changed

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/activities/PermissionsActivity.kt

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ import com.onesignal.OneSignal
1010
import com.onesignal.common.AndroidSupportV4Compat
1111
import com.onesignal.core.R
1212
import com.onesignal.core.internal.permissions.impl.RequestPermissionService
13+
import com.onesignal.core.internal.preferences.IPreferencesService
14+
import com.onesignal.core.internal.preferences.PreferenceOneSignalKeys
15+
import com.onesignal.core.internal.preferences.PreferenceStores
1316

1417
class PermissionsActivity : Activity() {
1518
private var _requestPermissionService: RequestPermissionService? = null
19+
private var _preferenceService: IPreferencesService? = null
1620
private var permissionRequestType: String? = null
1721
private var androidPermissionString: String? = null
1822

@@ -21,6 +25,7 @@ class PermissionsActivity : Activity() {
2125
OneSignal.initWithContext(this)
2226

2327
_requestPermissionService = OneSignal.getService()
28+
_preferenceService = OneSignal.getService()
2429

2530
handleBundleParams(intent.extras)
2631
}
@@ -62,8 +67,8 @@ class PermissionsActivity : Activity() {
6267
private fun requestPermission(androidPermissionString: String?) {
6368
if (!_requestPermissionService!!.waiting) {
6469
_requestPermissionService!!.waiting = true
65-
_requestPermissionService!!.neverAskAgainClicked =
66-
!AndroidSupportV4Compat.ActivityCompat.shouldShowRequestPermissionRationale(
70+
_requestPermissionService!!.shouldShowRequestPermissionRationaleBeforeRequest =
71+
AndroidSupportV4Compat.ActivityCompat.shouldShowRequestPermissionRationale(
6772
this@PermissionsActivity,
6873
androidPermissionString
6974
)
@@ -107,14 +112,34 @@ class PermissionsActivity : Activity() {
107112
}
108113

109114
private fun shouldShowSettings(): Boolean {
110-
return (
111-
_requestPermissionService!!.fallbackToSettings &&
112-
_requestPermissionService!!.neverAskAgainClicked &&
113-
!AndroidSupportV4Compat.ActivityCompat.shouldShowRequestPermissionRationale(
115+
if (!_requestPermissionService!!.fallbackToSettings)
116+
return false;
117+
118+
// We want to show settings after the user has clicked "Don't Allow" 2 times.
119+
// After the first time shouldShowRequestPermissionRationale becomes true, after
120+
// the second time shouldShowRequestPermissionRationale becomes false again. We
121+
// look for the change from `true` -> `false`. When this happens we remember this
122+
// rejection, as the user will never be prompted again.
123+
if (_requestPermissionService!!.shouldShowRequestPermissionRationaleBeforeRequest) {
124+
if (!AndroidSupportV4Compat.ActivityCompat.shouldShowRequestPermissionRationale(
114125
this@PermissionsActivity,
115126
androidPermissionString
116127
)
117-
)
128+
) {
129+
_preferenceService!!.saveBool(
130+
PreferenceStores.ONESIGNAL,
131+
"${PreferenceOneSignalKeys.PREFS_OS_USER_REJECTED_PERMISSION_PREFIX}${androidPermissionString}",
132+
true
133+
)
134+
return false;
135+
}
136+
}
137+
138+
return _preferenceService!!.getBool(
139+
PreferenceStores.ONESIGNAL,
140+
"${PreferenceOneSignalKeys.PREFS_OS_USER_REJECTED_PERMISSION_PREFIX}$androidPermissionString",
141+
false
142+
)!!
118143
}
119144

120145
companion object {

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/permissions/impl/RequestPermissionService.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import com.onesignal.core.internal.application.IApplicationService
99
import com.onesignal.core.internal.permissions.IRequestPermissionService
1010

1111
internal class RequestPermissionService(
12-
private val _application: IApplicationService
12+
private val _application: IApplicationService,
1313
) : Activity(), IRequestPermissionService {
1414

1515
var waiting = false
1616
var fallbackToSettings = false
17-
var neverAskAgainClicked = false
17+
var shouldShowRequestPermissionRationaleBeforeRequest = false
1818
private val callbackMap = HashMap<String?, IRequestPermissionService.PermissionCallback>()
1919

2020
override fun registerAsCallback(

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/preferences/IPreferencesService.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ object PreferenceOneSignalKeys {
151151
*/
152152
const val PREFS_OS_LAST_LOCATION_TIME = "OS_LAST_LOCATION_TIME"
153153

154+
// Permissions
155+
/**
156+
* (Boolean) A prefix key for the permission state. When true, the user has rejected this
157+
* permission too many times and will not be prompted again.
158+
*/
159+
const val PREFS_OS_USER_REJECTED_PERMISSION_PREFIX = "USER_REJECTED_PERMISSION_"
160+
154161
// HTTP
155162
/**
156163
* (String) A prefix key for retrieving the ETAG for a given HTTP GET cache key. The cache

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/notifications/INotificationsManager.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ interface INotificationsManager {
99
*/
1010
val permission: Boolean
1111

12+
/**
13+
* Whether this app can request push notification permission.
14+
*/
15+
val canRequestPermission: Boolean
16+
1217
/**
1318
* Prompt the user for permission to push notifications. This will display the native
1419
* OS prompt to request push notification permission. If the user enables, a push

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/notifications/internal/MisconfiguredNotificationsManager.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import com.onesignal.notifications.IPermissionChangedHandler
1212
internal class MisconfiguredNotificationsManager : INotificationsManager {
1313
override val permission: Boolean
1414
get() = throw EXCEPTION
15+
override val canRequestPermission: Boolean
16+
get() = throw EXCEPTION
1517

1618
override suspend fun requestPermission(fallbackToSettings: Boolean): Boolean = throw EXCEPTION
1719
override fun removeNotification(id: Int) = throw EXCEPTION

OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/NotificationsManager.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ internal class NotificationsManager(
4545

4646
override var permission: Boolean = NotificationHelper.areNotificationsEnabled(_applicationService.appContext)
4747

48+
override val canRequestPermission: Boolean
49+
get() = _notificationPermissionController.canRequestPermission
50+
4851
private val _permissionChangedNotifier = EventProducer<IPermissionChangedHandler>()
4952

5053
init {

OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/permissions/INotificationPermissionController.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ import com.onesignal.common.events.IEventNotifier
3131

3232
internal interface INotificationPermissionController :
3333
IEventNotifier<INotificationPermissionChangedHandler> {
34+
/**
35+
* Whether this app can request push notification permission.
36+
*/
37+
val canRequestPermission: Boolean
38+
3439
/**
3540
* Prompt the user for notification permission. Note it is possible the application
3641
* will be killed while the permission prompt is being displayed to the user. When the

OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/permissions/impl/NotificationPermissionController.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ import com.onesignal.core.internal.application.ApplicationLifecycleHandlerBase
3636
import com.onesignal.core.internal.application.IApplicationService
3737
import com.onesignal.core.internal.permissions.AlertDialogPrepromptForAndroidSettings
3838
import com.onesignal.core.internal.permissions.IRequestPermissionService
39+
import com.onesignal.core.internal.preferences.IPreferencesService
40+
import com.onesignal.core.internal.preferences.PreferenceOneSignalKeys
41+
import com.onesignal.core.internal.preferences.PreferenceStores
3942
import com.onesignal.notifications.R
4043
import com.onesignal.notifications.internal.common.NotificationHelper
4144
import com.onesignal.notifications.internal.permissions.INotificationPermissionChangedHandler
@@ -44,13 +47,21 @@ import com.onesignal.notifications.internal.permissions.INotificationPermissionC
4447
internal class NotificationPermissionController(
4548
private val _application: IApplicationService,
4649
private val _requestPermission: IRequestPermissionService,
47-
private val _applicationService: IApplicationService
50+
private val _applicationService: IApplicationService,
51+
private val _preferenceService: IPreferencesService
4852
) : IRequestPermissionService.PermissionCallback,
4953
INotificationPermissionController {
5054

5155
private val _waiter = WaiterWithValue<Boolean>()
5256
private val _events = EventProducer<INotificationPermissionChangedHandler>()
5357

58+
override val canRequestPermission: Boolean
59+
get() = !_preferenceService.getBool(
60+
PreferenceStores.ONESIGNAL,
61+
"${PreferenceOneSignalKeys.PREFS_OS_USER_REJECTED_PERMISSION_PREFIX}${ANDROID_PERMISSION_STRING}",
62+
false
63+
)!!
64+
5465
init {
5566
_requestPermission.registerAsCallback(PERMISSION_TYPE, this)
5667
}

0 commit comments

Comments
 (0)