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
 | 
						|
        
 | 
						|
    }
 | 
						|
} |