using System.Collections; using Unity.EditorCoroutines.Editor; namespace Guru.Editor { using NUnit.Framework; using UnityEditor; using UnityEngine; using System; using System.IO; using System.Xml; public static class AndroidManifestMod { private const string TargetPath = "Plugins/Android/AndroidManifest.xml"; private const string ValOptimizeInitialization = "com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION"; private const string ValOptimizeAdLoading = "com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING"; private const string NamespaceAndroid = "http://schemas.android.com/apk/res/android"; private const string NamespaceTools = "http://schemas.android.com/tools"; private const string PermissionReadPhoneState = "android.permission.READ_PHONE_STATE"; private static string TargetFullPath = Path.Combine(Application.dataPath, TargetPath); public static bool IsManifestExist() => File.Exists(TargetFullPath); public static void Apply() { if (!IsManifestExist()) { CopyManifest(); } var doc = new XmlDocument(); doc.Load(TargetFullPath); SetApplicationMod(doc); SetPermissionMod(doc); doc.Save(TargetFullPath); } /// /// Fix all Elements in /// /// private static void SetApplicationMod(XmlDocument doc) { string rootName = "manifest/application"; var rootNode = doc.SelectSingleNode(rootName); int item1 = 0; int item2 = 0; if (rootNode == null) { Debug.LogError($"Can't find root with name {rootName} ..."); return; } XmlNodeList metadatas = rootNode.SelectNodes("meta-data"); if (metadatas != null && metadatas.Count > 0) { bool isDirty = false; foreach (XmlElement e in metadatas) { if (e != null) { if (e.HasAttribute("name", NamespaceAndroid)) { if (e.Attributes["android:name"].Value == ValOptimizeInitialization) item1 = 1; if (e.Attributes["android:name"].Value == ValOptimizeAdLoading) item2 = 1; } } } } if (item1 == 0) { var e = doc.CreateElement("meta-data"); e.SetAttribute("name",NamespaceAndroid, ValOptimizeInitialization); e.SetAttribute("value",NamespaceAndroid, "true"); rootNode.AppendChild(e); } if (item2 == 0) { var e = doc.CreateElement("meta-data"); e.SetAttribute("name",NamespaceAndroid,ValOptimizeAdLoading); e.SetAttribute("value",NamespaceAndroid, "true"); rootNode.AppendChild(e); } var rootE = doc.SelectSingleNode("manifest") as XmlElement; if (rootE != null) { rootE.Attributes["package"].Value = PlayerSettings.applicationIdentifier; // 写入包名 } } /// /// Fix all permissions /// /// private static void SetPermissionMod(XmlDocument doc) { string attName = "uses-permission"; string rootName = "manifest"; bool isBuild = false; var rootNode = doc.SelectSingleNode(rootName); XmlElement item1 = null; if (rootNode == null) { Debug.LogError($"Can't find root with name {rootName} ..."); return; } XmlNodeList permissions = rootNode.SelectNodes(attName); if (permissions != null && permissions.Count > 0) { foreach (XmlElement e in permissions) { if (e != null) { if (e.HasAttribute("android:name")) { if (e.Attributes["android:name"].Value == PermissionReadPhoneState) item1 = e; } } } } isBuild = false; if (item1 == null) { isBuild = true; item1 = doc.CreateElement(attName); } item1.SetAttribute("name",NamespaceAndroid, PermissionReadPhoneState); item1.SetAttribute("node",NamespaceTools, "remove"); if (isBuild) rootNode.AppendChild(item1); } private static void CopyManifest() { if (File.Exists(TargetFullPath)) return; var path = GuruEditorHelper.GetFilePath($"{nameof(AndroidManifestMod)} t:Script"); if (!string.IsNullOrEmpty(path)) { var from = Path.GetFullPath($"{path}/../../Files/AndroidManifest.txt"); if (File.Exists(from)) { File.Copy(from, TargetFullPath); } } } #region Testing [Test] public static void Test_Injection() { Apply(); } #endregion } }