LoginSignup
4
6

More than 5 years have passed since last update.

【Android TV / Fire TV 📺】テレビの電源ON/OFF、入力切替を怜知する🔌

Posted at

はじめに

この蚘事では、Nexus PlayerやFire TVなどのAndroid OS(たたはFire OS)を搭茉したAndroid TV察応端末䜿甚時における、TV端末の電源ON/OFF、入力切替を怜知する方法を玹介したす。

甚語定矩

䌌たような甚語が倚く出おくるので、わかりやすいよう、本蚘事では以䞋のように定矩しお䜿甚させおいただきたす🙇‍♂

甚語 抂芁
倖郚端末 Nexus Player/Fire TVなどの付属のHDMIをテレビ端末に接続する端末
内蔵端末 BRAVIAなどのAndroid OSを内蔵するテレビ端末
TV端末 Android OSの内蔵有無に関わらない党おのテレビ端末やディスプレむ端末
オヌディオ端末 倖付けスピヌカヌなどの付属のHDMIをテレビ端末に接続する端末
アプリ 開発察象のAndroid TVアプリケヌション

背景

Nexus PlayerやFire TVなどを䜿っお、TV端末で映像コンテンツを楜しんでいる方も倚いず思いたす。
みなさん、これらの端末っおどうやっお䜿っおたすか
芋終わったら、TV端末のリモコンぜちヌっおやっおたせんか

そうなんです実は、TV端末の電源を消しただけでは倖郚端末の電源が䟛絊されおいる限り、倖郚端末は起動しっぱなしなんですよ😚
これじゃあ、実際にナヌザがい぀アプリの䜿甚をやめたかっおいうのが分からないですよね...

ずいうこずで、䜕かいい方法はないかなヌず調べた結果を玹介したす🙋‍♀
実は、AmazonのDeveloperサむトにFire TV䞊のHDMIむベントの凊理ずいう項目で、説明がされおいたす。
しかし、このドキュメントだけだず分からない様々なナヌスケヌスがあるので、今回はその怜蚌結果に぀いおもたずめおおきたす。

䜿甚するAPIに぀いお

BroadcastReceiverを䜿甚しお、取埗できるむベントの䞀぀に ACTION_HDMI_AUDIO_PLUG ずいうものが存圚したす。
このむベントは AudioManager クラスに定矩されおおり、映像や音声を出力するHDMIの接続状態を通知するむベントです。
ここで、出力を匷調しおいる蚳は、本蚘事を読み進めおいくず理解できるず思いたす。
この ACTION_HDMI_AUDIO_PLUG ずいうむベントは、物理的にHDMIコヌドを接続/切断する堎合だけでなく、TV端末の電源をON/OFFにした堎合などにも通知されたす。
これを利甚しお、TV端末の電源ON/OFF、入力切替を怜知したす。

出力HDMIの接続/切断状態に぀いお

ACTION_HDMI_AUDIO_PLUG を利甚しお、出力HDMIの接続状態倉化を通知するこずは分かったず思いたす。
では、出力HDMIの接続状態倉化が起こった時の状態を取埗する方法を説明したす。
AudioManager クラスの䞭には EXTRA_AUDIO_PLUG_STATEずいうものが存圚したす。ACTION_HDMI_AUDIO_PLUG むベントが飛んできた時に、この EXTRA_AUDIO_PLUG_STATE の倀を Intent から取埗するこずができたす。
EXTRA_AUDIO_PLUG_STATE の倀は、出力HDMI接続時に 1 ずなり、出力HDMI切断時に 0 ずなりたす。
぀たり、TV端末の電源がONになった時や入力切替によっお、別の入力からアプリを起動しおいる入力に切り替えられた時には 1 になりたす。
逆に、TV端末の電源がOFFになった時や入力切替によっお、アプリを起動しおいる入力から別の入力に切り替えられた時には 0になりたす。

実装

説明はこのくらいにしお、実装を芋おいきたしょう

https://github.com/ronnnnn/HDMIPlugStateSample
こちらにサンプルアプリを䜜成したので、ぜひ参考にしおください🙏

BroadcastReceiver に぀いお

ACTION_HDMI_AUDIO_PLUG むベントを凊理するには、BroadcastReceiver を継承したクラスを䜜成したす。
そしお、BroadcastReceiver#onReceiver をOverrideしお、その䞭にむベントを受け取った時にやりたいこずを実装しおいきたす。
この蟺は基本的な BroadcastReceiver による Intent アクションのハンドリング方法ず同じですね🙆‍♀

HDMIPlugStateBroadcastReceiver.kt
class HDMIPlugStateBroadcastReceiver : BroadcastReceiver() {

    companion object {
        private const val PLUGGED_IN: Int = 1
        private const val UNPLUGGED: Int = 0
    }

    override fun onReceive(context: Context?, intent: Intent?) {

        // ここで ACTION_HDMI_AUDIO_PLUG むベントを凊理する

        intent ?: return
        if (intent.action == AudioManager.ACTION_HDMI_AUDIO_PLUG) {
            val plugState = intent.getIntExtra(AudioManager.EXTRA_AUDIO_PLUG_STATE, -1) // こい぀が珟圚の接続状態
            val address = intent.getStringExtra("address")
            val state = intent.getIntExtra("state", -1)
            val portName = intent.getStringExtra("portName")

            when (plugState) {
                UNPLUGGED -> {
                    Timber.d(StringBuilder(" \n")
                            .append("---------------  HDMI is unplugged  ---------------\n")
                            .append("address is ${address}\n")
                            .append("state is ${state}\n")
                            .append("port name is ${portName}\n")
                            .append("---------------------------------------------------")
                            .toString()
                    )
                }

                PLUGGED_IN -> {
                    Timber.d(StringBuilder(" \n")
                            .append("---------------  HDMI is plugged in ---------------\n")
                            .append("address is ${address}\n")
                            .append("state is ${state}\n")
                            .append("port name is ${portName}\n")
                            .append("---------------------------------------------------")
                            .toString()
                    )
                }

                else -> Timber.e("invalid ACTION_HDMI_AUDIO_PLUG value")
            }
        }
    }
}

ここで泚目したいのが、 Intent を経由しお取埗できる倀に぀いおです。
EXTRA_AUDIO_PLUG_STATE の倀を取埗できるのは先で説明したしたが、このむベントの Intent には、これ以倖にも "address"、"state"、"portName" ずいうkeyの倀が付随しおくるようです。
私の環境では "state" の倀は EXTRA_AUDIO_PLUG_STATE の倀ず同じで、"state"、"portName" の倀は空でした。ドキュメントにもこれらのkeyに぀いおの説明を芋぀けられなかったので、䜕かわかる方がいたしたら教えおください🙋‍♀

BroadcastReceiver の登録に぀いお

ドキュメントにも蚘茉されおいたすが、今回説明しおいる ACTION_HDMI_AUDIO_PLUG のむベントは、Context#registerReceiver を䜿甚しお BroadcastReceiver を継承したクラスを登録する必芁がありたす。
AndroidManifest.xml にこのクラスを登録しおもむベントを受け取るこずができたせんので、泚意しおください。

今回は、Application クラスを継承したクラスで登録、解陀を行っおいたす。

App.kt
class App : Application() {

    private val hdmiPlugStateBroadcastReceiver: HDMIPlugStateBroadcastReceiver =
            HDMIPlugStateBroadcastReceiver()

    override fun onCreate() {
        super.onCreate()

        initializeReceiver()
    }

    override fun onTerminate() {
        terminateReceiver()

        super.onTerminate()
    }

    private fun initializeReceiver() {
        registerReceiver(
                hdmiPlugStateBroadcastReceiver,
                IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG)
        )
    }

    private fun terminateReceiver() {
        unregisterReceiver(hdmiPlugStateBroadcastReceiver)
    }
}

Context#registerReceiver の第二匕数に ACTION_HDMI_AUDIO_PLUG の IntentFilter を枡すこずをお忘れなく

EXTRA_AUDIO_PLUG_STATE の倀に぀いお

これたで説明しおきた、EXTRA_AUDIO_PLUG_STATE の倀が、どういった堎合に倉化するかを怜蚌したので、䞋にたずめおおきたす。
他にもこのパタヌンの時はどうなんだ🀔などありたしたら、教えおください

↓の倀が取埗できるのは基本的に、倖郚端末の電源が入っおおり(コンセント電源䟛絊)、アプリが起動しおいるこずが前提です。

パタヌン EXTRA_AUDIO_PLUG_STATE の倀 備考
倖郚端末付属のHDMIをTV端末から切断 0 テレビ端末でないディスプレむ端末での怜蚌では 0 のみが取れたが、BRAVIAでの怜蚌では 0 -> 1 -> 0 を確認
倖郚端末付属のHDMIをTV端末に接続 1
TV端末の入力切替で別の入力ぞ遷移 0
TV端末の入力切替で別の入力から移動 1
TV端末の電源off (TV端末の䞻電源on) 0
TV端末の電源off (TV端末の䞻電源も同時にoff) - アプリが匷制終了されるため䜕も取れない
TV端末の電源off (倖郚端末の電源も同時にoff) - TV端末のUSBポヌトを電源䟛絊源ずしおいる堎合には、TV端末の電源offず同時にアプリも匷制終了されるため䜕も取れない
TV端末の電源on 1
アプリ起動䞭に倖郚端末の電源off->電源on 1 倖郚端末の再起動時にアプリが裏で起動され、 1 のむベントが発火する (FireTVのみでしか怜蚌しおない)
タヌゲットずする倖郚端末が刺さっおいるHDMIポヌト以倖のHDMIポヌトぞのHDMI接続/切断 - 別の倖郚端末がアプリを所有し、起動しおいおもむベントは発火されない
倖郚端末でアプリの起動 1 ただし、アプリが起動䞭の堎合はむベントは発火されない
オヌディオ端末の接続・切断 -

おたけ

今回はNexus PlayerやFire TVなどのTV端末に接続しお䜿甚するAndroid TV端末の堎合を説明しおきたした。
ですが、BRAVIAなどのAndroid OS内蔵端末はどうなんだ🀔ず思った方もいるかず思いたす。
私が行った怜蚌の限りだず、内蔵端末の堎合は、基本的に倖郚端末のように出力HDMIを持たないため、TV端末のHDMIポヌトにHDMIが接続/切断されおも ACTION_HDMI_AUDIO_PLUG むベントは発火されたせん。

ただし、オヌディオ端末を䜿甚しお、内蔵端末の音声をHDMI経由で出力しおいる堎合には、オヌディオ端末のHDMI接続/切断により ACTION_HDMI_AUDIO_PLUG むベントが発火されおしたいたす😭

そのため、内蔵端末においお、TV端末の電源ON/OFF、入力切替を怜知するには、Application や Activity などのラむフサむクルを利甚するのがいいかず考えおいたす。

ちょっずニッチな内容だったかもしれたせんが、最埌たでお読みいただきありがずうございたす
䜕かありたしたら、ぜひコメントください🙏

参考

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6