Skip to content

Commit ae2ca03

Browse files
authored
Merge pull request #223 from Unity-Technologies/android-permission
Android notification permission API rework
2 parents f68953f + d434068 commit ae2ca03

File tree

5 files changed

+121
-82
lines changed

5 files changed

+121
-82
lines changed

TestProjects/Main/Assets/Scripts/AndroidTest.cs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -290,26 +290,16 @@ private void InstantiateAllTestButtons()
290290

291291
void RequestNotificationPermission()
292292
{
293-
var permission = AndroidNotificationCenter.UserPermissionToPost;
294-
if (permission == PermissionStatus.Allowed)
295-
m_LOGGER.Green("Already authorized");
296-
if (permission == PermissionStatus.DeniedDontAskAgain)
297-
m_LOGGER.Red("Denied, don't ask again");
298-
else
293+
var request = new PermissionRequest();
294+
switch (request.Status)
299295
{
300-
m_LOGGER.Blue("Requesting permission");
301-
permission = AndroidNotificationCenter.RequestPermissionToPost();
302-
switch (permission)
303-
{
304-
case PermissionStatus.Allowed:
305-
m_LOGGER.Green("Permission granted");
306-
break;
307-
case PermissionStatus.RequestPending:
308-
return;
309-
default:
310-
m_LOGGER.Red(permission.ToString());
311-
break;
312-
}
296+
case PermissionStatus.Allowed:
297+
m_LOGGER.Green("Already allowed");
298+
break;
299+
case PermissionStatus.Denied:
300+
case PermissionStatus.DeniedDontAskAgain:
301+
m_LOGGER.Red(request.Status.ToString());
302+
break;
313303
}
314304
}
315305

com.unity.mobile.notifications/Documentation~/Android.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@ After you create a notification channel, you can't change its behavior. For more
2323

2424
On devices that use Android versions prior to 8.0, this package emulates the same behavior by applying notification channel properties, such as `Importance`, to individual notifications.
2525

26+
## Request permission to post notifications
27+
28+
Starting with Android 13.0 (API level 33) notifications can not be posted without users permission. They can still be scheduled, but will work silently with no UI shown to the user. You can request the permission by running this method in the coroutine:
29+
30+
```c#
31+
IEnumerator RequestNotificationPermission()
32+
{
33+
var request = new PermissionRequest();
34+
while (request.Status == PermissionStatus.RequestPending)
35+
yield return null;
36+
// here use request.Status to determine users response
37+
}
38+
```
39+
2640
## Manage notifications
2741

2842
This package provides a set of APIs to manage notifications. These APIs allow you to perform actions such as sending, updating, and deleting notifications. For more notification-related APIs, see [AndroidNotificationCenter](../api/Unity.Notifications.Android.AndroidNotificationCenter.html).

com.unity.mobile.notifications/Runtime/Android/AndroidNotificationCenter.cs

Lines changed: 2 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -14,37 +14,6 @@
1414

1515
namespace Unity.Notifications.Android
1616
{
17-
/// <summary>
18-
/// Represents a status of the Android runtime permission.
19-
/// </summary>
20-
public enum PermissionStatus
21-
{
22-
/// <summary>
23-
/// No permission as user was not prompted for it.
24-
/// </summary>
25-
NotRequested = 0,
26-
27-
/// <summary>
28-
/// User gave permission.
29-
/// </summary>
30-
Allowed = 1,
31-
32-
/// <summary>
33-
/// User denied permission.
34-
/// </summary>
35-
Denied = 2,
36-
37-
/// <summary>
38-
/// User denied permission and expressed intent to not be prompted again.
39-
/// </summary>
40-
DeniedDontAskAgain = 3,
41-
42-
/// <summary>
43-
/// A request for permission was made and user hasn't responded yet.
44-
/// </summary>
45-
RequestPending = 4,
46-
}
47-
4817
/// <summary>
4918
/// Current status of a scheduled notification, can be queried using CheckScheduledNotificationStatus.
5019
/// </summary>
@@ -568,7 +537,7 @@ public static JniMethodID FindMethod(AndroidJavaClass clazz, string name, string
568537
public class AndroidNotificationCenter
569538
{
570539
private static int API_POST_NOTIFICATIONS_PERMISSION_REQUIRED = 33;
571-
private static string PERMISSION_POST_NOTIFICATIONS = "android.permission.POST_NOTIFICATIONS";
540+
internal static string PERMISSION_POST_NOTIFICATIONS = "android.permission.POST_NOTIFICATIONS";
572541

573542
/// <summary>
574543
/// A PlayerPrefs key used to save users reply to POST_NOTIFICATIONS request (integer value of the PermissionStatus).
@@ -627,7 +596,7 @@ public static bool Initialize()
627596
return s_Initialized;
628597
}
629598

630-
static void SetPostPermissionSetting(PermissionStatus status)
599+
internal static void SetPostPermissionSetting(PermissionStatus status)
631600
{
632601
PlayerPrefs.SetInt(SETTING_POST_NOTIFICATIONS_PERMISSION, (int)status);
633602
}
@@ -668,36 +637,6 @@ public static PermissionStatus UserPermissionToPost
668637
}
669638
}
670639

671-
/// <summary>
672-
/// Request user permission to post notifications.
673-
/// Before Android 13 (API 33) will allow immediately.
674-
/// May succeed or fail immediately. Users response is saved to PlayerPrefs.
675-
/// Respects users wish to not be asked again.
676-
/// </summary>
677-
/// <returns>PermissionStatus.RequestPending if user is prompted for permission or immediately known reply.</returns>
678-
/// <seealso cref="SETTING_POST_NOTIFICATIONS_PERMISSION"/>
679-
public static PermissionStatus RequestPermissionToPost()
680-
{
681-
var permissionStatus = UserPermissionToPost;
682-
if (permissionStatus == PermissionStatus.Allowed)
683-
return permissionStatus;
684-
if (permissionStatus == PermissionStatus.DeniedDontAskAgain)
685-
return permissionStatus;
686-
// Can only request permission if applications target SDK is 33, not actual device SDK
687-
if (s_TargetApiLevel < API_POST_NOTIFICATIONS_PERMISSION_REQUIRED)
688-
{
689-
// don't change setting here, in case app gets updated
690-
return PermissionStatus.DeniedDontAskAgain;
691-
}
692-
693-
var callbacks = new PermissionCallbacks();
694-
callbacks.PermissionGranted += (unused) => SetPostPermissionSetting(PermissionStatus.Allowed);
695-
callbacks.PermissionDenied += (unused) => SetPostPermissionSetting(PermissionStatus.Denied);
696-
callbacks.PermissionDeniedAndDontAskAgain += (unused) => SetPostPermissionSetting(PermissionStatus.DeniedDontAskAgain);
697-
Permission.RequestUserPermission(PERMISSION_POST_NOTIFICATIONS, callbacks);
698-
return PermissionStatus.RequestPending;
699-
}
700-
701640
/// <summary>
702641
/// Creates a notification channel that notifications can be posted to.
703642
/// Notification channel settings can be changed by users on devices running Android 8.0 and above.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using UnityEngine.Android;
2+
3+
namespace Unity.Notifications.Android
4+
{
5+
/// <summary>
6+
/// Represents a status of the Android runtime permission.
7+
/// </summary>
8+
public enum PermissionStatus
9+
{
10+
/// <summary>
11+
/// No permission as user was not prompted for it.
12+
/// </summary>
13+
NotRequested = 0,
14+
15+
/// <summary>
16+
/// User gave permission.
17+
/// </summary>
18+
Allowed = 1,
19+
20+
/// <summary>
21+
/// User denied permission.
22+
/// </summary>
23+
Denied = 2,
24+
25+
/// <summary>
26+
/// User denied permission and expressed intent to not be prompted again.
27+
/// </summary>
28+
DeniedDontAskAgain = 3,
29+
30+
/// <summary>
31+
/// A request for permission was made and user hasn't responded yet.
32+
/// </summary>
33+
RequestPending = 4,
34+
}
35+
36+
/// <summary>
37+
/// A class to request permission to post notifications.
38+
/// Before Android 13 (API 33) it is not required and Status will become Allowed immediately.
39+
/// May succeed or fail immediately. Users response is saved to PlayerPrefs.
40+
/// Respects users wish to not be asked again.
41+
/// </summary>
42+
/// <seealso cref="AndroidNotificationCenter.UserPermissionToPost"/>
43+
/// <seealso cref="AndroidNotificationCenter.SETTING_POST_NOTIFICATIONS_PERMISSION"/>
44+
public class PermissionRequest
45+
{
46+
/// <summary>
47+
/// The status of this request.
48+
/// Value other than RequestPending means request has completed.
49+
/// </summary>
50+
public PermissionStatus Status { get; set; }
51+
52+
/// <summary>
53+
/// Create a new request.
54+
/// Will show user a dialog asking for permission if that is required to post notifications and user hasn't permanently denied it already.
55+
/// </summary>
56+
/// <see cref="PermissionStatus.DeniedDontAskAgain"/>
57+
public PermissionRequest()
58+
{
59+
Status = AndroidNotificationCenter.UserPermissionToPost;
60+
switch (Status)
61+
{
62+
case PermissionStatus.NotRequested:
63+
case PermissionStatus.Denied:
64+
Status = PermissionStatus.RequestPending;
65+
RequestPermission();
66+
break;
67+
}
68+
}
69+
70+
void RequestPermission()
71+
{
72+
var callbacks = new PermissionCallbacks();
73+
callbacks.PermissionGranted += (unused) => PermissionResponse(PermissionStatus.Allowed);
74+
callbacks.PermissionDenied += (unused) => PermissionResponse(PermissionStatus.Denied);
75+
callbacks.PermissionDeniedAndDontAskAgain += (unused) => PermissionResponse(PermissionStatus.DeniedDontAskAgain);
76+
Permission.RequestUserPermission(AndroidNotificationCenter.PERMISSION_POST_NOTIFICATIONS, callbacks);
77+
}
78+
79+
void PermissionResponse(PermissionStatus status)
80+
{
81+
Status = status;
82+
AndroidNotificationCenter.SetPostPermissionSetting(status);
83+
}
84+
}
85+
}

com.unity.mobile.notifications/Runtime/Android/NotificationPermission.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)