update: 新增 Notification 服务和对一个的 noti 查询功能
Signed-off-by: huyufei <yufei.hu@castbox.fm>main
parent
9024b8171c
commit
4e24169b25
|
|
@ -17,7 +17,9 @@
|
|||
"Google.Play.Review",
|
||||
"Google.Play.Common",
|
||||
"Guru.LitJson",
|
||||
"Unity.Advertisement.IosSupport"
|
||||
"Unity.Advertisement.IosSupport",
|
||||
"Unity.Notifications.Android",
|
||||
"Unity.Notifications.iOS"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1fef034d48ac449fb99531b40139954e
|
||||
timeCreated: 1718844748
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8c0dd2d4b63445c2828e05c10274d672
|
||||
timeCreated: 1718845536
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "GuruNotification.Editor",
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e75025463d0c436482bf4c3dab674315
|
||||
timeCreated: 1718845553
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d6dd827f370441718ca2e49f3f603e4e
|
||||
timeCreated: 1718845525
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
namespace Guru.Notification
|
||||
{
|
||||
using System;
|
||||
public interface INotificationAgent
|
||||
{
|
||||
void Init();
|
||||
|
||||
string GetStatus();
|
||||
|
||||
bool IsAllowed();
|
||||
|
||||
void RequestPermission(Action<string> callback = null);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 43e051a65e9b469b8b9e8a9f6b4be944
|
||||
timeCreated: 1718844775
|
||||
|
|
@ -0,0 +1,247 @@
|
|||
namespace Guru.Notification
|
||||
{
|
||||
using System;
|
||||
using UnityEngine;
|
||||
#if UNITY_ANDROID
|
||||
using UnityEngine.Android;
|
||||
using Unity.Notifications.Android;
|
||||
#endif
|
||||
|
||||
public class NotificationAgentAndroid : INotificationAgent
|
||||
{
|
||||
public const string FCM_DEFAULT_CHANNEL_ID = "fcm_default_channel";
|
||||
private const string STATUS_GRANTED = "granted";
|
||||
private const string STATUS_DENIDED = "denied";
|
||||
private const int REQUEST_PERMISSION_SDK_VERSION = 33;
|
||||
private const string PERMISSION_POST_NOTIFICATION = "android.permission.POST_NOTIFICATIONS";
|
||||
|
||||
private bool _initOnce = false;
|
||||
private string _notiStatus;
|
||||
private bool _isPluginReady = false;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
public void Init()
|
||||
{
|
||||
if (!_initOnce) return;
|
||||
|
||||
SetGrantStatus(false);
|
||||
#if UNITY_ANDROID
|
||||
InitPlugins();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取状态
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetStatus()
|
||||
{
|
||||
if (!_initOnce) Init();
|
||||
#if UNITY_ANDROID
|
||||
UpdateNotiStatus();
|
||||
#endif
|
||||
return _notiStatus;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置授权状态
|
||||
/// </summary>
|
||||
/// <param name="flag"></param>
|
||||
private void SetGrantStatus(bool flag = false)
|
||||
{
|
||||
_notiStatus = flag ? STATUS_GRANTED : STATUS_DENIDED;
|
||||
}
|
||||
|
||||
|
||||
public bool IsAllowed()
|
||||
{
|
||||
return _notiStatus == STATUS_GRANTED;
|
||||
}
|
||||
|
||||
public void RequestPermission(Action<string> callback = null)
|
||||
{
|
||||
#if UNITY_ANDROID
|
||||
RequestAndroidPermission(callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
// -------------------- Android 获取状态逻辑 --------------------
|
||||
|
||||
#if UNITY_ANDROID
|
||||
|
||||
private PermissionStatus _permissionStatus;
|
||||
|
||||
private void TryExecute(Action handler)
|
||||
{
|
||||
try
|
||||
{
|
||||
handler?.Invoke();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 初始化插件
|
||||
/// </summary>
|
||||
private void InitPlugins()
|
||||
{
|
||||
_isPluginReady = AndroidNotificationCenter.Initialize();
|
||||
|
||||
if (!_isPluginReady)
|
||||
{
|
||||
Debug.LogError($"[Noti][AND] --- AndroidNotificationCenter init failed!");
|
||||
// TODO: 处理初始化失败的情况
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateNotiStatus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新 Notification 状态码
|
||||
/// </summary>
|
||||
private void UpdateNotiStatus()
|
||||
{
|
||||
if (!_isPluginReady) return;
|
||||
|
||||
TryExecute(() =>
|
||||
{
|
||||
_permissionStatus = AndroidNotificationCenter.UserPermissionToPost;
|
||||
switch (_permissionStatus)
|
||||
{
|
||||
case PermissionStatus.Allowed:
|
||||
SetGrantStatus(true);
|
||||
break;
|
||||
default:
|
||||
_notiStatus = STATUS_DENIDED;
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private Action<string> _onPermissionCallback;
|
||||
private PermissionCallbacks _permissionCallbacks;
|
||||
private void RequestAndroidPermission(Action<string> callback = null)
|
||||
{
|
||||
if (!_isPluginReady) return;
|
||||
|
||||
_onPermissionCallback = callback;
|
||||
UpdateNotiStatus();
|
||||
|
||||
TryExecute(() =>
|
||||
{
|
||||
bool hasPerm = Permission.HasUserAuthorizedPermission(PERMISSION_POST_NOTIFICATION);
|
||||
var sdkInt = GetAndroidSDKVersion();
|
||||
if (sdkInt < REQUEST_PERMISSION_SDK_VERSION)
|
||||
{
|
||||
// 低版本处理方式
|
||||
if (_notiStatus == STATUS_GRANTED)
|
||||
{
|
||||
SetGrantStatus(true);
|
||||
// 已经允许了
|
||||
callback?.Invoke(_notiStatus);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_permissionStatus == PermissionStatus.NotRequested ||
|
||||
AndroidNotificationCenter.ShouldShowPermissionToPostRationale)
|
||||
{
|
||||
AndroidNotificationCenter.OpenNotificationSettings(FCM_DEFAULT_CHANNEL_ID); // 打开ChannelID
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (hasPerm)
|
||||
{
|
||||
SetGrantStatus(true);
|
||||
// 已经允许了
|
||||
callback?.Invoke(_notiStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 未允许
|
||||
// 则请求弹窗
|
||||
Permission.RequestUserPermission(PERMISSION_POST_NOTIFICATION, SetupPermissionCallbacks());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private PermissionCallbacks SetupPermissionCallbacks()
|
||||
{
|
||||
if(_permissionCallbacks != null) DisposePermissionCallbacks();
|
||||
_permissionCallbacks = new PermissionCallbacks();
|
||||
_permissionCallbacks.PermissionDenied += OnPermissionGranted;
|
||||
_permissionCallbacks.PermissionDeniedAndDontAskAgain += OnPermissionGranted;
|
||||
_permissionCallbacks.PermissionGranted += OnPermissionGranted;
|
||||
return _permissionCallbacks;
|
||||
}
|
||||
|
||||
private void DisposePermissionCallbacks()
|
||||
{
|
||||
if (_permissionCallbacks != null)
|
||||
{
|
||||
_permissionCallbacks.PermissionGranted -= OnPermissionGranted;
|
||||
_permissionCallbacks.PermissionDenied -= PermissionDenied;
|
||||
_permissionCallbacks.PermissionDeniedAndDontAskAgain -= PermissionDenied;
|
||||
_permissionCallbacks = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求通过
|
||||
/// </summary>
|
||||
/// <param name="permissionName"></param>
|
||||
private void OnPermissionGranted(string permissionName)
|
||||
{
|
||||
if (permissionName == PERMISSION_POST_NOTIFICATION)
|
||||
{
|
||||
_notiStatus = STATUS_GRANTED;
|
||||
_onPermissionCallback?.Invoke(_notiStatus);
|
||||
}
|
||||
|
||||
DisposePermissionCallbacks();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求拒绝
|
||||
/// </summary>
|
||||
/// <param name="permissionName"></param>
|
||||
private void PermissionDenied(string permissionName)
|
||||
{
|
||||
if (permissionName == PERMISSION_POST_NOTIFICATION)
|
||||
{
|
||||
_notiStatus = STATUS_DENIDED;
|
||||
_onPermissionCallback?.Invoke(_notiStatus);
|
||||
}
|
||||
|
||||
DisposePermissionCallbacks();
|
||||
}
|
||||
|
||||
private int GetAndroidSDKVersion()
|
||||
{
|
||||
int sdkInt = 999;
|
||||
TryExecute(() =>
|
||||
{
|
||||
using (AndroidJavaClass jc = new AndroidJavaClass("android.os.Build$VERSION"))
|
||||
{
|
||||
sdkInt = jc.GetStatic<int>("SDK_INT");
|
||||
Debug.LogWarning($"[SDK] --- Android SDK Version:{sdkInt}");
|
||||
}
|
||||
});
|
||||
return sdkInt;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 554fcea56ce74a80a2424e5c037ce6c0
|
||||
timeCreated: 1718844764
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
|
||||
|
||||
namespace Guru.Notification
|
||||
{
|
||||
using System;
|
||||
using UnityEngine;
|
||||
#if UNITY_IOS
|
||||
using System.Threading.Tasks;
|
||||
using Unity.Notifications.iOS;
|
||||
#endif
|
||||
|
||||
public class NotificationAgentIOS : INotificationAgent
|
||||
{
|
||||
|
||||
private const string STATUS_GRANTED = "granted";
|
||||
private const string STATUS_DENIDED = "denied";
|
||||
private const string STATUS_PROVISIONAL = "provisional";
|
||||
private const string STATUS_NOT_DETERMINED = "not_determined";
|
||||
|
||||
private static bool _initOnce;
|
||||
private static int _waitSeconds = 30;
|
||||
|
||||
|
||||
private string _notiStatus;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
if (_initOnce) return;
|
||||
_initOnce = true;
|
||||
|
||||
_notiStatus = STATUS_NOT_DETERMINED;
|
||||
#if UNITY_IOS
|
||||
InitPlugins();
|
||||
#endif
|
||||
}
|
||||
|
||||
public string GetStatus()
|
||||
{
|
||||
if (!_initOnce) Init();
|
||||
#if UNITY_IOS
|
||||
UpdateStatus();
|
||||
#endif
|
||||
return _notiStatus;
|
||||
}
|
||||
|
||||
public bool IsAllowed()
|
||||
{
|
||||
return _notiStatus == STATUS_GRANTED;
|
||||
}
|
||||
|
||||
public void RequestPermission(Action<string> callback = null)
|
||||
{
|
||||
if (!_initOnce) Init();
|
||||
#if UNITY_IOS
|
||||
RequestIOSPermission(callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_IOS
|
||||
|
||||
private void InitPlugins()
|
||||
{
|
||||
UpdateStatus();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 更新状态
|
||||
/// </summary>
|
||||
private void UpdateStatus()
|
||||
{
|
||||
var status = iOSNotificationCenter.GetNotificationSettings().AuthorizationStatus;
|
||||
switch (status)
|
||||
{
|
||||
case AuthorizationStatus.Authorized:
|
||||
_notiStatus = STATUS_GRANTED;
|
||||
break;
|
||||
case AuthorizationStatus.Denied:
|
||||
_notiStatus = STATUS_DENIDED;
|
||||
break;
|
||||
case AuthorizationStatus.NotDetermined:
|
||||
_notiStatus = STATUS_NOT_DETERMINED;
|
||||
break;
|
||||
case AuthorizationStatus.Provisional:
|
||||
_notiStatus = STATUS_PROVISIONAL;
|
||||
break;
|
||||
default:
|
||||
Debug.Log($"[SDK][Noti][iOS] --- Unmarked AuthorizationStatus: {status}");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求 IOS 的推送
|
||||
/// </summary>
|
||||
/// <param name="callback"></param>
|
||||
private async void RequestIOSPermission(Action<string> callback = null)
|
||||
{
|
||||
Debug.Log($"[SDK][Noti][iOS] --- RequestIOSPermission start");
|
||||
int timePassed = 0;
|
||||
using (var req = new AuthorizationRequest(AuthorizationOption.Alert | AuthorizationOption.Badge, true))
|
||||
{
|
||||
while (!req.IsFinished && timePassed < _waitSeconds)
|
||||
{
|
||||
timePassed++;
|
||||
await Task.Delay(1000);
|
||||
};
|
||||
|
||||
if (timePassed >= _waitSeconds)
|
||||
{
|
||||
Debug.LogWarning($"[SDK][Noti][iOS] --- RequestIOSPermission timeout");
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
callback?.Invoke(_notiStatus);
|
||||
Debug.Log($"[SDK][Noti][iOS] --- User Selected: {_notiStatus}");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5068c6e238e74251955320761c96182b
|
||||
timeCreated: 1718871877
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
|
||||
namespace Guru.Notification
|
||||
{
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// For Editor to use Notifications
|
||||
/// </summary>
|
||||
public class NotificationAgentStub: INotificationAgent
|
||||
{
|
||||
private const string STATUS_GRANTED = "granted";
|
||||
private const string STATUS_DENIDED = "denied";
|
||||
private const string STATUS_NOT_DETERMINED = "not_determined";
|
||||
|
||||
private Action<string> _onPermissionCallback;
|
||||
private float _delaySeconds = 1.0f;
|
||||
|
||||
private string EditorGrantedStatus
|
||||
{
|
||||
get => PlayerPrefs.GetString(nameof(EditorGrantedStatus), STATUS_NOT_DETERMINED);
|
||||
set => PlayerPrefs.SetString(nameof(EditorGrantedStatus), value);
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
Debug.Log($"[SDK][Noti][EDT] --- NotificationAgentStub Init: {EditorGrantedStatus}");
|
||||
}
|
||||
|
||||
public string GetStatus() => EditorGrantedStatus;
|
||||
|
||||
public bool IsAllowed()
|
||||
{
|
||||
return EditorGrantedStatus == STATUS_GRANTED;
|
||||
}
|
||||
|
||||
public void RequestPermission(Action<string> callback = null)
|
||||
{
|
||||
Debug.Log($"[SDK][Noti][EDT] --- RequestPermission ---");
|
||||
_onPermissionCallback = callback;
|
||||
DelayCallPermissionHandle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 延迟模拟回调
|
||||
/// </summary>
|
||||
private async void DelayCallPermissionHandle()
|
||||
{
|
||||
await Task.Delay((int)(1000 * _delaySeconds));
|
||||
EditorGrantedStatus = STATUS_GRANTED;
|
||||
_onPermissionCallback?.Invoke(EditorGrantedStatus);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6550e85d25634c46b7a57c490dcea173
|
||||
timeCreated: 1718850440
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
namespace Guru.Notification
|
||||
{
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 消息管理器
|
||||
/// </summary>
|
||||
public class NotificationService
|
||||
{
|
||||
// 服务版本号
|
||||
public const string Version = "0.0.1";
|
||||
|
||||
|
||||
// 初始化标志位
|
||||
private static bool _initOnce;
|
||||
|
||||
private static string DEFAULT_USER_STATUS = "not_determined";
|
||||
|
||||
|
||||
#region 初始化
|
||||
|
||||
private static INotificationAgent _agent;
|
||||
|
||||
internal static INotificationAgent Agent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_agent == null)
|
||||
{
|
||||
_agent = GetAgent();
|
||||
}
|
||||
return _agent;
|
||||
}
|
||||
}
|
||||
|
||||
private static INotificationAgent GetAgent()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
return new NotificationAgentStub();
|
||||
#elif UNITY_ANDROID
|
||||
return new NotificationAgentAndroid();
|
||||
#elif UNITY_IOS
|
||||
return new NotificationAgentIOS();
|
||||
#endif
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
public static void Initialize()
|
||||
{
|
||||
if (_initOnce) return;
|
||||
_initOnce = true;
|
||||
Agent?.Init(); // 初始化代理
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region 接口
|
||||
|
||||
/// <summary>
|
||||
/// 拉起 Noti 请求
|
||||
/// </summary>
|
||||
/// <param name="callback"></param>
|
||||
public static void RequestPermission(Action<string> callback = null)
|
||||
{
|
||||
if (Agent != null)
|
||||
{
|
||||
Agent.RequestPermission(callback);
|
||||
return;
|
||||
}
|
||||
callback?.Invoke(DEFAULT_USER_STATUS);
|
||||
}
|
||||
|
||||
public static bool IsPermissionGranted()
|
||||
{
|
||||
return Agent?.IsAllowed() ?? false;
|
||||
}
|
||||
|
||||
public static string GetStatus()
|
||||
{
|
||||
return Agent?.GetStatus() ?? DEFAULT_USER_STATUS;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e0f31750e8bc48a6a5e4f56ee2d5e1cc
|
||||
timeCreated: 1718846076
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
"dependencies": {
|
||||
"com.unity.ads.ios-support": "1.2.0",
|
||||
"com.unity.editorcoroutines": "1.0.0",
|
||||
"com.unity.mobile.notifications": "2.2.2",
|
||||
"com.unity.mobile.android-logcat": "1.3.2",
|
||||
"com.unity.purchasing": "4.10.0"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue