using System.Collections.Generic;
namespace Guru.Editor
{
using System.Xml;
using System.IO;
using UnityEngine;
///
/// Android 配置修改器
///
public class MainManifestDoc
{
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 XmlDocument _doc;
public XmlDocument Doc => _doc;
private string _docPath;
private bool _isReady = false;
private XmlElement _manifestNode;
private XmlElement _applicationNode;
private XmlNodeList _metadataList;
private XmlNodeList _permissionList;
#region Initiallize
///
/// 加载文件
///
///
///
public static MainManifestDoc 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 MainManifestDoc();
mod.ReadFromPath(docPath);
return mod;
}
public static MainManifestDoc Read(string xmlStr, string docPath = "")
{
var mod = new MainManifestDoc();
mod.ReadFromXml(xmlStr, docPath);
return mod;
}
///
/// 从文件路径读取
///
///
public void ReadFromPath(string docPath)
{
_isReady = false;
if (File.Exists(_docPath))
{
_docPath = docPath;
var xmlStr = File.ReadAllText(docPath);
ReadFromXml(xmlStr);
}
}
public void ReadFromXml(string xmlStr, string docPath = "")
{
_doc = new XmlDocument();
_doc.LoadXml(xmlStr);
Init();
}
///
/// Initializes the Doc
///
private void Init()
{
// --- Root Nodes ---
_manifestNode = _doc.SelectSingleNode("manifest") as XmlElement;
_applicationNode = _doc.SelectSingleNode("manifest/application") as XmlElement;
// --- Metadatas ---
_metadataList = _applicationNode.SelectNodes("meta-data");
// --- Permissions ---
_permissionList = _applicationNode.SelectNodes("uses-permission");
AddXmlnsAndroid();
AddXmlnsTools();
_isReady = true;
}
///
/// Save Doc
///
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);
}
///
/// Add Replace Item
///
///
public void AddReplaceItem(string item)
{
if (_manifestNode != null)
{
List items = new List(5);
if (_manifestNode.HasAttribute("replace", NamespaceTools))
{
var arr = _manifestNode.GetAttribute("replace",NamespaceTools).Split(',');
if(arr != null && arr.Length > 0)
{
items.AddRange(arr);
}
}
if (!items.Contains(item)) items.Add(item);
_manifestNode.SetAttribute("replace", NamespaceTools, string.Join(",", items));
}
}
///
/// Set metadata
///
///
///
public void SetMetadata(string key, string value)
{
_metadataList = _applicationNode?.SelectNodes("meta-data") ?? null;
XmlElement item = null;
if (_metadataList != null)
{
foreach (XmlElement e in _metadataList)
{
// var nm = e.GetAttribute("name", NamespaceAndroid);
if (e.GetAttribute("name", NamespaceAndroid) is string k && k == key)
{
item = e;
break;
}
}
}
if (item == null)
{
item = _doc.CreateElement("meta-data");
_applicationNode?.AppendChild(item);
}
item.SetAttribute("name", NamespaceAndroid, key);
item.SetAttribute("value", NamespaceAndroid, value);
}
#endregion
#region Output
public override string ToString()
{
if (_doc != null) return _doc.InnerXml;
return this.ToString();
}
#endregion
}
}