| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  | 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"; | 
					
						
							| 
									
										
										
										
											2024-06-21 06:01:33 +00:00
										 |  |  |         // private const string STATUS_NOT_DETERMINED = "not_determined"; | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |         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; | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         private string SavedNotiPermStatus | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             get => PlayerPrefs.GetString(nameof(SavedNotiPermStatus), ""); | 
					
						
							|  |  |  |             set => PlayerPrefs.SetString(nameof(SavedNotiPermStatus), value); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /// <summary> | 
					
						
							|  |  |  |         /// 初始化 | 
					
						
							|  |  |  |         /// </summary> | 
					
						
							|  |  |  |         public void Init() | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (!_initOnce) return; | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |             _initOnce = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             _notiStatus = STATUS_DENIDED; | 
					
						
							|  |  |  |             if (!string.IsNullOrEmpty(SavedNotiPermStatus)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 _notiStatus = SavedNotiPermStatus; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  | #if UNITY_ANDROID | 
					
						
							|  |  |  |             InitPlugins(); | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /// <summary> | 
					
						
							|  |  |  |         /// 获取状态 | 
					
						
							|  |  |  |         /// </summary> | 
					
						
							|  |  |  |         /// <returns></returns> | 
					
						
							|  |  |  |         public string GetStatus() | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (!_initOnce) Init(); | 
					
						
							|  |  |  | #if UNITY_ANDROID | 
					
						
							|  |  |  |             UpdateNotiStatus(); | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  |             return _notiStatus; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         /// <summary> | 
					
						
							|  |  |  |         /// 设置授权状态 | 
					
						
							|  |  |  |         /// </summary> | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |         /// <param name="status">授权状态</param> | 
					
						
							|  |  |  |         private void SetGrantStatus(string status) | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |             _notiStatus = status; | 
					
						
							|  |  |  |             SavedNotiPermStatus = status; | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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() | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-06-21 01:45:26 +00:00
										 |  |  |             AndroidNotificationCenter.Initialize(); | 
					
						
							|  |  |  |             Debug.Log($"[Noti][AND] --- Notification Service InitPlugins"); | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |              | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |             UpdateNotiStatus(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /// <summary> | 
					
						
							|  |  |  |         /// 更新 Notification 状态码 | 
					
						
							|  |  |  |         /// </summary> | 
					
						
							|  |  |  |         private void UpdateNotiStatus() | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-06-21 06:13:58 +00:00
										 |  |  |            | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |             TryExecute(() => | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 _permissionStatus = AndroidNotificationCenter.UserPermissionToPost; | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |                 var status = ""; | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |                 switch (_permissionStatus) | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |                     // case PermissionStatus.NotRequested: | 
					
						
							|  |  |  |                     //     _notiStatus = STATUS_NOT_DETERMINED; | 
					
						
							|  |  |  |                     //     break; | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |                     case PermissionStatus.Allowed: | 
					
						
							| 
									
										
										
										
											2024-06-25 14:34:18 +00:00
										 |  |  |                         status = STATUS_GRANTED;; | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |                         break; | 
					
						
							|  |  |  |                     default: | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |                         status = STATUS_DENIDED; | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |                         break; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 SetGrantStatus(status); | 
					
						
							| 
									
										
										
										
											2024-06-21 01:45:26 +00:00
										 |  |  |                 Debug.LogWarning($"[SDK][AND] --- UpdateNotiStatus:{_notiStatus}  |  UserPermissionToPost:{_permissionStatus}"); | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |             }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private Action<string> _onPermissionCallback; | 
					
						
							|  |  |  |         private PermissionCallbacks _permissionCallbacks; | 
					
						
							|  |  |  |         private void RequestAndroidPermission(Action<string> callback = null) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             UpdateNotiStatus(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |             if (_notiStatus == STATUS_GRANTED) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 callback?.Invoke(_notiStatus); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             _onPermissionCallback = callback; | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |             TryExecute(() => | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 var sdkInt = GetAndroidSDKVersion(); | 
					
						
							|  |  |  |                 if (sdkInt < REQUEST_PERMISSION_SDK_VERSION) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     // 低版本处理方式 | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |                     Debug.Log($"[SDK][Noti] --- #2 SDK {sdkInt} not requested -> open channel"); | 
					
						
							| 
									
										
										
										
											2024-06-24 10:40:20 +00:00
										 |  |  |                     AndroidNotificationCenter.RegisterNotificationChannel(new AndroidNotificationChannel(FCM_DEFAULT_CHANNEL_ID,  | 
					
						
							|  |  |  |                             FCM_DEFAULT_CHANNEL_ID, "", Importance.Default)); // 打开ChannelID | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |                     SetGrantStatus(STATUS_GRANTED); | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |                     // SDK 33 以上,请求弹窗 | 
					
						
							| 
									
										
										
										
											2024-06-21 06:13:58 +00:00
										 |  |  |                     bool hasPermission = Permission.HasUserAuthorizedPermission(PERMISSION_POST_NOTIFICATION); | 
					
						
							|  |  |  |                     if (hasPermission) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         SetGrantStatus(STATUS_GRANTED); | 
					
						
							|  |  |  |                         callback?.Invoke(STATUS_GRANTED); | 
					
						
							|  |  |  |                         return; | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2024-06-21 08:18:18 +00:00
										 |  |  |                     Debug.Log($"[SDK][Noti] --- #3 SDK {sdkInt} :: Ask Post Permission"); | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |                     Permission.RequestUserPermission(PERMISSION_POST_NOTIFICATION, SetupPermissionCallbacks()); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         private PermissionCallbacks SetupPermissionCallbacks() | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if(_permissionCallbacks != null) DisposePermissionCallbacks(); | 
					
						
							|  |  |  |             _permissionCallbacks = new PermissionCallbacks(); | 
					
						
							|  |  |  |             _permissionCallbacks.PermissionGranted += OnPermissionGranted; | 
					
						
							| 
									
										
										
										
											2024-06-21 03:25:18 +00:00
										 |  |  |             _permissionCallbacks.PermissionDenied += OnPermissionDenied; | 
					
						
							|  |  |  |             _permissionCallbacks.PermissionDeniedAndDontAskAgain += OnPermissionDenied; | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |             return _permissionCallbacks; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         private void DisposePermissionCallbacks() | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (_permissionCallbacks != null) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 _permissionCallbacks.PermissionGranted -= OnPermissionGranted; | 
					
						
							| 
									
										
										
										
											2024-06-21 03:25:18 +00:00
										 |  |  |                 _permissionCallbacks.PermissionDenied -= OnPermissionDenied; | 
					
						
							|  |  |  |                 _permissionCallbacks.PermissionDeniedAndDontAskAgain -= OnPermissionDenied; | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |                 _permissionCallbacks = null; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         /// <summary> | 
					
						
							|  |  |  |         /// 请求通过 | 
					
						
							|  |  |  |         /// </summary> | 
					
						
							|  |  |  |         /// <param name="permissionName"></param> | 
					
						
							|  |  |  |         private void OnPermissionGranted(string permissionName) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (permissionName == PERMISSION_POST_NOTIFICATION) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 _notiStatus = STATUS_GRANTED; | 
					
						
							|  |  |  |                 _onPermissionCallback?.Invoke(_notiStatus); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |             SetGrantStatus(STATUS_GRANTED); | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |             DisposePermissionCallbacks(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /// <summary> | 
					
						
							|  |  |  |         /// 请求拒绝 | 
					
						
							|  |  |  |         /// </summary> | 
					
						
							|  |  |  |         /// <param name="permissionName"></param> | 
					
						
							| 
									
										
										
										
											2024-06-21 03:25:18 +00:00
										 |  |  |         private void OnPermissionDenied(string permissionName) | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (permissionName == PERMISSION_POST_NOTIFICATION) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 _notiStatus = STATUS_DENIDED; | 
					
						
							|  |  |  |                 _onPermissionCallback?.Invoke(_notiStatus); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-06-21 05:15:50 +00:00
										 |  |  |             SetGrantStatus(STATUS_DENIDED); | 
					
						
							| 
									
										
										
										
											2024-06-20 10:20:38 +00:00
										 |  |  |             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 | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |