Flutterで画面の自動消灯を防止!keep_screen_onパッケージ解説

Flutterアプリを開発していると、ユーザーが画面を操作していなくても、一定時間画面を表示し続けたいケースがあります。

例えば、

  • 動画を再生する
  • レシピを表示する
  • カーナビとして利用する
  • バーコードやQRコードを表示する
  • プレゼンテーション画面を表示する
  • 計測画面を表示する
  • 電子書籍を読む
  • ゲームをプレイする

といったアプリでは、OSによる自動スリープが発生するとユーザー体験が損なわれることがあります。

今回紹介する keep_screen_on は、Android・iOSで画面の自動消灯を防止するFlutterプラグインです。

KeepScreenOn.turnOn() を呼び出すだけで画面を点灯したままにでき、turnOff() を呼び出せば通常の自動消灯へ戻せます。Androidでは、さらに FLAG_ALLOW_LOCK_WHILE_SCREEN_ON を扱うこともできます。(Dart packages)

この記事では、keep_screen_on の基本的な使い方から、画面を常時点灯させる方法、状態の確認、Android固有の機能、StatefulWidget での利用方法まで詳しく解説します。

keep_screen_onとは?

keep_screen_on は、端末の画面が自動的に消灯するのを防ぐためのFlutterプラグインです。

通常、スマートフォンでは一定時間操作しないと画面が自動的に消灯します。

keep_screen_on を利用すると、

アプリ起動
   ↓
KeepScreenOn.turnOn()
   ↓
画面を点灯したままにする
   ↓
KeepScreenOn.turnOff()
   ↓
通常の自動消灯へ戻す

という制御ができます。(Dart packages)

Androidでは FLAG_KEEP_SCREEN_ON、iOSでは UIApplication.shared.isIdleTimerDisabled を利用して実現されています。(Dart packages)

keep_screen_onの特徴

主な特徴は以下の通りです。

機能対応
自動消灯の防止
自動消灯の再有効化
現在の状態確認
Android対応
iOS対応
Android固有のロック制御
FLAG_KEEP_SCREEN_ON
FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
Web×
Windows×
macOS×
Linux×

現在の keep_screen_on 6.0.0 はAndroid・iOS向けのプラグインとして提供されています。(Dart packages)

インストール

pubspec.yaml に追加します。

YAML

dependencies:
  keep_screen_on: ^6.0.0

または、以下のコマンドでも追加できます。

Bash

flutter pub add keep_screen_on

コードから利用する場合はインポートします。

Dart

import 'package:keep_screen_on/keep_screen_on.dart';

(Dart packages)

画面を消灯させない

基本的な使い方は非常にシンプルです。

Dart

KeepScreenOn.turnOn();

これだけで、アプリ実行中の自動画面消灯を防止できます。(Dart packages)

例えば、ボタンを押したときに画面を常時点灯へ変更するなら、

Dart

ElevatedButton(
  onPressed: () {
    KeepScreenOn.turnOn();
  },
  child: const Text('画面を点灯したままにする'),
)

と記述できます。

画面の自動消灯を元に戻す

常時点灯を解除する場合は turnOff() を利用します。

Dart

KeepScreenOn.turnOff();

これによって通常の自動消灯に戻ります。(Dart packages)

また、turnOn()on: false を指定する方法もあります。

Dart

KeepScreenOn.turnOn(on: false);

turnOff() と同じように、自動消灯を再び有効にできます。(Dart packages)

現在の状態を確認する

現在、画面の自動消灯が無効になっているか確認できます。

isOn プロパティを利用します。

Dart

final isOn = await KeepScreenOn.isOn;

print(isOn);

isOnFuture<bool?> を返します。(Dart packages)

逆に、自動消灯が有効な状態か確認する場合は isOff を利用できます。

Dart

final isOff = await KeepScreenOn.isOff;

print(isOff);

こちらも Future<bool?> を返します。(Dart packages)

StatefulWidgetで利用する

画面単位で常時点灯を有効にしたい場合は、StatefulWidget と組み合わせると便利です。

例えば、画面を開いたときに常時点灯を有効にし、画面を閉じるときに解除します。

Dart

class KeepScreenPage extends StatefulWidget {
  const KeepScreenPage({super.key});

  @override
  State<KeepScreenPage> createState() => _KeepScreenPageState();
}

class _KeepScreenPageState extends State<KeepScreenPage> {
  @override
  void initState() {
    super.initState();

    KeepScreenOn.turnOn();
  }

  @override
  void dispose() {
    KeepScreenOn.turnOff();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text('画面は消灯しません'),
      ),
    );
  }
}

このようにすると、この画面が表示されている間だけ自動消灯を防止できます。

disposeでturnOffする

keep_screen_on を利用する際に特に重要なのが、有効化したら適切なタイミングで解除することです。

公式ドキュメントでも、turnOn() を呼び出した後に turnOff() を呼び出すよう注意されています。解除を忘れると、アプリが実行されている間は自動消灯されない状態が続きます。(Dart packages)

そのため、

Dart

@override
void dispose() {
  KeepScreenOn.turnOff();

  super.dispose();
}

のように、dispose() で解除する構成が分かりやすいでしょう。

レシピアプリへの利用

料理中にスマートフォンでレシピを表示するアプリでは、画面を触らずにレシピを確認することがあります。

通常なら一定時間経過後に画面が消灯します。

keep_screen_on を利用すれば、

レシピ画面を表示
      ↓
画面を常時点灯
      ↓
料理中もレシピを確認
      ↓
画面を閉じる
      ↓
通常の自動消灯へ戻す

という使い方ができます。

QRコード・バーコード表示への利用

QRコードやバーコードを表示する画面でも便利です。

例えば、店舗で会員証やチケットを提示するアプリでは、ユーザーが画面を操作せずにコードを表示し続けることがあります。

Dart

@override
void initState() {
  super.initState();

  KeepScreenOn.turnOn();
}

表示画面を閉じたら、

Dart

@override
void dispose() {
  KeepScreenOn.turnOff();

  super.dispose();
}

としておけば、必要な画面だけ常時点灯にできます。

動画・メディアアプリへの利用

動画を視聴している間は、画面を消灯させたくない場合があります。

動画再生画面を開いたときに、

Dart

KeepScreenOn.turnOn();

とし、再生画面を離れるときに、

Dart

KeepScreenOn.turnOff();

とすることで、画面単位で制御できます。

ナビゲーションアプリへの利用

カーナビなど、常に地図を確認するアプリにも利用できます。

Dart

class NavigationPage extends StatefulWidget {
  const NavigationPage({super.key});

  @override
  State<NavigationPage> createState() => _NavigationPageState();
}

class _NavigationPageState extends State<NavigationPage> {
  @override
  void initState() {
    super.initState();

    KeepScreenOn.turnOn();
  }

  @override
  void dispose() {
    KeepScreenOn.turnOff();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text('Navigation'),
      ),
    );
  }
}

このように、ナビゲーション画面だけ常時点灯にできます。

AndroidのFLAG_KEEP_SCREEN_ON

Androidでは、KeepScreenOn.turnOn() を呼び出すと、内部的に

android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON

がActivityのWindowに設定されます。(Dart packages)

このAndroid標準の仕組みを利用して、画面の自動消灯を防止しています。

FLAG_ALLOW_LOCK_WHILE_SCREEN_ONを利用する

Androidでは、FLAG_KEEP_SCREEN_ON に加えて FLAG_ALLOW_LOCK_WHILE_SCREEN_ON を指定することもできます。

例えば、

Dart

KeepScreenOn.turnOn(
  withAllowLockWhileScreenOn: true,
);

とします。(Dart packages)

withAllowLockWhileScreenOntrue にすると、FLAG_KEEP_SCREEN_ON と一緒に FLAG_ALLOW_LOCK_WHILE_SCREEN_ON が指定されます。

FLAG_ALLOW_LOCK_WHILE_SCREEN_ONだけを変更する

Androidでは、このフラグだけを操作するAPIも用意されています。

追加する場合は、

Dart

KeepScreenOn.addAllowLockWhileScreenOn();

解除する場合は、

Dart

KeepScreenOn.clearAllowLockWhileScreenOn();

とします。(Dart packages)

FLAG_ALLOW_LOCK_WHILE_SCREEN_ONの状態を確認する

現在の設定状態は isAllowLockWhileScreenOn で確認できます。

Dart

final value =
    await KeepScreenOn.isAllowLockWhileScreenOn;

print(value);

このAPIはAndroid向けの機能です。Android以外では null が返ります。(Dart packages)

Android以外でAndroid専用APIを呼び出した場合

addAllowLockWhileScreenOnclearAllowLockWhileScreenOn などのAndroid専用機能は、Android以外では何も行いません。

公式ドキュメントでは、非Android環境における戻り値について、

API非Androidでの戻り値
addAllowLockWhileScreenOnfalse
clearAllowLockWhileScreenOnfalse
isAllowLockWhileScreenOnnull

とされています。(Dart packages)

そのため、Android専用機能を利用する場合でも、プラットフォームによる挙動の違いを考慮して実装できます。

iOSではどう動く?

iOSでは、turnOn() によって、

UIApplication.shared.isIdleTimerDisabled = true

が設定されます。(Dart packages)

これにより、iOSの自動スリープを無効化します。

turnOff() を呼び出すと通常の状態へ戻ります。

バックグラウンドに移動した場合

iOSでは、アプリがバックグラウンドへ移動すると自動消灯が復元されます。(Dart packages)

Androidでは、Activityが切り替わった場合、自動消灯の状態は切り替わったActivityに従います。(Dart packages)

このため、単純にアプリ全体で常時点灯を設定するより、必要な画面で有効化・解除する設計が扱いやすいでしょう。

アプリ全体で常時点灯にする

アプリ全体で画面を常時点灯させたい場合は、アプリ起動時に設定することもできます。

Dart

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  KeepScreenOn.turnOn();

  runApp(
    const MyApp(),
  );
}

ただし、この方法ではアプリ全体で自動消灯が無効になるため、必要な画面だけで利用する場合は画面単位で管理する方が適しています。

計測アプリへの利用

ストップウォッチやタイマー、計測アプリでは、計測中に画面が消えるとユーザーが困る場合があります。

例えば、

計測開始
   ↓
画面を常時点灯
   ↓
計測終了
   ↓
自動消灯を復元

という処理を実装できます。

Dart

void startMeasurement() {
  KeepScreenOn.turnOn();
}

void stopMeasurement() {
  KeepScreenOn.turnOff();
}

非常にシンプルに実装できます。

プレゼンテーション画面への利用

プレゼンテーションや展示用アプリでは、ユーザーが長時間操作しないことがあります。

その場合も、

Dart

KeepScreenOn.turnOn();

を利用することで、表示中の画面が自動消灯するのを防止できます。

メリット

シンプルなAPI

画面を常時点灯させるだけなら、

Dart

KeepScreenOn.turnOn();

だけで実装できます。

Android・iOSに対応

Androidでは FLAG_KEEP_SCREEN_ON、iOSでは isIdleTimerDisabled を利用して、それぞれのプラットフォームに合わせて動作します。(Dart packages)

状態を確認できる

isOnisOff を利用して、現在の設定状態を取得できます。(Dart packages)

Android固有の制御にも対応

必要であれば FLAG_ALLOW_LOCK_WHILE_SCREEN_ON も操作できます。(Dart packages)

画面単位で利用しやすい

StatefulWidgetinitState()dispose() を組み合わせることで、特定の画面だけ常時点灯にできます。

注意点

turnOffを忘れない

turnOn() を呼び出した後に turnOff() を呼び忘れると、アプリ実行中は自動消灯されない状態が続きます。公式ドキュメントでもこの点が明確に注意されています。(Dart packages)

バッテリー消費に注意

画面を点灯したままにすると、通常よりバッテリーを消費しやすくなります。

必要な画面・必要な時間だけ有効にするのがおすすめです。

Android固有機能がある

FLAG_ALLOW_LOCK_WHILE_SCREEN_ON 関連のAPIはAndroid専用です。

Web・デスクトップには対応していない

現在のpub.devの対応プラットフォームはAndroidとiOSです。(Dart packages)

まとめ

keep_screen_on は、Flutterアプリで画面の自動消灯を防止したい場合に利用できるシンプルなプラグインです。

基本的な使い方は、

Dart

KeepScreenOn.turnOn();

で有効化し、

Dart

KeepScreenOn.turnOff();

で通常の自動消灯へ戻すだけです。

主な特徴として、

  • 自動画面消灯の防止
  • 自動消灯の再有効化
  • 現在の状態確認
  • Android・iOS対応
  • Androidの FLAG_KEEP_SCREEN_ON
  • Androidの FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
  • StatefulWidget と組み合わせた画面単位の制御

などが挙げられます。(Dart packages)

特に、動画プレイヤー、レシピアプリ、ナビゲーション、計測アプリ、QRコード表示、プレゼンテーションなど、ユーザーが画面を操作していなくても表示を維持したいアプリで便利なパッケージです。

画面を常時点灯させるという目的に機能を絞っているため、複雑な設定を必要とせず導入できる点も魅力でしょう。

タイトルとURLをコピーしました