Open8
AppLabにリリースするために、AndroidManifestファイルを設定する

技術構成
- XR Interaction Toolkit ver2.2.0
- OpenXR ver1.4.2
- 場合によっては今後Oculusプラグインいれるかも?
- Home押したらストップ、みたいな要件を実現するために、とか。
参考URL

VRC.Quest.Packaging.4
- VRC要件
- 以下の記事から、UnityのProjectSettingsをもう一度見直す
- [Minimum API Level (最小APIレベル)]について、23にするという記事と、29にするという記事が両方とも公式から出ているので注意。Metaの公式Twitterで29の方に変更されているのでそちらに合わせる
マニュフェストファイルを自動生成してくれるツールはどこ?
- Oculus Integrationをいれていないので、当然Oculusというメニューはない。これにOculus Integrationの何かを追加して、
[Oculus] >[Tools (ツール)] > [Create store-compatible AndroidManifest.xml]
を表示させたい。 - 調べた結果、Oculus IntegarationのVRが担っている。
Assets/Oculus/VR/Editor/OVRManifestPreprocessor.cs
Oculus Integrationを必要な部分入れる
(追記)ほとんど入れる必要なかった
- Oculus Integrationのインポートは必要ないかも。とりあえずEditorメニューからマニフェストファイルを作ってから消した。ただし、サンプルのファイルだけIntegrationの中にある(VR > Editor > AndroidManifest.OVRSubmission.xml)のでそれだけ入れて、生成されたファイルと比べてみた。
(古い)必要な部分だけいれてみたときの過程
- これを"Yes"
- これに"Use OpenXR"
- これに"OK"
- これに"Restart"
- 再起動後、これに"Enable"
- => 修正: OculusXR FeatureをEnabledにすると、コントローラーの位置の情報がおかしくなるのでdisabledにする
- 毎回再生時にOculusXRをenabledにしろというポップアップがうるさいので、いったん該当箇所の関数に
return
を仕込む、Assets/Oculus/VR/Scripts/Editor/OculusXRFeatureEnabler.cs
- 毎回再生時にOculusXRをenabledにしろというポップアップがうるさいので、いったん該当箇所の関数に
マニュフェストファイルを作る
- Oculus > Tools > Create store-compatible AndroidManifest.xmlから
- 作成された
Editorのツールから作成されたマニフェストファイルと、Oculus Integrationでインポートしたマニフェストファイルの違い
- ツールから作成したほう
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto">
<application android:label="@string/app_name" android:icon="@mipmap/app_icon" android:allowBackup="false">
<activity android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" android:configChanges="locale|fontScale|keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode" android:launchMode="singleTask" android:name="com.unity3d.player.UnityPlayerActivity" android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="com.oculus.intent.category.VR" />
</intent-filter>
<meta-data android:name="com.oculus.vr.focusaware" android:value="true" />
</activity>
<meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="false" />
<meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only" />
<meta-data android:name="com.oculus.supportedDevices" android:value="quest|quest2|cambria" />
</application>
<uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" />
</manifest>
- Oculus Integrationからインポートした方
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="auto">
<application
android:label="@string/app_name"
android:icon="@mipmap/app_icon">
<activity
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
android:configChanges="locale|fontScale|keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode"
android:launchMode="singleTask"
android:name="com.unity3d.player.UnityPlayerActivity"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="false" />
<meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>
</application>
</manifest>
差分まとめ
ツールの行数 | 内容 | Integrationの行数 |
---|---|---|
1 | 同じ | 1 |
2 | 同じ | 2~3 |
3 | ツールの方だけ、android:allowBackup="false" が含まれる | 4~6 |
4 | 同じ | 7~12 |
5~9 | ツールの方だけ、<category android:name="com.oculus.intent.category.VR" /> が含まれる | 13~16 |
10 | ツールの方だけ、<meta-data android:name="com.oculus.vr.focusaware" android:value="true" /> が含まれる | 該当なし |
11 | 同じ(閉じタグだけ) | 17 |
12~14 | ツールの方だけ、 <meta-data android:name="com.oculus.supportedDevices" android:value="quest | quest2 |
15 | 同じ(閉じタグだけ) | 20 |
16 | ツールの方だけ、 <uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" /> が含まれる | 該当なし |
17 | 同じ(閉じタグだけ) | 21 |
マニュフェストファイルの変更
アプリ名
-
application ノードにおいて、 android:label にはアプリ名、またはアプリ名を表す適切な表現が含まれていなければならず、ラベルはプラットフォーム内で一意でなければなりません。
- app_nameになってる
- => 書き換えた
versionCode
-
versionCode は、このアプリの前回のビルドで使用した値よりも大きくなければなりません。
- 欄がない
- => Unityで設定するので無しでOK
debuggable
-
android:debuggable の値は、 falseでなければなりません。アプリは、デバッグバージョンではなく、リリースバージョンでなければなりません。
- 欄がない
- => Unityで設定するので無しでOK
minSdkVersionとtargetSdkVersion
-
android:minSdkVersion と android:targetSdkVersion は適切に設定されていなければなりません。...
- 欄がない
- => Unityで設定するので無しでOK

AppIDの設定
- 記事冒頭の「参考」にあげた記事の中に、AppIDを設定する必要性が書かれている。
- これが必要なのか不明。
- Application IDに数値をいれると、Editorからボタン1つで開発者ダッシュボードのwebページに飛ぶことができる
- 今後、UnityEditorから直接アップロードする際に使える、くらいで、リリースの必須要件ではない可能性はある。

Version管理について
- UnityのProject Settings の
Version
とBundle Version Code
、Android ManifestのversionCode
とversionName
の違いは?
それぞれの定義
Unityでの項目
- 定義
-
Bundle Version Code
が内部的には重要。制約: 正の整数 -
Version
の扱い分からず...(おそらくユーザーへの表示用)- 実際、以下のC#コードでアクセスできるのは、
Version
の方
- 実際、以下のC#コードでアクセスできるのは、
var appVersion = Application.version;
Android Manifestでの項目
- 定義
- `versionCodeが内部的に重要。制約: 正の整数
-
versionName
はユーザーへの表示用。
対応
- Unityの
Bundle Version Code
と、ManifestのversionCode
(制約も、正の整数ということで同じ) - Unityの
Version
と、ManifestのversionName
(どちらもユーザー表示用。制約は特になし)「
Manifestにも書く必要があると思ってたけど、Unityが設定してくれるから書かないでいいのか(?)

ビルドして出力されたmanifestファイルに残っている課題
問題1: 不要な権限へのアクセスをしている
<uses-permission android:name="android.permission.BLUETOOTH" />
- どのソースがアクセスを要求しているのか、調査が必要
解決?? => 追記: 解決していない
- OculusXRプラグインの中にこのような個所があった。
- パス:
Library/PackageCache/com.unity.xr.oculus@3.0.1/Editor/OculusBuildProcessor.cs
- パス:
OculusBuildProcessor.cs
// if the Microphone class is used in a project, the BLUETOOTH permission is automatically added to the manifest
// we remove it here since it will cause projects to fail Oculus cert
// this shouldn't affect Bluetooth HID devices, which don't need the permission
nodePath = "/manifest";
RemoveNameValueElementInTag(manifestDoc, nodePath, "uses-permission", "android:name", "android.permission.BLUETOOTH");
- OpenXRのプロジェクトを一度Oculusプラグインに変更し、ビルドしたところ、マニフェストファイルからBLUETOOTHのpermissionが消えた。
- その後、OpenXRに戻してビルドしなおしてもBLUETOOTHは消えたまま。
- AndroidManifestファイルの作成手順が分からず混乱中。昔作ったファイルを参考に新しいものを作る模様。何回かビルドしていたら、また戻った(BLUETOOTHのパーミッションを書いている。ダメ
- 自分で、OculusBuildProcessor.csみたいなものを書く必要があるか?
- => OculusBuildProcessor.csを通したものとそうでないもので、どんな差分がmanifestファイルに生じるか確認してみる
OculusBuildProcessor.csを通したmanifestファイルとそうでないものの違い
- BLUETOOTHのパーミッション
- OpenXR:
<uses-permission android:name="android.permission.BLUETOOTH" />
がある - Oculus: 無い
- OpenXR:
-
<activity
タグのandroid:configChanges
- OpenXR:
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density
- Oculus:
android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenLayout|screenSize|uiMode|density"
- OpenXR:
-
<activity
タグのandroid:screenOrientation
- OpenXR:
android:screenOrientation="fullUser"
- Oculus:
android:screenOrientation="landscape"
- OpenXR:
-
meta-data
のsupportDevices
- OpenXR:
android:value="quest|quest2|cambria"
- Oculus:
android:value="quest|quest2"
- OpenXR:
- Oculusのみ、
meta-data
で以下の3行が追加されている
<meta-data
android:name="com.unity.xr.oculus.LowOverheadMode"
android:value="false" />
<meta-data
android:name="com.unity.xr.oculus.LateLatching"
android:value="false" />
<meta-data
android:name="com.unity.xr.oculus.LateLatchingDebug"
android:value="false" />
問題2(追記: 問題ではないかも): android:icon, labelがデフォルトのまま
android:icon="@mipmap/app_icon"
android:label="@string/app_name"
- 以下のように書き換えるとエラー
android:label="MemoriaVR"
- エラー内容コピーし忘れたが、他のAndroidManifestとマージできない、という感じだった。
- 以下ではどうか?
android:label="@string/MemoriaVR"
- だめだ、たぶん同じエラーがでている
C:\Users\UaweName\Projects\ProjectName\Library\Bee\Android\Prj\IL2CPP\Gradle\launcher\src\main\AndroidManifest.xml:4:16-48 Error:
Attribute application@label value=(@string/app_name) from AndroidManifest.xml:4:16-48
is also present at [:unityLibrary] AndroidManifest.xml:45:9-42 value=(@string/MemoriaVR).
Suggestion: add 'tools:replace="android:label"' to <application> element at AndroidManifest.xml:4:3-83 to override.
- いや、これそもそも問題ではないかもしれない。ここのlabelを変更している記事を見ないので。たぶんここで名前を指定しているとかではなくて、キー的な役割をしているのかも

出力されたapkファイルのAndroinManifestファイルを読みにいく
- apkファイルに実際に出力されているマニフェストには何が書かれているのか、というのが気にある
-
apkを解凍し-jarコマンドによって見に行く記事を参考に実施
- ちなみにJavaも入れてなかったのでいれた参考
- ファイルの置き場所は適当だが、以下のようなコマンドで閲覧可能
C:/'Program Files'/Java/jdk-19/bin/java.exe -jar ~/Downloads/AXMLPrinter2.jar ~/Projects/testbuild/AndroidManifest.xml

RECORD_AUDIOのパーミッションが必要なのかどうか
- AppLabへアップロードしたところ、以下のような警告がでた
- 現在、オーディオ関連のパーミッションは2つある。
-
RECORD_AUDIO
とMODIFY_AUDIO_SETTINGS
-
RECORD_AUDIO
- 定義
-
Allows an application to record audio.
MODIFY_AUDIO_SETTINGS
- 定義
-
Allows an application to modify global audio settings.
必要なのか精査
- 定義が簡素すぎてわからん。。。今回、マイクの使用を許可するかユーザーに聞く部分があり、それはどちらに該当するのだろうか?
- 該当部分のC#コードは以下のような感じ
RequestUserPermission (Permission.Microphone);
-
Permission.Microphone
の定義元を見に行ったところ、以下のように記述されていた
Permission.cs
/// <summary>
/// <para>Used when requesting permission or checking if permission has been granted to use the microphone.</para>
/// </summary>
public const string Microphone = "android.permission.RECORD_AUDIO";
- Questで初めて起動したときにでるメッセージは以下であり、「音声の録音」= "RECORD AUDIO"そのものなので、これは必要な権利だと思われる。
音声の録音を「〇〇」に許可しますか?

permission.MODIRY_AUDIO_SETTINGSは必要なのか?
- 結論: 削除の方法が分からないので、いったんいれた状態で出してみよう。
経緯
- Meta Quest Developer Hubからapkファイルをアップロードしたところ、以下のような警告がでた。
- ダッシュボードではRECORD_AUDIOの方しか出ていなかったのに、MODIFY_AUDIO_SETTINGSもあったらだめなのか。
- MODIRY_AUDIO_SETTINGSが何をするのか、という情報については非常に少ない。
-
音量などの音声全般の設定の変更を許可します。(ブログ)
MODIFY_AUDIO_SETTINGSを消そうとする
- BLUETOOTHをマニフェストファイルを作成する際に消したように、MODIFY_AUDIO_SETTINGSも消すコードをかませる。
- しかし、どうしても消えなかった。
- RECORD_AUDIOを入れたことによって自動追加されているのかと思い、RECORD_AUDIOと両方とも消す処理をいれたが、MODIFY_AUDIO_SETTINGSはどうしても追加されてしまう。
パーミッションって機能と関係しているの?
- マニフェストファイルに書かれているパーミッションが、そもそも機能と本当に関係しているのか、ということが気になったので調べた。
- RECORD_AUDIOを消したビルドを作ってみる。
- 結果: 正常通り機能しなかった。まず、「音声を録音しますか?」のポップアップがでてこない。また、ワールドに入るたびに一時的に重くなる。当然録音もされない。