こんにちは。
ちゃらいアヒルです。
現在作成しているプロジェクトの要件で以下2点の対応が必要になりました。
・端末の音量を取得する
・端末の音量を操作する
ムムム・・・とうとうPlugin作成に手を出す時がきたか!!
と言うことで、AndroidとiOSでそれぞれ以下のように対応しました!
Android
Androidはとてもシンプルです。
// ミュート音量かどうか調べる
public bool IsMuteVolume()
{
#if UNITY_ANDROID
AndroidJavaClass unityPlayer = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" );
AndroidJavaObject context = unityPlayer.GetStatic<AndroidJavaObject>( "currentActivity" );
AndroidJavaObject audioManager = context.Call<AndroidJavaObject>( "getSystemService", "audio" );
return 0 >= audioManager.Call<int>( "getStreamVolume", 3 );
#endif
}
// 音量設定
public void SetVolume()
{
#if UNITY_ANDROID
AndroidJavaClass unityPlayer = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" );
AndroidJavaObject context = unityPlayer.GetStatic<AndroidJavaObject>( "currentActivity" );
AndroidJavaObject audioManager = context.Call<AndroidJavaObject>( "getSystemService", "audio" );
// 今回は最大ボリュームの半分に設定する仕様
int maxVolume = audioManager.Call<int>( "getStreamMaxVolume", 3 );
audioManager.Call( "setStreamVolume", 3, maxVolume / 2, 0 );
#endif
}
iOS
iOSの場合は工程が多いです...
1. プロジェクトフォルダの「Assets/Plugins/iOS」フォルダ以下に「PluginDeviceAudio.mm」を作成する
※ファイル名は自由で構いません。
※今回はObjective-Cでコーディングを行いました。
Androidで実装した「ミュート音量かどうか調べる/音量設定」関数を定義します。
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#import <AVFoundation/AVFoundation.h>
extern "C"
{
BOOL _PluginDeviceAudio_IsMuteVolume();
void _PluginDeviceAudio_SetVolume();
}
BOOL _PluginDeviceAudio_IsMuteVolume()
{
float volume = AVAudioSession.sharedInstance.outputVolume;
if( volume > 0.0 )
{
return NO;
}
return YES;
}
void _PluginDeviceAudio_SetVolume()
{
MPVolumeView *volumeView = [[MPVolumeView alloc] init];
UISlider *volumeSlider = nil;
for( UIView *view in [volumeView subviews] )
{
if( [NSStringFromClass(view.class) isEqualToString:@"MPVolumeSlider"] )
{
volumeSlider = (UISlider *)view;
break;
}
}
dispatch_after( dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
volumeSlider.value = 0.5f;
});
}
2. UnityからiOSビルドで出力されたXcodeプロジェクトに「MediaPlayer.framework」を追加するため「PostProcessBuild」ファイルを作成する
public static class PostProcessBuild
{
[PostProcessBuild(99)]
public static void OnPostProcessBuild( BuildTarget target, string path )
{
#if UNITY_IOS
if( target == BuildTarget.iOS )
{
_postProcessBuildIOS( path );
}
#endif
}
#if UNITY_IOS
private static void _postProcessBuildIOS( string path )
{
string projectPath = PBXProject.GetPBXProjectPath( path );
PBXProject pbxProject = new PBXProject();
pbxProject.ReadFromString( File.ReadAllText(projectPath) );
string target = pbxProject.TargetGuidByName( "Unity-iPhone" );
// framework追加
pbxProject.AddFrameworkToProject( target, "MediaPlayer.framework", true );
// 出力
File.WriteAllText( projectPath, pbxProject.WriteToString() );
}
#endif
}
3. 「PluginDeviceAudio.mm」ファイルに定義された関数を呼び出す
#if UNITY_IOS
[DllImport("__Internal")]
private static extern bool _PluginDeviceAudio_IsMuteVolume();
[DllImport("__Internal")]
private static extern void _PluginDeviceAudio_SetVolume();
#endif
// ミュート音量かどうか調べる
public bool IsMuteVolume()
{
#if UNITY_IOS
return _PluginDeviceAudio_IsMuteVolume();
#endif
}
// 音量設定
public void SetVolume()
{
#if UNITY_IOS
_PluginDeviceAudio_SetVolume();
#endif
}
まとめると上記のようになります。
あとは、アプリ側で
・IsMuteVolume
・SetVolume
を任意のタイミングで呼び出す流れとなります。
もう、Objective-C触りたくない・・・
また次回!