使わないでホコリを被っていたAndroid端末に赤外線機能が付いていたので、テレビリモコンとして使えないかイジイジしてみたお話です。
環境
端末名:HUAWEI honor8
テレビ:SHARP AQUOS LC-32H11
ConsumerIrManager
赤外線機能を使うには ConsumerIrManager
を使います。APIレベルは19。
https://developer.android.com/reference/android/hardware/ConsumerIrManager
getSystemService
で CONSUMER_IR_SERVICE
を指定する形です。
val consumerIrManager = getSystemService(Context.CONSUMER_IR_SERVICE) as ConsumerIrManager
パーミッションの追加
ConsumerIrManager
のメソッドをそのまま使おうとすると java.lang.SecurityException: Requires TRANSMIT_IR permission
という例外が発生してしまうので、パーミッションを追加する必要があります。
<uses-permission android:name="android.permission.TRANSMIT_IR" />
TRANSMIT_IR
というなかなか見慣れないパーミッションですが、これでOKでした。
赤外線機能が使えるのかどうかのチェック
今回は赤外線機能がある端末で検証しておりますが、赤外線機能が無い端末の場合に ConsumerIrManager
のメソッドを使うと java.lang.UnsupportedOperationException: IR emitter not available
という例外が発生するため、そもそも赤外線機能があるのかどうかのチェックもすることができます。
if (consumerIrManager.hasIrEmitter()) {
// ある場合
} else {
// 無い場合
}
hasIrEmitter()
メソッドで赤外線機能があるかどうかがわかるので、シンプルにそれを使えばOKでした。
赤外線を送信する
本題となる赤外線送信に関して。
transmit
メソッドを使います。
https://developer.android.com/reference/android/hardware/ConsumerIrManager.html#transmit(int,%20int[])
引数は2つで carrierFrequency
と pattern
。
carrierFrequency
carrierFrequency
は日本語に訳すと「キャリア周波数」らしいですが、正直さっぱり
リモコンの場合は、 http://www.256byte.com/remocon.htm のページによると
一部のリモコンを除いた大抵のリモコンでは38kHzが利用されています。
とのことで、実際に 38000
を指定したらOKでした。
pattern
これは赤外線のパターンで、リモコンの場合各ボタンに対してパターンがある、という感じみたいです。
今回はSHARP製のテレビだったので色々と調べたところ、👇のリポジトリに各ボタンに対するパターンがまとまっておりまして、ここに記載のある値を拝借して使ってみたところOKでした。
https://github.com/misscrocodile/sharp-remote/blob/master/remoteControl/remoteControl.ino
サンプルコード
以上のことを踏まえたサンプルコードは下記のような感じです。
enum class Pattern(val value: IntArray) {
ON_OFF(
arrayListOf(3350, 1700, 400, 400, 450, 1200, 450, 400, 450, 1250, 400, 400, 400, 1300, 400, 400, 400, 1250, 450, 400, 400, 1250, 400, 400, 450, 1250, 400, 1250, 400, 400, 450, 1250, 400, 400, 450, 1250, 400, 1250, 400, 1300, 400, 1250, 400, 400, 400, 400, 450, 400, 450, 1200, 450, 400, 400, 1300, 400, 400, 400, 400, 450, 1250, 400, 400, 450, 400, 400, 400, 450, 400, 450, 1250, 400, 1250, 400, 400, 450, 1250, 400, 400, 450, 400, 400, 400, 450, 1250, 400, 400, 450, 400, 400, 400, 450, 1250, 400, 400, 450, 1200, 450, 1250, 400).toIntArray()
)
// ... 他のパターン
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// ON/OFFボタン押下でON/OFFのパターンを送信
findViewById<View>(R.id.button_on_off).setOnClickListener {
val consumerIrManager =
getSystemService(Context.CONSUMER_IR_SERVICE) as ConsumerIrManager
if (consumerIrManager.hasIrEmitter()) {
consumerIrManager.transmit(38000, Pattern.ON_OFF.value)
} else {
Toast.makeText(this, "赤外線未対応です。", Toast.LENGTH_SHORT).show()
}
}
}
}
実際の様子
非常にわかりにくく、ガッキーが写っていることに目が行っちゃいますが、ボタン押下でテレビのON/OFFが切り替わっている様子です。
まとめ
とりあえず赤外線に関して全く理解しておりませんが、Androidからテレビの操作をすることができました。
ConsumerIrManager
を使うことで、思いの外簡単に赤外線通信ができるので、例えばプッシュ通知を受け取ったタイミングで赤外線通信を行うなどの仕組みを作れば、IoT的なことも実現できそうだなと思いました。
参考Qiita
Android向け赤外線送信アプリ作成した時の備忘録
https://qiita.com/h-adachi/items/9d70d46904734ffced6a