これは何
UnityではAndroidの音量を操作するためのAPIが存在しないので、ネイティブプラグインを作る必要がある。
AndroidStudioでとりあえずサンプルを作ってみる
Androidのコードをコンパイルするために、一番手っ取り早いのはAndroid Studioを使い、モジュール(aar)を作ることである。
Kotlinで書く場合、Static Methodを作れない(作れはするものの、@JvmStaticをUnityが理解出来ずに挫折)ので、Javaでプロジェクトを作る(APIレベルは念の為Android12とかにしておく)
プロジェクトが出来たら「File」->「New」->「New Module」でモジュールを作る(作り終えたら「File」->「Project Structure」のModulesからappを削除しておく)
※ここでTemplateがデフォルトでPhone&Tabletになっているので、Android Libraryを選択すること
build.gradle.ktsのdependencyに2行追加

モジュールのlibsディレクトリにUnityEditorに含まれているclasses.jarを移植しておく
(コンパイルエラーを回避するためのものでArtifactには含まれないようにする。モジュールからUnityにSendMessageしたりしないなら不要)
public static String getStreamVolumes(Context ctx) {
AudioManager audioManager = (AudioManager) ctx.getSystemService(AUDIO_SERVICE);
Map<String, Integer> volumeMap = new HashMap<String, Integer>();
volumeMap.put("accessibility", audioManager.getStreamVolume(AudioManager.STREAM_ACCESSIBILITY));
volumeMap.put("alarm", audioManager.getStreamVolume(AudioManager.STREAM_ALARM));
volumeMap.put("music", audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
volumeMap.put("dtmf", audioManager.getStreamVolume(AudioManager.STREAM_DTMF));
volumeMap.put("notification", audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION));
volumeMap.put("ring", audioManager.getStreamVolume(AudioManager.STREAM_RING));
volumeMap.put("system", audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM));
volumeMap.put("voiceCall", audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL));
Gson gson = new Gson();
String ret = gson.toJson(volumeMap);
return ret;
}
こんな感じのコードを書いて、Androidの現在のボリュームをJSONで返却するような実装を行う
メニュー「Build」->「Make Module ‘モジュール名’」でビルドを実行する
実行が完了するとライブラリルートから「./build/outputs/aar」以下にライブラリのパッケージが出来上がっている(Build Variantはお好みで)
※Gsonは匿名クラスをnull化するので、Mapの初期化(new HashMap<>(){{put(key, value)}}みたいなやつ)で匿名クラス化してしまわないように注意。
Unityでのインポート
/Assets/Plugins/Android以下に、作成したaarファイルと、今回サンプルのプログラムで依存するGsonのjarを配置。
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject activity = jc.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject ctx = activity.Call<AndroidJavaObject>("getApplicationContext");
var audioHelper = new AndroidJavaClass("xxxxxxxxxxxxxxx.AndroidAudioHelper"); <-- rewrite me
var androidRes = audioHelper.CallStatic<string>("getStreamVolumes", ctx);
Debug.LogError($"AndroidRes: {androidRes}");
こんな感じでApplicationContextをネイティブのStaticMethodに渡して色々動かすことが出来る。
aarのデコンパイル
実際触って何かしら謎挙動に遭遇した時、aarのデコンパイルをしたくなる。
一番手っ取り早いと思ったのがjadxで、Macならば「brew install jadx」からの「jadx-gui」でGUIのデコンパイラが起動し、aarファイルをドラッグするだけで一発でデコンパイルしてくれる。

エンジニアとして働く90年生まれ。Web系技術を追っかけたり、PCガジェットや自転車いじりが趣味。オーディオオタク。