web-dev-qa-db-ja.com

Unityでカスタムマニフェストファイルと権限を使用しますか?

私は現在、Androidの小さなゲームをプログラミングしようとしています。ステータスバーを表示したいので、プロジェクトフォルダー(C:\ Users\Public\Documents\Unity ProjectsのAndroidManifestを変更しました\ ProjectName\Temp\StagingArea)は次のようになります。

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

しかし、私がAPKを生成するたびに、団結はAndroid Manifestをこれに変更します:

<application Android:theme="@style/UnityThemeSelector" Android:icon="@drawable/app_icon" Android:label="@string/app_name" Android:debuggable="false" Android:isGame="true" Android:banner="@drawable/app_banner">

Unity3Dは変更されたマニフェストを毎回変更しますか?

10
genaray

間違ったAndroidManifestファイルを変更しています。変更する<ProjectName>\Temp\StagingAreaからのAndroidManifestは、プロジェクトをビルドするたびにUnityによって生成されます。

カスタムAndroidManifestファイルを使用するには、カスタムAndroidManifestファイルを<ProjectName>Assets\Plugins\Androidに配置する必要があります。

1. <UnityInstallationDirecory>\Editor\Data\PlaybackEngines\AndroidPlayer\Apkに移動し、AndroidManifest.xmlファイルを<ProjectName>Assets\Plugins\Androidにコピーします

2 .<ProjectName>Assets\Plugins\Androidからコピーしたマニフェストファイルを開き、マニフェストを追加します。

特定のケースでは、<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">を追加します。保存、ビルド、実行。

UnityはそのAndroidManifestファイルを使用します。クラッシュやその他の問題が発生した場合、Unityはそれを変更することを望んでいません。

18
Programmer

Unity 2018以降、IPostGenerateGradleAndroidProjectinterface を実装する必要があります。これにより、Unityが生成した後にAndroidマニフェストを編集できるようになります。以下のコードでは、マイクの許可を設定し、ハードウェアアクセラレーションを設定し、アプリケーションテーマを設定するメソッドを追加しました(SetMicrophonePermission()を、UnityがOnPostGenerateGradleAndroidProject()を呼び出すときに呼び出される優先メソッドに置き換えます)。

次のコードを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);
    }
}
11
pale bone

unityランタイムパーミッションの場合、この関数を作成してスキップパーミッションダイアログを追加します(例 https://docs.unity3d.com/Manual/Android-manifest.html

例えば

<manifest>
    <application>
        <meta-data Android:name="unityplayer.SkipPermissionsDialog" Android:value="true" />

これがコードです:

internal void SetSkipPermissionsDialog()
{
    var manifest = SelectSingleNode("/manifest");
    var application = manifest.SelectSingleNode("application");
    XmlElement child = CreateElement("meta-data");
    application.AppendChild(child);
    XmlAttribute newAttribute = CreateAndroidAttribute("name", "unityplayer.SkipPermissionsDialog");
    child.Attributes.Append(newAttribute);
    newAttribute = CreateAndroidAttribute("value", "true");
    child.Attributes.Append(newAttribute);
}
0
linojon