画面を 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_LOCK | ON | OFF | OFF |
SCREEN_DIM_WAKE_LOCK | ON | 薄暗い(Dim) | OFF |
SCREEN_BRIGHT_WAKE_LOCK | ON | 明るい | Off |
FULL_WAKE_LOCK | ON | 明るい | 明るい |
スクリーン (ディスプレイ) はバッテリーを食う主な要因になるので、特別に薄暗くする (dim) というオプションもあります。
例えば私の現時点の端末 (DROID X Gingerbread) でバッテリーの利用状況を見ると、次のようにディスプレイにて主にバッテリーが消費されていることが分かります。
マーケティングリサーチ調査会社の MM 総研が 2011年5月に発表した資料によると、スマートフォンユーザーはバッテリーの持ちに不安を持っている人が多いという結果がでています。 バッテリーを食うアプリは嫌われる可能性は高いと思うので、スクリーンを ON にしておく必要があるかどうかはしっかり検討すべきです。
パワーマネージャの動作の確認プログラム
ウェイクロックの種類によって動作がどのように変わるか確認するためのプログラムを作りました。
"Acquire Lock" ボタンをクリックすると、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>