337 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			337 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C#
		
	
	
| 
 | |
| 
 | |
| 
 | |
| namespace Guru.Editor
 | |
| {
 | |
|     using System.Xml;
 | |
|     using System.IO;
 | |
|     using UnityEngine;
 | |
|     using System.Collections.Generic;
 | |
|     
 | |
|     
 | |
|     /// <summary>
 | |
|     /// Android 配置修改器
 | |
|     /// </summary>
 | |
|     public class AndroidManifestDoc
 | |
|     {
 | |
|         private const string TargetPath = "Plugins/Android/AndroidManifest.xml";
 | |
|         private const string XmlnsAndroid = "xmlns:android";
 | |
|         private const string NamespaceAndroid = "http://schemas.android.com/apk/res/android";
 | |
|         private const string XmlnsTools= "xmlns:tools";
 | |
|         private const string NamespaceTools = "http://schemas.android.com/tools";
 | |
|         
 | |
|         private const string UserPermission = "uses-permission";
 | |
|         private const string MetaData = "meta-data";
 | |
|         private const string KName = "name";
 | |
| 
 | |
|         private XmlDocument _doc;
 | |
|         public XmlDocument Doc => _doc;
 | |
| 
 | |
|         private string _docPath;
 | |
|         private bool _isReady = false;
 | |
|         
 | |
|         private XmlElement _manifestNode;
 | |
|         private XmlElement _applicationNode;
 | |
| 
 | |
|         
 | |
|         #region Initiallize
 | |
|         
 | |
|         /// <summary>
 | |
|         /// 加载文件
 | |
|         /// </summary>
 | |
|         /// <param name="docPath"></param>
 | |
|         /// <returns></returns>
 | |
|         public static AndroidManifestDoc Load(string docPath = "")
 | |
|         {
 | |
|             if (string.IsNullOrEmpty(docPath))
 | |
|             {
 | |
|                 docPath = Path.GetFullPath(Path.Combine(Application.dataPath, TargetPath));
 | |
|             }
 | |
| 
 | |
|             if (!File.Exists(docPath))
 | |
|             {
 | |
|                 Debug.LogError($"--- File not found: {docPath}");
 | |
|                 return null;
 | |
|             }
 | |
| 
 | |
|             var mod = new AndroidManifestDoc();
 | |
|             mod.ReadFromPath(docPath);
 | |
|             return mod;
 | |
|         }
 | |
| 
 | |
|         public static AndroidManifestDoc Read(string xmlStr, string docPath = "")
 | |
|         {
 | |
|             var mod = new AndroidManifestDoc();
 | |
|             mod.ReadFromXml(xmlStr, docPath);
 | |
|             return mod;
 | |
|         }
 | |
|         
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 从文件路径读取
 | |
|         /// </summary>
 | |
|         /// <param name="docPath"></param>
 | |
|         public void ReadFromPath(string docPath)
 | |
|         {
 | |
|             _isReady = false;
 | |
|             if (File.Exists(docPath))
 | |
|             {
 | |
|                 var xmlStr = File.ReadAllText(docPath);
 | |
|                 ReadFromXml(xmlStr, docPath);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Debug.LogError($"--- File not found: {docPath}");
 | |
|             }
 | |
|         }
 | |
| 
 | |
| 
 | |
|         public void ReadFromXml(string xmlStr, string docPath = "")
 | |
|         {
 | |
|             _doc = new XmlDocument();
 | |
|             _doc.LoadXml(xmlStr);
 | |
|             if(!string.IsNullOrEmpty(docPath)) _docPath = docPath;
 | |
|             Init();
 | |
|         }
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Initializes the Doc
 | |
|         /// </summary>
 | |
|         private void Init()
 | |
|         {
 | |
|             // --- Root Nodes ---
 | |
|             _manifestNode = _doc.SelectSingleNode("manifest") as XmlElement;
 | |
|             _applicationNode = _doc.SelectSingleNode("manifest/application") as XmlElement;
 | |
|             
 | |
|             AddXmlnsAndroid();
 | |
|             AddXmlnsTools();
 | |
|             _isReady = true;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Save Doc
 | |
|         /// </summary>
 | |
|         public void Save(string docPath = "")
 | |
|         {
 | |
|             if (_isReady)
 | |
|             {
 | |
|                 if (!string.IsNullOrEmpty(docPath)) _docPath = docPath;
 | |
|                 if (!string.IsNullOrEmpty(_docPath))
 | |
|                 {
 | |
|                     var dir = Directory.GetParent(_docPath);
 | |
|                     if(!dir.Exists) dir.Create();
 | |
|                     _doc.Save(_docPath);
 | |
| 
 | |
|                 }
 | |
| 
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Node Opreation
 | |
| 
 | |
|         
 | |
|         public static bool AddAttribute(XmlElement node, string key, string value)
 | |
|         {
 | |
|             if (node != null)
 | |
|             {
 | |
|                 if (node.HasAttribute(key))
 | |
|                 {
 | |
|                     node.Attributes[key].Value = value;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     node.SetAttribute(key, value);
 | |
|                 }
 | |
|                 return true;
 | |
|             }
 | |
|             return false;
 | |
|         }
 | |
|         
 | |
|         
 | |
| 
 | |
|         #endregion
 | |
|         
 | |
|         #region API
 | |
| 
 | |
|         public bool AddXmlnsAndroid()
 | |
|         {
 | |
|             return AddAttribute(_manifestNode, XmlnsAndroid, NamespaceAndroid);
 | |
|         }
 | |
|         
 | |
|         public bool AddXmlnsTools()
 | |
|         {
 | |
|             return AddAttribute(_manifestNode, XmlnsTools, NamespaceTools);
 | |
|         }
 | |
|         
 | |
|         /// <summary>
 | |
|         /// Add Replace Item
 | |
|         /// </summary>
 | |
|         /// <param name="item"></param>
 | |
|         public void AddApplicationReplaceItem(string item)
 | |
|         {
 | |
|             if (_applicationNode != null)
 | |
|             {
 | |
|                 List<string> items = new List<string>(5);
 | |
|                 if (_applicationNode.HasAttribute("replace", NamespaceTools))
 | |
|                 {
 | |
|                     var arr = _applicationNode.GetAttribute("replace",NamespaceTools).Split(',');
 | |
|                     if(arr != null && arr.Length > 0)
 | |
|                     {
 | |
|                         items.AddRange(arr);
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (!items.Contains(item)) items.Add(item);
 | |
|                 
 | |
|                 _applicationNode.SetAttribute("replace",  NamespaceTools, string.Join(",", items));
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         public void SetApplicationAttribute(string key, string value)
 | |
|         {
 | |
|             if (_applicationNode != null)
 | |
|             {
 | |
|                 _applicationNode.SetAttribute(key, NamespaceAndroid, value);
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         /// <summary>
 | |
|         /// Set metadata
 | |
|         /// </summary>
 | |
|         /// <param name="key"></param>
 | |
|         /// <param name="value"></param>
 | |
|         /// <param name="valueName"></param>
 | |
|         /// <param name="keyName"></param>
 | |
|         public void SetMetadata(string key, string value, string valueName = "value", string keyName = KName)
 | |
|         {
 | |
|             if (_doc == null || !_isReady) return;
 | |
|             
 | |
|             XmlElement node = null;
 | |
|             if (!TryGetMetadata(key, out node, keyName))
 | |
|             {
 | |
|                 node = _doc.CreateElement(MetaData);
 | |
|                 _applicationNode?.AppendChild(node);
 | |
|             }
 | |
| 
 | |
|             node.SetAttribute(keyName, NamespaceAndroid, key);
 | |
|             node.SetAttribute(valueName, NamespaceAndroid, value);
 | |
|         }
 | |
| 
 | |
|         
 | |
|         /// <summary>
 | |
|         /// 添加权限
 | |
|         /// </summary>
 | |
|         /// <param name="key"></param>
 | |
|         /// <param name="keyName"></param>
 | |
|         public void AddPermission(string key, string keyName = KName)
 | |
|         {
 | |
|             if (_doc == null || !_isReady) return;
 | |
| 
 | |
|             XmlElement node = null;
 | |
|             if(!TryGetPermission(key, out node, keyName))
 | |
|             {
 | |
|                 node = _doc.CreateElement(UserPermission);
 | |
|                 _manifestNode?.AppendChild(node);
 | |
|             }
 | |
|             node.SetAttribute(keyName, NamespaceAndroid, key);
 | |
|         }
 | |
|         
 | |
|         /// <summary>
 | |
|         /// 删除 Permission
 | |
|         /// </summary>
 | |
|         /// <param name="key"></param>
 | |
|         /// <param name="value"></param>
 | |
|         /// <param name="keyName"></param>
 | |
|         /// <param name="valueName"></param>
 | |
|         public void RemovePermission(string key, string value = "remove", string keyName = "name",  string valueName = "node")
 | |
|         {
 | |
|             if (_doc == null || !_isReady) return;
 | |
|             
 | |
|             XmlElement node = null;
 | |
|             if(!TryGetPermission(key, out node, keyName))
 | |
|             {
 | |
|                 node = _doc.CreateElement(UserPermission);
 | |
|                 _manifestNode?.AppendChild(node);
 | |
|             }
 | |
|             node.SetAttribute(keyName, NamespaceAndroid, key);
 | |
|             node.SetAttribute(valueName, NamespaceTools, value);
 | |
|         }
 | |
|         
 | |
|         public bool SetPackageName(string packageName)
 | |
|         {
 | |
|             if (_manifestNode != null)
 | |
|             {
 | |
|                 _manifestNode.Attributes["package"].Value = packageName;
 | |
|                 return true;
 | |
|             }
 | |
|             return false;
 | |
|         }
 | |
|         
 | |
|         #endregion
 | |
| 
 | |
|         #region Data Opration
 | |
| 
 | |
|         public bool TryGetMetadata(string name, out XmlElement node, string keyName = KName)
 | |
|         {
 | |
|             node = null;
 | |
| 
 | |
|             if(_applicationNode != null)
 | |
|             {
 | |
|                 var list = _applicationNode.SelectNodes(MetaData);
 | |
|                 if (list != null)
 | |
|                 {
 | |
|                     foreach (XmlElement e in list)
 | |
|                     {
 | |
|                         if (e.GetAttribute(keyName, NamespaceAndroid) == name)
 | |
|                         {
 | |
|                             node = e;
 | |
|                             return true;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             return false;
 | |
|         }
 | |
|         
 | |
|         
 | |
|         public bool TryGetPermission(string name, out XmlElement node, string keyName = KName)
 | |
|         {
 | |
|             node = null;
 | |
| 
 | |
|             if(_manifestNode != null)
 | |
|             {
 | |
|                 var list = _manifestNode.SelectNodes(UserPermission);
 | |
|                 if (list != null)
 | |
|                 {
 | |
|                     foreach (XmlElement e in list)
 | |
|                     {
 | |
|                         if (e.GetAttribute(keyName, NamespaceAndroid) == name)
 | |
|                         {
 | |
|                             node = e;
 | |
|                             return true;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             return false;
 | |
|         }
 | |
|         
 | |
|         #endregion
 | |
|         
 | |
|         #region Output
 | |
| 
 | |
| 
 | |
|         public override string ToString()
 | |
|         {
 | |
|             if (_doc != null) return _doc.InnerXml;
 | |
|             return this.ToString();
 | |
|         }
 | |
| 
 | |
| 
 | |
|         #endregion
 | |
|         
 | |
|     }
 | |
| } |