画面を ON のままにする方法

バッテリーを長持ちさせるために、通常はある程度の時間が経ったら画面を暗く、あるいは薄暗くします。

ディスプレーの設定 (Screen Timeout) にて、どの程度の時間が経った後にスクリーンを OFF にするか設定可能です。

通常はそれでいいのですが、例えばビデオや TV の画像を再生するアプリケーションで動画を見ているときに、1分おきに画面が暗くなっても困りますよね。

この場合、このアプリケーションの開発者は動画プレーヤーを使っているときだけ画面が OFF にならないように(逆に言えば ON のままに) するとよいでしょう。

ここではシステムの設定に関わらず、画面を ON のままにする方法を説明します。

パワーマネージャからロックを取得

画面を ON にしておくには、PowerManager (パワーマネージャ) の newWakeLock メソッドで WakeLock を取得して、そのロックを取得します。

コードは次のようになります。

import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
...
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
WakeLock lock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My tag");
lock.acquire();
//ここの間、画面をONのままにできる
lock.release();

ここでは CREEN_DIM_WAKE_LOCK というタイプの WakeLock を取得していますが、後述のようにロックには他の種類もあります。 用途に合わせてタイプを選んでください。

パーミッションの設定

WakeLock を利用する場合はパーミッション (WAKE_LOCK) を AndroidManifest.xml に設定します。

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

ウェイクロックの種類

newWakeLock に渡すパラメータで、どんな種類のウェイクロックにするか決められます。

CPUスクリーンキーボード
PARTIAL_WAKE_LOCKONOFFOFF
SCREEN_DIM_WAKE_LOCKON薄暗い(Dim)OFF
SCREEN_BRIGHT_WAKE_LOCKON明るいOff
FULL_WAKE_LOCKON明るい明るい

スクリーン (ディスプレイ) はバッテリーを食う主な要因になるので、特別に薄暗くする (dim) というオプションもあります。

例えば私の現時点の端末 (DROID X Gingerbread) でバッテリーの利用状況を見ると、次のようにディスプレイにて主にバッテリーが消費されていることが分かります。

Android のバッテリー利用状況

マーケティングリサーチ調査会社の MM 総研が 2011年5月に発表した資料によると、スマートフォンユーザーはバッテリーの持ちに不安を持っている人が多いという結果がでています。 バッテリーを食うアプリは嫌われる可能性は高いと思うので、スクリーンを ON にしておく必要があるかどうかはしっかり検討すべきです。

パワーマネージャの動作の確認プログラム

ウェイクロックの種類によって動作がどのように変わるか確認するためのプログラムを作りました。

WakeLock のテスト

"Acquire Lock" ボタンをクリックすると、WakeLock の選択画面が表示されます。

WakeLock のテスト

ロックを選択すると、そのロックを取得します。選択されたロックの種類は画面にも表示されています。

WakeLock のテスト

この状態でロックが効いています。選択したロックの種類に応じた動きがみられるはずです。例えば、FULL_WAKE_LOCK を選択すれば画面は明るいままのはずです。

ロックを解除するには "Release Lock" を押します。

上記のソースは次の通りです。

まず、画面のレイアウトは次の通り。リニアレイアウトで、ボタン二つ、TextView を並べています。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
<Button
  android:id="@+id/lock_button"
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content" 
  android:text="Acquire Lock"/>
<Button
  android:id="@+id/unlock_button"
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content" 
  android:text="Release Lock"/>
<TextView
  android:id="@+id/lock_type"
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content"
  android:gravity="center"
  android:textSize="20sp"
  android:text=""/>
</LinearLayout>

タイプの選択ダイアログのため、次のような文字列配列も用意します。

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="app_name">WakeLock1</string>
  <string-array name="locktype">
    <item>PARTIAL_WAKE_LOCK</item>
    <item>SCREEN_DIM_WAKE_LOCK</item>
    <item>SCREEN_BRIGHT_WAKE_LOCK</item>
    <item>FULL_WAKE_LOCK</item>
  </string-array>
</resources>

本体のコードは次の通り。 PowerManager は onCreate で作成して、ボタンを押したときに選択したタイプに応じてウェイクロックを作成しています。

package com.keicode.android.test;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.PowerManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class WakeLock1 extends Activity implements OnClickListener {

  final static String TAG = "WakeLock1";
  PowerManager powerManager;
  PowerManager.WakeLock wakeLock;
  
  Button lockButton;
  Button unlockButton;
  TextView typeTextView;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    typeTextView = (TextView)findViewById(R.id.lock_type);
    lockButton = (Button)findViewById(R.id.lock_button);
    unlockButton = (Button)findViewById(R.id.unlock_button);
    lockButton.setOnClickListener(this);
    unlockButton.setOnClickListener(this);
    enableLockButton(true);
    
    powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
  }

  @Override
  public void onClick(View v) {
    switch(v.getId()){
    case R.id.lock_button:
      acquireLock();
      break;
    case R.id.unlock_button:
      releaseLock();
      break;
    }
    
  }
  
  protected void acquireLock(){
    new AlertDialog.Builder(this)
    .setTitle("Lock Type")
    .setItems(R.array.locktype,
    new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
        Log.d(TAG, "which = " + which);
        int flag = 0;
        switch(which){
        case 0:
          flag = PowerManager.PARTIAL_WAKE_LOCK;
          break;
        case 1:
          flag = PowerManager.SCREEN_DIM_WAKE_LOCK;
          break;
        case 2:
          flag = PowerManager.SCREEN_BRIGHT_WAKE_LOCK;
          break;
        case 3:
          flag = PowerManager.FULL_WAKE_LOCK;
          break;
        }
        
        wakeLock = powerManager.newWakeLock(flag, TAG);
        wakeLock.acquire();
        enableLockButton(false);
        showLockType(flag);
      }
    })
    .show();
  }
  
  protected void releaseLock(){
    wakeLock.release();
    enableLockButton(true);
    showLockType(0);
  }

  protected void enableLockButton(boolean b){
    lockButton.setEnabled(b);
    unlockButton.setEnabled(!b);
  }
  
  protected void showLockType(int flag){
    String txt = "";
    switch(flag){
    case PowerManager.PARTIAL_WAKE_LOCK:
      txt = "PARTIAL_WAKE_LOCK";
      break;
    case PowerManager.SCREEN_DIM_WAKE_LOCK:
      txt = "SCREEN_DIM_WAKE_LOCK";
      break;
    case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
      txt = "SCREEN_BRIGHT_WAKE_LOCK";
      break;
    case PowerManager.FULL_WAKE_LOCK:
      txt = "FULL_WAKE_LOCK";
      break;
    }
    typeTextView.setText(txt);
  }

}

AndroidManifest.xml にパーミッションを設定することもお忘れ無く。

<?xml version="1.0" encoding="utf-8"?>
<manifest 
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.keicode.android.test"
  android:versionCode="1"
  android:versionName="1.0">
  <uses-sdk android:minSdkVersion="8" />
  <uses-permission android:name="android.permission.WAKE_LOCK"/>
  <application 
    android:icon="@drawable/icon" 
    android:label="@string/app_name">
    <activity android:name=".WakeLock1"
      android:label="@string/app_name">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  </application>
</manifest>

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Android 開発入門