diff --git a/Runtime/GuruNoification/Editor/Android_PostCustomActivity.cs b/Runtime/GuruNoification/Editor/Android_PostCustomActivity.cs
new file mode 100644
index 0000000..5974496
--- /dev/null
+++ b/Runtime/GuruNoification/Editor/Android_PostCustomActivity.cs
@@ -0,0 +1,178 @@
+
+
+#if UNITY_ANDROID
+
+namespace Guru.Notification
+{
+    using System;
+    using System.IO;
+    using UnityEditor.Android;
+    using System.Xml;
+    
+    public class PostCustomActivity: IPostGenerateGradleAndroidProject
+    {
+        private const int POST_ORDER = 10;
+        private const string K_PREMISSION_POST_NOTIFICATIONS = "android.permission.POST_NOTIFICATIONS";
+        private const string K_CUSTOM_NOTIFICATION_ACTIVITY = "custom_notification_android_activity";
+        private const string V_DEFAULT_GURU_ACTIVITY = "com.google.firebase.messaging.MessageForwardingService";
+        const string K_ANDROID_NAMESPACE_URI = "http://schemas.android.com/apk/res/android";
+        
+        public int callbackOrder => POST_ORDER;
+
+        public void OnPostGenerateGradleAndroidProject(string path)
+        {
+            SetupAndroidManifest(path);
+        }
+        
+        /// 
+        /// 设置 Android Manifest
+        /// 
+        /// 
+        /// 
+        private void SetupAndroidManifest(string projectPath)
+        {
+            var manifestPath = $"{projectPath}/src/main/AndroidManifest.xml";
+            if (!File.Exists(manifestPath))
+                throw new FileNotFoundException($"'{manifestPath}' doesn't exist.");
+
+            XmlDocument manifestDoc = new XmlDocument();
+            manifestDoc.Load(manifestPath);
+            
+            InjectAndroidManifest(manifestPath, manifestDoc);
+
+            manifestDoc.Save(manifestPath);
+        }
+        
+        internal static void InjectAndroidManifest(string manifestPath, XmlDocument manifestDoc)
+        {
+            string mainActivity = GetLauncherActivity(manifestDoc);
+
+            AppendAndroidMetadataField(manifestPath, manifestDoc, K_CUSTOM_NOTIFICATION_ACTIVITY, mainActivity);
+            AppendAndroidPermissionField(manifestPath, manifestDoc, K_PREMISSION_POST_NOTIFICATIONS);
+            
+            UnityEngine.Debug.Log($"Add custom notification activity: {mainActivity} success!!");
+        }
+        
+        internal static void AppendAndroidPermissionField(string manifestPath, XmlDocument xmlDoc, string name, string maxSdk = null)
+        {
+            AppendAndroidPermissionField(manifestPath, xmlDoc, "uses-permission", name, maxSdk);
+        }
+        
+        internal static void AppendAndroidPermissionField(string manifestPath, XmlDocument xmlDoc, string tagName, string name, string maxSdk)
+        {
+            var manifestNode = xmlDoc.SelectSingleNode("manifest");
+            if (manifestNode == null)
+                throw new ArgumentException(string.Format("Missing 'manifest' node in '{0}'.", manifestPath));
+
+            XmlElement metaDataNode = null;
+            foreach (XmlNode node in manifestNode.ChildNodes)
+            {
+                if (!(node is XmlElement) || node.Name != tagName)
+                    continue;
+
+                var element = (XmlElement)node;
+                var elementName = element.GetAttribute("name", K_ANDROID_NAMESPACE_URI);
+                if (elementName == name)
+                {
+                    if (maxSdk == null)
+                        return;
+                    var maxSdkAttr = element.GetAttribute("maxSdkVersion", K_ANDROID_NAMESPACE_URI);
+                    if (!string.IsNullOrEmpty(maxSdkAttr))
+                        return;
+                    metaDataNode = element;
+                }
+            }
+
+            if (metaDataNode == null)
+            {
+                metaDataNode = xmlDoc.CreateElement(tagName);
+                metaDataNode.SetAttribute("name", K_ANDROID_NAMESPACE_URI, name);
+            }
+            if (maxSdk != null)
+                metaDataNode.SetAttribute("maxSdkVersion", K_ANDROID_NAMESPACE_URI, maxSdk);
+
+            manifestNode.AppendChild(metaDataNode);
+        }
+        
+        internal static void AppendAndroidMetadataField(string manifestPath, XmlDocument xmlDoc, string name, string value)
+        {
+            var applicationNode = xmlDoc.SelectSingleNode("manifest/application");
+            if (applicationNode == null)
+                throw new ArgumentException(string.Format("Missing 'application' node in '{0}'.", manifestPath));
+
+            var nodes = xmlDoc.SelectNodes("manifest/application/meta-data");
+            if (nodes != null)
+            {
+                // Check if there is a 'meta-data' with the same name.
+                foreach (XmlNode node in nodes)
+                {
+                    var element = node as XmlElement;
+                    if (element == null)
+                        continue;
+
+                    var elementName = element.GetAttribute("name", K_ANDROID_NAMESPACE_URI);
+                    if (elementName == name)
+                    {
+                        element.SetAttribute("value", K_ANDROID_NAMESPACE_URI, value);
+                        return;
+                    }
+                }
+            }
+
+            XmlElement metaDataNode = xmlDoc.CreateElement("meta-data");
+            metaDataNode.SetAttribute("name", K_ANDROID_NAMESPACE_URI, name);
+            metaDataNode.SetAttribute("value", K_ANDROID_NAMESPACE_URI, value);
+
+            applicationNode.AppendChild(metaDataNode);
+        }
+        
+        internal static string GetLauncherActivity(XmlDocument xmlDoc)
+        {
+            var applicationNode = xmlDoc.SelectSingleNode("manifest/application");
+            if (applicationNode == null)
+                throw new ArgumentException($"Missing 'application' node in doc.");
+            
+            var nodes = xmlDoc.SelectNodes("manifest/application/activity");
+            if (nodes != null)
+            {
+                foreach (XmlNode node in nodes)
+                {
+                    var activityNode = node as XmlElement;
+                    if (activityNode == null)
+                        continue;
+
+                    if (activityNode.HasChildNodes)
+                    {
+                        var intentFilterNode = activityNode.SelectSingleNode("intent-filter");
+                       
+                        if(intentFilterNode == null || !intentFilterNode.HasChildNodes)
+                            continue;
+                        
+                        foreach (XmlElement childNode in intentFilterNode)
+                        {
+                            if(childNode == null) continue;
+                            
+                            // 判断 action/category 二者取其一
+                            if (childNode.Name == "action" && childNode.InnerXml.Contains("android.intent.action.MAIN"))
+                            {
+                                var activityName = activityNode.GetAttribute("name", K_ANDROID_NAMESPACE_URI);
+                                return activityName;
+                            }
+                            
+                            if (childNode.Name == "category" && childNode.InnerXml.Contains("android.intent.category.LAUNCHER"))
+                            {
+                                var activityName = activityNode.GetAttribute("name", K_ANDROID_NAMESPACE_URI);
+                                return activityName;
+                            }
+                        }
+                    }
+                }
+            }
+
+            return V_DEFAULT_GURU_ACTIVITY;
+        }
+        
+    }
+}
+
+#endif
diff --git a/Runtime/GuruNoification/Editor/Android_PostCustomActivity.cs.meta b/Runtime/GuruNoification/Editor/Android_PostCustomActivity.cs.meta
new file mode 100644
index 0000000..c51fbb5
--- /dev/null
+++ b/Runtime/GuruNoification/Editor/Android_PostCustomActivity.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 2e6de94961cc47abbabbc7e872085a98
+timeCreated: 1718934648
\ No newline at end of file
diff --git a/Runtime/GuruNoification/Manager/NotificationAgentAndroid.cs b/Runtime/GuruNoification/Manager/NotificationAgentAndroid.cs
index d2cdaae..33a087e 100644
--- a/Runtime/GuruNoification/Manager/NotificationAgentAndroid.cs
+++ b/Runtime/GuruNoification/Manager/NotificationAgentAndroid.cs
@@ -134,6 +134,7 @@ namespace Guru.Notification
                     // 低版本处理方式
                     if (_notiStatus == STATUS_GRANTED)
                     {
+                        Debug.Log($"[SDK][Noti] --- #1 SDK {sdkInt} has already Grated!");
                         SetGrantStatus(true);
                         // 已经允许了
                         callback?.Invoke(_notiStatus);
@@ -141,9 +142,11 @@ namespace Guru.Notification
                     }
                     else
                     {
-                        if (_permissionStatus == PermissionStatus.NotRequested ||
+                        if (_permissionStatus == PermissionStatus.NotRequested || 
+                            _permissionStatus == PermissionStatus.RequestPending ||
                             AndroidNotificationCenter.ShouldShowPermissionToPostRationale)
                         {
+                            Debug.Log($"[SDK][Noti] --- #2 SDK {sdkInt} not requested -> open channel");
                             AndroidNotificationCenter.OpenNotificationSettings(FCM_DEFAULT_CHANNEL_ID); // 打开ChannelID
                         }
                     }
@@ -151,6 +154,7 @@ namespace Guru.Notification
                 }
                 else if (hasPerm)
                 {
+                    Debug.Log($"[SDK][Noti] --- #3 SDK {sdkInt} :: Post permission has already granted!");
                     SetGrantStatus(true);
                     // 已经允许了
                     callback?.Invoke(_notiStatus);
@@ -159,6 +163,7 @@ namespace Guru.Notification
                 {
                     // 未允许
                     // 则请求弹窗
+                    Debug.Log($"[SDK][Noti] --- #3 SDK {sdkInt} :: Ask Post Permission");
                     Permission.RequestUserPermission(PERMISSION_POST_NOTIFICATION, SetupPermissionCallbacks());
                 }
             });
@@ -168,9 +173,9 @@ namespace Guru.Notification
         {
             if(_permissionCallbacks != null) DisposePermissionCallbacks();
             _permissionCallbacks = new PermissionCallbacks();
-            _permissionCallbacks.PermissionDenied += OnPermissionGranted;
-            _permissionCallbacks.PermissionDeniedAndDontAskAgain += OnPermissionGranted;
             _permissionCallbacks.PermissionGranted += OnPermissionGranted;
+            _permissionCallbacks.PermissionDenied += OnPermissionDenied;
+            _permissionCallbacks.PermissionDeniedAndDontAskAgain += OnPermissionDenied;
             return _permissionCallbacks;
         }
         
@@ -179,8 +184,8 @@ namespace Guru.Notification
             if (_permissionCallbacks != null)
             {
                 _permissionCallbacks.PermissionGranted -= OnPermissionGranted;
-                _permissionCallbacks.PermissionDenied -= PermissionDenied;
-                _permissionCallbacks.PermissionDeniedAndDontAskAgain -= PermissionDenied;
+                _permissionCallbacks.PermissionDenied -= OnPermissionDenied;
+                _permissionCallbacks.PermissionDeniedAndDontAskAgain -= OnPermissionDenied;
                 _permissionCallbacks = null;
             }
         }
@@ -204,7 +209,7 @@ namespace Guru.Notification
         /// 请求拒绝
         /// 
         /// 
-        private void PermissionDenied(string permissionName)
+        private void OnPermissionDenied(string permissionName)
         {
             if (permissionName == PERMISSION_POST_NOTIFICATION)
             {