Use custom Manifest file and permission in Unity?
You are modifying the wrong AndroidManifest
file. That AndroidManifest
from <ProjectName>\Temp\StagingArea
you are modifying is generated by unity each time you build your project.
To use a custom AndroidManifest
file, you have to put your custom AndroidManifest
file at <ProjectName>Assets\Plugins\Android
.
1.Go to <UnityInstallationDirecory>\Editor\Data\PlaybackEngines\AndroidPlayer\Apk
, Copy the AndroidManifest.xml
file to your <ProjectName>Assets\Plugins\Android
2.Open the copied Manifest file from <ProjectName>Assets\Plugins\Android
and add your manifest.
In your particular case, add <application android:theme="Theme.Light.NoTitleBar" android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="false" android:isGame="true" android:banner="@drawable/app_banner">
to it. Save, Build and Run.
Unity will now use that AndroidManifest
file. If you get crash or any other problem, then Unity does not want you to change that.
Starting with Unity 2018 you should implement the IPostGenerateGradleAndroidProject
interface which will allow you to edit the android manifest after Unity produces it. In the code below I have added methods to set the microphone permission, set hardware acceleration, and set your application theme ( replace SetMicrophonePermission()
to your preferred method, which is called when Unity calls OnPostGenerateGradleAndroidProject()
).
Add the following code to Assets/Editor/ModifyUnityAndroidAppManifestSample.cs
using System.IO;
using System.Text;
using System.Xml;
using UnityEditor.Android;
public class ModifyUnityAndroidAppManifestSample : IPostGenerateGradleAndroidProject
{
public void OnPostGenerateGradleAndroidProject(string basePath)
{
// If needed, add condition checks on whether you need to run the modification routine.
// For example, specific configuration/app options enabled
var androidManifest = new AndroidManifest(GetManifestPath(basePath));
androidManifest.SetMicrophonePermission();
// Add your XML manipulation routines
androidManifest.Save();
}
public int callbackOrder { get { return 1; } }
private string _manifestFilePath;
private string GetManifestPath(string basePath)
{
if (string.IsNullOrEmpty(_manifestFilePath))
{
var pathBuilder = new StringBuilder(basePath);
pathBuilder.Append(Path.DirectorySeparatorChar).Append("src");
pathBuilder.Append(Path.DirectorySeparatorChar).Append("main");
pathBuilder.Append(Path.DirectorySeparatorChar).Append("AndroidManifest.xml");
_manifestFilePath = pathBuilder.ToString();
}
return _manifestFilePath;
}
}
internal class AndroidXmlDocument : XmlDocument
{
private string m_Path;
protected XmlNamespaceManager nsMgr;
public readonly string AndroidXmlNamespace = "http://schemas.android.com/apk/res/android";
public AndroidXmlDocument(string path)
{
m_Path = path;
using (var reader = new XmlTextReader(m_Path))
{
reader.Read();
Load(reader);
}
nsMgr = new XmlNamespaceManager(NameTable);
nsMgr.AddNamespace("android", AndroidXmlNamespace);
}
public string Save()
{
return SaveAs(m_Path);
}
public string SaveAs(string path)
{
using (var writer = new XmlTextWriter(path, new UTF8Encoding(false)))
{
writer.Formatting = Formatting.Indented;
Save(writer);
}
return path;
}
}
internal class AndroidManifest : AndroidXmlDocument
{
private readonly XmlElement ApplicationElement;
public AndroidManifest(string path) : base(path)
{
ApplicationElement = SelectSingleNode("/manifest/application") as XmlElement;
}
private XmlAttribute CreateAndroidAttribute(string key, string value)
{
XmlAttribute attr = CreateAttribute("android", key, AndroidXmlNamespace);
attr.Value = value;
return attr;
}
internal XmlNode GetActivityWithLaunchIntent()
{
return SelectSingleNode("/manifest/application/activity[intent-filter/action/@android:name='android.intent.action.MAIN' and " +
"intent-filter/category/@android:name='android.intent.category.LAUNCHER']", nsMgr);
}
internal void SetApplicationTheme(string appTheme)
{
ApplicationElement.Attributes.Append(CreateAndroidAttribute("theme", appTheme));
}
internal void SetStartingActivityName(string activityName)
{
GetActivityWithLaunchIntent().Attributes.Append(CreateAndroidAttribute("name", activityName));
}
internal void SetHardwareAcceleration()
{
GetActivityWithLaunchIntent().Attributes.Append(CreateAndroidAttribute("hardwareAccelerated", "true"));
}
internal void SetMicrophonePermission()
{
var manifest = SelectSingleNode("/manifest");
XmlElement child = CreateElement("uses-permission");
manifest.AppendChild(child);
XmlAttribute newAttribute = CreateAndroidAttribute("name", "android.permission.RECORD_AUDIO");
child.Attributes.Append(newAttribute);
}
}