周囲の明るさに応じた画面の輝度の調整

現在、時計アプリの製作中なのですが、周囲の明るさに応じて画面の明るさを変えられたらいいなと思い、その部分をテストするためのアプリを作りました。

今までは入力も結果表示もスマホ画面か音声の出力しかやっていなかったので、周囲の明るさを取得する照度センサーや輝度を調整するバックライトの操作は「難しそう」の先入観がありました。 しかしやってみると輝度の調整は簡単でした。onCreate(・・・) の下、setContentView(・・・) の後に次の3行を付け加えるだけ。
 
(kotlin)

 val lp = window.attributes  		//ウインドウの属性を取得
        lp.screenBrightness = 0.1f 	//属性の中で輝度を0.5に設定(最大値は1.0)
        window.attributes = lp 
なんなら、次の1行でもよい。(ただし後述の問題点あり)
 
(kotlin)

 window.attributes.screenBrightness = 0.1f
 
 
いっぽう照度の取得は少し面倒。SensorEventListenerというインターフェースが必要で、sensorManagerというクラスも使う必要があります。 次のコードで、スマホ付属の照度センサーの有無と、センサーがある場合にはその測定値が画面表示されます。
 
(kotlin)


class MainActivity : AppCompatActivity(), SensorEventListener { //SensorEventListenerというインターフェースをつけておくことが必要。


    private lateinit var sensorManager: SensorManager            //SensorManagerを遅延初期化
    private var lightSensor: Sensor? =
        null                        //SensorクラスのlightSensorをメンバ変数として作っておく(onCreate、onResumeの両方で使うので)
    private lateinit var textViewValue: TextView
    private lateinit var textViewExist: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        lightSensor =
            sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)                //センサーの中で照度計をlightSensorとして設定

        textViewValue = findViewById<TextView>(R.id.txtIlluminunce)    // 「>」と「<」は全角にしています。
        textViewExist = findViewById<TextView>(R.id.txtLightSensor)       // 「>」と「<」は全角にしています。

    }

    override fun onAccuracyChanged(
        sensor: Sensor,
        accuracy: Int
    ) {                //照度計の精度が変化したときの関数は、今回は空欄としておく。
    }

    override fun onSensorChanged(event: SensorEvent) {
        val lux = event.values[0]

        textViewValue.text = "照度センサー値:\n" + lux.toString()
    }

    override fun onResume() {
        super.onResume()
        lightSensor?.also { light ->
            sensorManager.registerListener(
                this,
                light,
                SensorManager.SENSOR_DELAY_NORMAL
            )    //sensorManager にリスナーと登録。
        }


        if (sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) != null) {     //照度センサーの有無を判定
            textViewExist.text = "照度センサー:\nあり"
        } else {
            textViewExist.text = "照度センサー:\nなし"
        }
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(this)            //sensorManagerへのリスナーの登録を解除
    }
}       
        
 次に、照度が変化したとき輝度を変えるため、onSensorChanged のところを次のようにしてみました。
 
(kotlin)

 override fun onSensorChanged(event: SensorEvent) {
        val lux = event.values[0]

        textViewValue.text = "照度センサー値:\n" + lux.toString()
        
         if (lux < 60) {              //ここから下を付け加えた。
            window.attributes.screenBrightness = 0.1f	//照度が60未満の時、画面輝度は0.1
         } else {
            window.attributes.screenBrightness = 1.0f	//照度が60以上の時、画面輝度は1.0
            }
    }
 しかし画面の明るさは調節できない・・・どういうことか。
ここで、onSensorChangedの中では輝度の調整ができないのかと思い、SharedPreferenceを使ってluxの値を onCreateのほうへ受け渡そうとしてみたり、1秒ごとにonCreateからluxの値を確認する方法などいろいろ、 みっともないやり方をやってみたけど、できない・・・
結果的には、最初の「なんなら、次の1行でもよい。」が災いのもとでした。
この1行は、ocCreateの直下じゃないと効かないみたいです。
理由は・・・よくはわかりません(基本がわかってないのがばれますが、詳しい方がいたら教えてください)。
参考にさせてもらったブログにあったとおり、つまり最初にお見せした3行を使えばよかった。
 
  val lp = window.attributes  		
        lp.screenBrightness = 輝度の値	
        window.attributes = lp 
ということで、できあがりは次のとおりです。onSensorChangedのところで、60ルクス以上と未満で画面の輝度を切り替えています。
 
(kotlin)

class MainActivity : AppCompatActivity(), SensorEventListener { //SensorEventListenerというインターフェースをつけておくことが必要。

    private lateinit var sensorManager: SensorManager   //SensorManagerを遅延初期化
    private var lightSensor: Sensor? =  null          //SensorクラスのlightSensorをメンバ変数として作っておく(onCreate、onResumeの両方で使うので)
    private lateinit var textViewValue: TextView
    private lateinit var textViewExist: TextView
    var lux: Float =0f

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)                //センサーの中で照度計をlightSensorとして設定
        textViewValue = findViewById(R.id.txtIlluminunce)    // 「>」と「<」は全角にしています。
        textViewExist = findViewById(R.id.txtLightSensor)       // 「>」と「<」は全角にしています。
     }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {  //照度計の精度が変化したときの関数。今回は空欄としておく。
    }

    override fun onSensorChanged(event: SensorEvent) {
        lux = event.values[0]
        val pref = getSharedPreferences("brightness", MODE_PRIVATE)
        pref.edit().putFloat("lux",lux).apply()

        textViewValue.text = "照度センサー値:\n" + lux.toString()

        val lp = window.attributes  		//ウインドウの属性を取得
        if (lux < 60) {              //照度が60未満なら画面を暗く、それ以上なら明るくする

            lp.screenBrightness = 0.1f 	//属性の中で輝度を0.1に設定
            findViewById(R.id.txtScreenBrightness).text = "暗"
            } else {
            lp.screenBrightness = 1.0f 	//属性の中で輝度を1.0に設定
            findViewById(R.id.txtScreenBrightness).text = "明"
            }
        window.attributes = lp  //windowの属性をlpとする
    }

    override fun onResume() {
        super.onResume()
        lightSensor?.also { light ->
            sensorManager.registerListener(
                this,
                light,
                SensorManager.SENSOR_DELAY_NORMAL
            )    //sensorManager にリスナーと登録。
        }

        if (sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) != null) {     //照度センサーの有無を判定
            textViewExist.text = "照度センサー:\nあり"
        } else {
            textViewExist.text = "照度センサー:\nなし"
        }
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(this)            //sensorManagerへのリスナーの登録を解除
    }
}
これで動きました。照度センサーを指で押さえて照度が60を下回るようにすると、スッと画面が暗くなります。何とか課題達成です。

次のサイトを参考にさせていただきました。
https://techbooster.org/android/device/1604/
https://wakky.tech/android-control-torchlight-by-sensor/
どうもありがとうございました。

コメント

このブログの人気の投稿

目覚まし時計アプリを公開します

超初心者の機械学習入門

画面回転で苦労した話(原因はわかった)