-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Android でのハンズフリーに対応する #69
Conversation
throw new IllegalStateException("Not on main thread!"); | ||
} | ||
} | ||
public static boolean runOnMainThread(Runnable action) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
自分のイメージする runOnMainThread は
- メインスレッド上で実行中なら即座に action を実行する
- そうでなければメインスレッドに action を投げて実行を依頼し
- 実行完了を待つ
です。1番目と3番目が自分のイメージと違います。
ただ Activity#runOnUiThread の場合、UI スレッド上で実行中なら actions を実行するのは同じですが、非 UI スレッドの場合は依頼を投げて実行完了を待たないようです。
どちらにせよ、メインスレッド上で実行中なら即座に action を実行するのはあった方が良さそうな感じです。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Activity#runOnUiThread の存在を知らなかったので、これで置き換える方向にしたいと思います。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
と思ったのですが、 Activity をこのレイヤーまで下ろしてないので、 runOnMainThread を
- メインスレッド上で実行中なら即座に action を実行する
- そうでなければメインスレッドに action を投げて実行を依頼する
という作りに変更しました。MainThreadWrapper もこれに合わせた作りに変えました。
* すでに接続済みの場合は startBluetoothSco ではインテントは発火しないが | ||
* registerReceiver を設定した際に発火する | ||
* ただ、その場合も startBluetoothSco は呼んでおかないと、 | ||
* 他のプログラムが stopBluetoothSco した際に終了してします |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
「終了してします」→「終了してしまう」
import java.util.List; | ||
import java.util.Set; | ||
|
||
public class SoraAudioManagerLegacy extends SoraAudioManagerBase { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SoraAudioManagerLegacy と SoraAudioManager2 は public class である必要は無さそうです。
ただユーザーの方でカスタマイズする時に使いやすいようにとかなら public でも良いかなとは思います。
} | ||
|
||
public static SoraAudioManager createWithMainThreadWrapper(Context context) { | ||
return new MainThreadWrapper(context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SoraAudioManager.createWithMainThreadWrapper が MainThreadWrapper を利用して、MainThreadWrapper の中で SoraAudioManager.create を利用して、依存が循環してるのが気になりますね。
new MainThreadWrapper(create(context))
にした方が、依存の向きが分かりやすくなるし、生成方法を外に出せて汎用性高くなりそうです。
(これだとユーザーが生成方法を指定できないから SoraAudioManager withMainThreadWrapper(SoraAudioManager manager)
みたいな関数があった方がより便利なんでしょうけど)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createWithMainThreadWrapper の作りをご指摘の形に合わせて変更しました。ベースにした AppRTC の名残でコンストラクタにメインスレッド実行制約がかかっていたのですが、コンストラクタのコードを洗ったところ無くても問題ないようだったので、これを解除して対応しました。withMainThreadWrapper もおまけなので作っておきました。
|
||
registerWiredHeadsetReceiver(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Override |
super.stop(); | ||
} | ||
|
||
// ハンズフリーかを確認する |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// ハンズフリーかを確認する | |
// ハンズフリーかを確認する | |
@Override |
return new SoraBluetoothManager(context, soraAudioManagerLegacy, audioManager); | ||
} | ||
|
||
protected SoraBluetoothManager( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
protected SoraBluetoothManager( | |
protected SoraBluetoothManager( |
@melpon ご指摘ありがとうございます🙏ご指摘いただいたところは一通り修正しましたので確認いただければと思います。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
よさそう
ありがとうございます!🙏 |
iOS のハンズフリーには #33 ですでに対応していますが、これに加えて Android のハンズフリーに対応します。
iOS の場合は C++ から容易に OS の API を利用することができますが、 Android では C++ からの OS の API 利用は煩雑ですので C++ での提供ではなく aar での提供とし利用するプロジェクトにおいてこれを取り込むこととしました。
Android でも iOS と同様の動きをになるようにしましたが、かなりのコード量となるため iOS とは異なり Unity SDK での利用だけでなく他でも使いやすいように意識してあります。
こんな感じで利用可能です
#33 の iOS と同様に
での切り替えが可能です。
しかしながら iOS とは異なりインスタンス生成が必要で、これは
SoraAudioManagerFactory.create
関数により行います。Android はオーディオデバイスの切り替えや Bluetooth ヘッドセットのスイッチングが 31 を境に大幅に変更されていることから、31 より前の Android に対応する
SoraAudioManagerLegacy
と以降に対応するSoraAudioManager2
を内部ために使い分けるためこのような実装になっています。また Android OS においては Bluetooth ヘッドセットへの接続制御は OS が行なっていないため、これをライブラリ内で行なっています。
加えてバックグラウンド音楽再生の一時停止処理など VoIP 向けのオーディオ設定を行う必要があるため。以下の 2 関数を用意してあります。
なお、ハンズフリーは iOS の場合には有線ヘッドセットや Bluetooth ヘッドセットを接続した際に強制解除されるため、同様の挙動を実装してあります。そのため、ユーザー操作起因でデバイスの変更があったことを通知する
OnChangeRouteObserver
を用意してあります。以上、ご確認ください🙏