Skip to content

Commit d400283

Browse files
authored
Merge pull request #1607 from OneSignal/add/notification_permission_prompting_callback_and_iam
[Add] notification permission prompting callback and In-App Message support
2 parents ec70036 + 550caa3 commit d400283

File tree

5 files changed

+119
-13
lines changed

5 files changed

+119
-13
lines changed

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -560,8 +560,17 @@ private void setupSubscriptionSwitch() {
560560

561561
subscriptionSwitch.setOnClickListener(v -> {
562562
OneSignal.disablePush(!subscriptionSwitch.isChecked());
563-
if (subscriptionSwitch.isChecked())
564-
OneSignal.promptForPushNotifications(true);
563+
if (subscriptionSwitch.isChecked()) {
564+
OneSignal.promptForPushNotifications(
565+
true,
566+
new OneSignal.PromptForPushNotificationPermissionResponseHandler() {
567+
@Override
568+
public void response(boolean accepted) {
569+
System.out.println("APP promptForPushNotifications:" + this + ":accepted: " + accepted);
570+
}
571+
}
572+
);
573+
}
565574
});
566575
}
567576

OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationPermissionController.kt

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,42 @@
2828
package com.onesignal
2929

3030
import android.os.Build
31+
import androidx.annotation.ChecksSdkIntAtLeast
3132

3233
object NotificationPermissionController : PermissionsActivity.PermissionCallback {
3334
private const val PERMISSION_TYPE = "NOTIFICATION"
3435
private const val ANDROID_PERMISSION_STRING = "android.permission.POST_NOTIFICATIONS"
3536

37+
private val callbacks:
38+
MutableSet<OneSignal.PromptForPushNotificationPermissionResponseHandler> = HashSet()
39+
3640
init {
3741
PermissionsActivity.registerAsCallback(PERMISSION_TYPE, this)
3842
}
3943

40-
fun prompt(fallbackToSettings: Boolean) {
41-
// TODO: Android 13 Beta 1 reports as 32 instead of 33, update to 33 once Google fixes this
42-
if (Build.VERSION.SDK_INT < 32)
44+
@ChecksSdkIntAtLeast(api = 33)
45+
val supportsNativePrompt =
46+
Build.VERSION.SDK_INT > 32 &&
47+
OSUtils.getTargetSdkVersion(OneSignal.appContext) > 32
48+
49+
fun prompt(
50+
fallbackToSettings: Boolean,
51+
callback: OneSignal.PromptForPushNotificationPermissionResponseHandler?,
52+
) {
53+
if (callback != null) callbacks.add(callback)
54+
55+
if (notificationsEnabled()) {
56+
fireCallBacks(true)
57+
return
58+
}
59+
60+
if (!supportsNativePrompt) {
61+
if (fallbackToSettings)
62+
showFallbackAlertDialog()
63+
else
64+
fireCallBacks(false)
4365
return
66+
}
4467

4568
PermissionsActivity.startPrompt(
4669
fallbackToSettings,
@@ -52,14 +75,21 @@ object NotificationPermissionController : PermissionsActivity.PermissionCallback
5275

5376
override fun onAccept() {
5477
OneSignal.refreshNotificationPermissionState()
78+
fireCallBacks(true)
5579
}
5680

5781
override fun onReject(fallbackToSettings: Boolean) {
58-
if (fallbackToSettings) showFallbackAlertDialog()
82+
val fallbackShown =
83+
if (fallbackToSettings)
84+
showFallbackAlertDialog()
85+
else
86+
false
87+
if (!fallbackShown) fireCallBacks(false)
5988
}
6089

61-
private fun showFallbackAlertDialog() {
62-
val activity = OneSignal.getCurrentActivity() ?: return
90+
// Returns true if dialog was shown
91+
private fun showFallbackAlertDialog(): Boolean {
92+
val activity = OneSignal.getCurrentActivity() ?: return false
6393
AlertDialogPrepromptForAndroidSettings.show(
6494
activity,
6595
activity.getString(R.string.notification_permission_name_for_title),
@@ -69,8 +99,22 @@ object NotificationPermissionController : PermissionsActivity.PermissionCallback
6999
NavigateToAndroidSettingsForNotifications.show(activity)
70100
}
71101
override fun onDecline() {
102+
fireCallBacks(false)
72103
}
73104
}
74105
)
106+
return true
75107
}
108+
109+
// Fires callbacks and clears them to ensure each is only called once.
110+
private fun fireCallBacks(accepted: Boolean) {
111+
callbacks.forEach { it.response(accepted) }
112+
callbacks.clear()
113+
}
114+
115+
fun onAppForegrounded() {
116+
fireCallBacks(notificationsEnabled())
117+
}
118+
119+
private fun notificationsEnabled() = OSUtils.areNotificationsEnabled(OneSignal.appContext)
76120
}

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
import java.util.ArrayList;
1111
import java.util.List;
1212

13-
import static com.onesignal.OSInAppMessageLocationPrompt.LOCATION_PROMPT_KEY;
14-
1513
public class OSInAppMessageAction {
1614

1715
private static final String ID = "id";
@@ -117,8 +115,14 @@ private void parseOutcomes(JSONObject json) throws JSONException {
117115
private void parsePrompts(JSONObject json) throws JSONException {
118116
JSONArray promptsJsonArray = json.getJSONArray(PROMPTS);
119117
for (int i = 0; i < promptsJsonArray.length(); i++) {
120-
if (promptsJsonArray.get(i).equals(LOCATION_PROMPT_KEY) ) {
121-
prompts.add(new OSInAppMessageLocationPrompt());
118+
String promptType = promptsJsonArray.getString(i);
119+
switch (promptType) {
120+
case OSInAppMessagePushPrompt.PUSH_PROMPT_KEY:
121+
prompts.add(new OSInAppMessagePushPrompt());
122+
break;
123+
case OSInAppMessageLocationPrompt.LOCATION_PROMPT_KEY:
124+
prompts.add(new OSInAppMessageLocationPrompt());
125+
break;
122126
}
123127
}
124128
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.onesignal;
2+
3+
public class OSInAppMessagePushPrompt extends OSInAppMessagePrompt {
4+
5+
static final String PUSH_PROMPT_KEY = "push";
6+
7+
@Override
8+
void handlePrompt(OneSignal.OSPromptActionCompletionCallback callback) {
9+
OneSignal.promptForPushNotifications(
10+
true,
11+
accepted -> {
12+
OneSignal.PromptActionResult result = accepted ?
13+
OneSignal.PromptActionResult.PERMISSION_GRANTED :
14+
OneSignal.PromptActionResult.PERMISSION_DENIED;
15+
callback.onCompleted(result);
16+
}
17+
);
18+
}
19+
20+
@Override
21+
String getPromptKey() {
22+
return PUSH_PROMPT_KEY;
23+
}
24+
25+
}

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,13 @@ public interface PostNotificationResponseHandler {
349349
void onFailure(JSONObject response);
350350
}
351351

352+
/**
353+
* Fires when the User accepts or declines the notification permission prompt.
354+
*/
355+
public interface PromptForPushNotificationPermissionResponseHandler {
356+
void response(boolean accepted);
357+
}
358+
352359
interface EntryStateListener {
353360
// Fire with the last appEntryState that just ended.
354361
void onEntryStateChange(AppEntryAction appEntryState);
@@ -1400,6 +1407,7 @@ static void onAppFocus() {
14001407
}
14011408

14021409
LocationController.onFocusChange();
1410+
NotificationPermissionController.INSTANCE.onAppForegrounded();
14031411

14041412
if (OSUtils.shouldLogMissingAppIdError(appId))
14051413
return;
@@ -2837,7 +2845,23 @@ public static void promptForPushNotifications() {
28372845
* settings if they have declined before.
28382846
*/
28392847
public static void promptForPushNotifications(boolean fallbackToSettings) {
2840-
NotificationPermissionController.INSTANCE.prompt(fallbackToSettings);
2848+
promptForPushNotifications(fallbackToSettings, null);
2849+
}
2850+
2851+
/**
2852+
* On Android 13 shows the system notification permission prompt to enable displaying
2853+
* notifications. This is required for apps that target Android API level 33 / "Tiramisu"
2854+
* to subscribe the device for push notifications.
2855+
*
2856+
* @param fallbackToSettings whether to show a Dialog to direct users to the App's notification
2857+
* settings if they have declined before.
2858+
* @param handler fires when the user declines ore accepts the notification permission prompt.
2859+
*/
2860+
public static void promptForPushNotifications(
2861+
boolean fallbackToSettings,
2862+
@Nullable PromptForPushNotificationPermissionResponseHandler handler
2863+
) {
2864+
NotificationPermissionController.INSTANCE.prompt(fallbackToSettings, handler);
28412865
}
28422866

28432867
/**

0 commit comments

Comments
 (0)