skip to content
私的歌詞倉庫

Androidの音量をリアルタイムで監視

/ 2 min read

Updated:
Table of Contents

はじめに

Android端末のボリュームをリアルタイムで監視し通知する方法です。

ContentObserverを使ってコールバックで音量を監視し、それをcallbackFlowでFlowに変換し通知します。

コード

Hiltを使ってDIしているので適宜読み替えてください。

interfaceを作成します。

interface VolumeObserver {
fun subscribe(): Flow<Int>
}

次に具体的な実装をしていきます。ContentObserverをcallbackFlowに変換しFlowで返します。

awaitCloseでFlowがキャンセルされた時にContentObserverの購読を解除することでメモリリークを防ぎます。

class VolumeObserverImpl @Inject constructor(
@ApplicationContext private val context: Context,
) : VolumeObserver {
private val uri = Settings.System.CONTENT_URI
private val contentResolver = context.contentResolver
private val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
override fun subscribe(): Flow<Int> = callbackFlow {
val contentObserver = object : ContentObserver(null) {
override fun onChange(selfChange: Boolean) {
super.onChange(selfChange)
val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
trySend(currentVolume)
}
}
contentResolver.registerContentObserver(
uri,
true,
contentObserver
)
trySend(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
awaitClose {
contentResolver.unregisterContentObserver(contentObserver)
}
}
}

呼び出すときはcollectして使います。

今回の実装では初回購読時に現在の音量を通知しているのでこれが不要な場合はdropして下さい。

volumeObserver
.subscribe()
.drop(1) // 初回購読時の音量が不要の場合はdropして下さい
.collect { volume ->
println(volume)
}

終わりに

今回はリアルタイムにAndroid端末の音量を監視する方法を紹介しました。

ContentObserverを始めて使いAndroid開発で知らないことが色々あるな…と実感しました。