Androidでパスコードロックを実現する


こんにちは@u_nation です。

Androidアプリを作っていてパスコードロックが欲しいと思うことは良くあると思います。

私は2.3.3をサポートしていた時代はBaseActivityでライフサイクルを監視して無理くりアプリのバックグラウンドを検知してゴニョゴニョしていました。。
もちろん、精度も悪く、ただの画面遷移なのにパスコードロック画面が出たりとかなり消耗しました。。
巷のアプリでも、ロック画面が出たり出なかったりするアプリをチラホラ見かけます。

ところが@heki1224様のこちらのスライドを見つけて、全て解決しました!誠にありがとうございます(>_<)

めちゃくちゃシンプルにアプリ全体のフォアグラウンド、バックグラウンドを検知できます。

public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks {
    private HashSet<Integer> activityStack = new HashSet<>();

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(this);
    }

    @Override
    public void onTerminate() {
        unregisterActivityLifecycleCallbacks(this);
        super.onTerminate();
    }

    @Override
    public void onActivityStarted(Activity activity) {
        boolean isForeground = activityStack.size() == 0;
        activityStack.add(activity.hashCode());
        if (isForeground) activity.startActivity(/*Activity for entering passcode*/);
    }

    @Override
    public void onActivityStopped(Activity activity) {
        activityStack.remove(activity.hashCode());
        boolean isBackground = activityStack.size() == 0;
    }
    ~~~~
}

これを応用して、パスコードロックを実現したサンプルを作りました。
ユーザーがパスコードロックを設定したら、バックグラウンドに入ったあとロック画面を表示し、解除されたら元の画面に戻るといういわゆるLINEのパスコードロックの完成度を目指しました。一年くらい放置したのを軽くリファクタリングしたため、バグってたらすみません。。

以上です。

追記

たまたま同僚の@magie_pooh氏の記事を見つけてさらにシンプルに画面回転を考慮した実装ができました。

簡単に説明するとComponentCallbacks2#onTrimMemoryをApplicationクラスで実装するとバックキーやホームボタン、マルチタスクボタンが押されてアプリがフォアグラウンドじゃなくなった事を検知できます。

  @Override public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
      // do something
    }
  }

サンプルの方も軽く更新したので、良ければぜひ(>_<)