update: 添加构建管线, 修复授权回调BUG 逻辑
--story=1020629 --user=yufei.hu 【中台】【BUG】修复 noti_perm 属性设置不正确的问题 https://www.tapd.cn/33527076/s/1152099main
							parent
							
								
									dbb56e5a32
								
							
						
					
					
						commit
						ffcb846a64
					
				|  | @ -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); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         /// 设置 Android Manifest | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="projectPath"></param> | ||||||
|  |         /// <exception cref="FileNotFoundException"></exception> | ||||||
|  |         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($"<color=#88ff00>Add custom notification activity: {mainActivity} success!!</color>"); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         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 | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | fileFormatVersion: 2 | ||||||
|  | guid: 2e6de94961cc47abbabbc7e872085a98 | ||||||
|  | timeCreated: 1718934648 | ||||||
|  | @ -134,6 +134,7 @@ namespace Guru.Notification | ||||||
|                     // 低版本处理方式 |                     // 低版本处理方式 | ||||||
|                     if (_notiStatus == STATUS_GRANTED) |                     if (_notiStatus == STATUS_GRANTED) | ||||||
|                     { |                     { | ||||||
|  |                         Debug.Log($"[SDK][Noti] --- #1 SDK {sdkInt} has already Grated!"); | ||||||
|                         SetGrantStatus(true); |                         SetGrantStatus(true); | ||||||
|                         // 已经允许了 |                         // 已经允许了 | ||||||
|                         callback?.Invoke(_notiStatus); |                         callback?.Invoke(_notiStatus); | ||||||
|  | @ -141,9 +142,11 @@ namespace Guru.Notification | ||||||
|                     } |                     } | ||||||
|                     else |                     else | ||||||
|                     { |                     { | ||||||
|                         if (_permissionStatus == PermissionStatus.NotRequested || |                         if (_permissionStatus == PermissionStatus.NotRequested ||  | ||||||
|  |                             _permissionStatus == PermissionStatus.RequestPending || | ||||||
|                             AndroidNotificationCenter.ShouldShowPermissionToPostRationale) |                             AndroidNotificationCenter.ShouldShowPermissionToPostRationale) | ||||||
|                         { |                         { | ||||||
|  |                             Debug.Log($"[SDK][Noti] --- #2 SDK {sdkInt} not requested -> open channel"); | ||||||
|                             AndroidNotificationCenter.OpenNotificationSettings(FCM_DEFAULT_CHANNEL_ID); // 打开ChannelID |                             AndroidNotificationCenter.OpenNotificationSettings(FCM_DEFAULT_CHANNEL_ID); // 打开ChannelID | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  | @ -151,6 +154,7 @@ namespace Guru.Notification | ||||||
|                 } |                 } | ||||||
|                 else if (hasPerm) |                 else if (hasPerm) | ||||||
|                 { |                 { | ||||||
|  |                     Debug.Log($"[SDK][Noti] --- #3 SDK {sdkInt} :: Post permission has already granted!"); | ||||||
|                     SetGrantStatus(true); |                     SetGrantStatus(true); | ||||||
|                     // 已经允许了 |                     // 已经允许了 | ||||||
|                     callback?.Invoke(_notiStatus); |                     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()); |                     Permission.RequestUserPermission(PERMISSION_POST_NOTIFICATION, SetupPermissionCallbacks()); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|  | @ -168,9 +173,9 @@ namespace Guru.Notification | ||||||
|         { |         { | ||||||
|             if(_permissionCallbacks != null) DisposePermissionCallbacks(); |             if(_permissionCallbacks != null) DisposePermissionCallbacks(); | ||||||
|             _permissionCallbacks = new PermissionCallbacks(); |             _permissionCallbacks = new PermissionCallbacks(); | ||||||
|             _permissionCallbacks.PermissionDenied += OnPermissionGranted; |  | ||||||
|             _permissionCallbacks.PermissionDeniedAndDontAskAgain += OnPermissionGranted; |  | ||||||
|             _permissionCallbacks.PermissionGranted += OnPermissionGranted; |             _permissionCallbacks.PermissionGranted += OnPermissionGranted; | ||||||
|  |             _permissionCallbacks.PermissionDenied += OnPermissionDenied; | ||||||
|  |             _permissionCallbacks.PermissionDeniedAndDontAskAgain += OnPermissionDenied; | ||||||
|             return _permissionCallbacks; |             return _permissionCallbacks; | ||||||
|         } |         } | ||||||
|          |          | ||||||
|  | @ -179,8 +184,8 @@ namespace Guru.Notification | ||||||
|             if (_permissionCallbacks != null) |             if (_permissionCallbacks != null) | ||||||
|             { |             { | ||||||
|                 _permissionCallbacks.PermissionGranted -= OnPermissionGranted; |                 _permissionCallbacks.PermissionGranted -= OnPermissionGranted; | ||||||
|                 _permissionCallbacks.PermissionDenied -= PermissionDenied; |                 _permissionCallbacks.PermissionDenied -= OnPermissionDenied; | ||||||
|                 _permissionCallbacks.PermissionDeniedAndDontAskAgain -= PermissionDenied; |                 _permissionCallbacks.PermissionDeniedAndDontAskAgain -= OnPermissionDenied; | ||||||
|                 _permissionCallbacks = null; |                 _permissionCallbacks = null; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | @ -204,7 +209,7 @@ namespace Guru.Notification | ||||||
|         /// 请求拒绝 |         /// 请求拒绝 | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         /// <param name="permissionName"></param> |         /// <param name="permissionName"></param> | ||||||
|         private void PermissionDenied(string permissionName) |         private void OnPermissionDenied(string permissionName) | ||||||
|         { |         { | ||||||
|             if (permissionName == PERMISSION_POST_NOTIFICATION) |             if (permissionName == PERMISSION_POST_NOTIFICATION) | ||||||
|             { |             { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue