やる気駆動型エンジニアの備忘録

WPF(XAML+C#)の話題を中心に.NET/Android/CI やたまに趣味に関するブログです

(Android)スクリーンのON/OFFを検出する

Android端末でスクリーンのON/OFFを検出する方法についてメモ。

開発環境

  • 開発環境 : Android Studio 3.0
  • Compile Sdk Version : API26 Android8.0 (O)
  • Min Sdk Version : API23 Android6.0 (Mashmallow)

スクリーンのON/OFFを検出する

通常、スクリーンのON/OFFを検出するにはIntentFilter を設定したBroadcastReceiver を使用します。
今回はサンプルとしてWakeLockBroadcastReceiver というスクリーンON/OFFを検出するためのBroadcastReceiver クラスを作成し、スクリーンの状態が変わるとWakeLockListener というリスナーに通知します。
Intent のAction 文字列は、スクリーンの表示が"Intent.ACTION_SCREEN_ON"、スクリーンの非表示が"Intent.ACTION_SCREEN_OFF"となっています。
以下、コード例です。

<WakeLockBroadcastReceiver.java

package com.example.iyemon.wakelocksample;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public final class WakeLockBroadcastReceiver extends BroadcastReceiver {

    private WakeLockListener listener;

    public WakeLockBroadcastReceiver(WakeLockListener listener) {
        this.listener = listener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals(Intent.ACTION_SCREEN_ON)) {
            this.listener.onScreenOn();
        } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
            this.listener.onScreenOff();
        }
    }
}

<WakeLockListener.java

package com.example.iyemon.wakelocksample;

public interface WakeLockListener {
    
    void onScreenOn();

    void onScreenOff();
}


<MainActivity.java

package com.example.iyemon.wakelocksample;

import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.format.DateFormat;
import android.widget.TextView;

import java.util.Calendar;


public class MainActivity extends AppCompatActivity implements WakeLockListener {

    private WakeLockBroadcastReceiver wakeLockBroadcastReceiver;
    private TextView loggingTextView;

    private final String NewLine =  System.getProperty("line.separator");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.loggingTextView = (TextView)findViewById(R.id.loggingTextView);

        wakeLockBroadcastReceiver = new WakeLockBroadcastReceiver(this);
        registerReceiver(wakeLockBroadcastReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
        registerReceiver(wakeLockBroadcastReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
    }

    @Override
    public void onScreenOn() {
        String text = loggingTextView.getText().toString();
        loggingTextView.setText(text + NewLine + getNow() + " Screen On.");
    }

    @Override
    public void onScreenOff() {
        String text = loggingTextView.getText().toString();
        loggingTextView.setText(text + NewLine + getNow() + " Screen Off.");
    }

    private String getNow(){
        return DateFormat.format("yyyy/MM/dd HH:mm:ss", Calendar.getInstance()).toString();
    }
}

これを実行すると以下のようになります。
f:id:iyemon018:20171228011742p:plain

ハマったところ

BroadcastReceiver にIntentFilter を設定する場合、manifest ファイルにフィルター名を設定すればいいのですが、ACTION_SCREEN_ON/ACTION_SCREEN_OFF はContext#registerReceiver を使用する必要があります。
その理由については以下のページが参考になります。

qiita.com


今回使用したプロジェクトはこちら↓↓↓↓↓

github.com