【Kotlin/Android】端末の画面の明るさをコードから変更する方法!WindowManager

【Kotlin/Android】端末の画面の明るさをコードから変更する方法!WindowManager

この記事からわかること

  • Android Studio/Kotlin端末画面明るさ変更するには?
  • window.attributes.screenBrightnessプロパティ
  • WindowManager.LayoutParamsで指定できる値

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

端末の画面の明るさをコードから変更する方法

Kotlinで端末の画面の明るさをコードから変更するにはwindow.attributes.screenBrightnessプロパティにWindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF/BRIGHTNESS_OVERRIDE_FULLなどを指定し再度attributesにセットします。例えば以下のように実装すると端末の画面の明るさを最大にすることができます。


// 画面の明るさを一番明るくする
window.attributes.apply {
    screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL
    window.attributes = this
}

screenBrightnessに設定できる定数が3種類用意されています。

public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
    // 画面の明るさを一番明るくする
    public static final float BRIGHTNESS_OVERRIDE_FULL = 1.0F;
    // 画面の明るさをユーザー設定値に戻す
    public static final float BRIGHTNESS_OVERRIDE_NONE = -1.0F;
    // 画面の明るさを一番暗くする
    public static final float BRIGHTNESS_OVERRIDE_OFF = 0.0F;
}

カスタム値を渡すことで微妙な明るさの調整を行うことも可能です。ただ例えば0.1を指定しても明るい端末もあれば暗い端末もあり、端末によって設定される明るさはまちまちのようです。


// 画面の明るさを50%にする
window.attributes.apply {
    screenBrightness = 0.5f
    window.attributes = this
}

またアプリ内から明るさを変更しても端末自体の設定は変更されないためアプリを停止させるとユーザーの設定していた明るさに戻ってくれるようです。これはwindow.attributes.screenBrightnessで制御できるのがあくまでActivity単位で設定しているためです。

ユーザーの設定値を取得する

ユーザーが現在端末で設定している明るさはscreenBrightnessに設定されている値を取得すればOKです。公式の実装でも以下のようにpreviousBrightnessに値をプールしておくような実装が推奨されています。

private var previousBrightness: Float = -1.0f

/** 画面の明るさを最大にする */
private fun maximizeScreenBrightness() {
    activity?.window?.let { window ->
        window.attributes?.apply {
            previousBrightness = screenBrightness
            screenBrightness = 1f
            window.attributes = this
        }
    }
}

/** 画面の明るさをユーザー初期設定値に戻す */
private fun restoreScreenBrightness() {
    activity?.window?.let { window ->
        window.attributes?.apply {
            screenBrightness = previousBrightness
            window.attributes = this
        }
    }
}

ただ私の端末のscreenBrightnessから取得できた値は常に-1.0でした。ユーザーが例えば明るさを80%にしていても0.8fが取得できるわけではないようで、おそらく「ユーザー設定値かどうか」だけが取得できるみたいです。

iOS

システム明るさを取得・更新する

screenBrightnessアプリ表示中に限りの明るさを取得・制御していましたが、デバイス自体の明るさを取得・制御するためにはSettings.SystemからSettings.System.SCREEN_BRIGHTNESSを指定して取得します。取得できる値は0 ~ 255の整数になっているようです。

private fun getSystemBrightness(context: Context): Int {
    return try {
        // システムの明るさを取得する
        Settings.System.getInt(context.contentResolver, Settings.System.SCREEN_BRIGHTNESS)
    } catch (e: Settings.SettingNotFoundException) {
        e.printStackTrace()
        -1 // エラー時
    }
}

ただ取得できた値は61%の状態で38となっており、本来なら255 × 0.61 ≒ 155になるかと思いますが想定通りの値は取得できませんでした。これはデバイスに依存して値がぶれるのかもしれません。

明るさの自動調節のON/OFFを取得する

「設定」>「ディスプレイ」>「明るさの自動調節」から設定できる明るさの自動調節のON/OFF状態を取得することも可能です。Settings.System.SCREEN_BRIGHTNESS_MODEを指定しSettings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATICであればONになっている状態になります。

/** 明るさの自動調節の有効/無効をチェック */
private fun isAutoBrightnessEnabled(): Boolean {
    return try {
        Settings.System.getInt(
            contentResolver,
            Settings.System.SCREEN_BRIGHTNESS_MODE
        ) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
    } catch (e: Settings.SettingNotFoundException) {
        false
    }
}

システムの明るさを更新する

システムの明るさを更新するためにはWRITE_SETTINGS権限が必要になります。まずは「AndroidManifest.xml」に以下を追加します。


<uses-permission android:name="android.permission.WRITE_SETTINGS" />

続いてアプリからシステム設定を変更できるようにユーザーに対して許可要求を実装します。

/** システム設定の変更許可要求 */
private fun requestWriteSettingsPermission(context: Context) {
    if (!Settings.System.canWrite(context)) {
        val intent = Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS)
        intent.data = Uri.parse("package:${context.packageName}")
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        context.startActivity(intent)

        Toast.makeText(context, "システム設定の変更を許可してください", Toast.LENGTH_LONG)
            .show()
    }
}

更新するにはputIntを使用します。これでシステムの明るさをアプリから制御することが可能です。ただこちらの実装はアプリをキルしても明るさがそのままになってしまうので考慮してあげる必要がありそうです。

/** システムの明るさを更新する */
private fun setSystemBrightness(context: Context, brightness: Int) {
    if (Settings.System.canWrite(context)) {
        // 安全範囲に制限
        val safeValue = brightness.coerceIn(0, 255) 
        Settings.System.putInt(
            context.contentResolver,
            Settings.System.SCREEN_BRIGHTNESS,
            safeValue
        )
    } else {
        requestWriteSettingsPermission(context)
    }
}

以下のように128を指定してみましたが、デバイスでは87%になったので意図しない明るさにならないように制御は必要そうです。

setSystemBrightness(this, 128)

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article