2011年1月15日土曜日

ロック画面より上にActivityを表示したい!

マーケットにあるステキなメディアプレーヤーさん方
使っていて疑問に思ったのが、どうやってロック画面より上に表示してるんだ?

と思ってググったら見つかったので試してみます。

明日の鍵 「スクリーンロックを解除する方法」
superdry memorandom :-D [memo]Androidアプリ側からスクリーンロックを解除し、画面表示する方法

どうやら、KeyguardManager.KeyguardLockのdisableKeyguard()で、ロック解除。
reenableKeyguard()で再度有効化、のようです。

何も考えず上記ブログで作られていた クラスを丸パクリし、ResumeでgetUnlock/PauseでreleaseUnlockを呼びました。
そして

  • アプリ起動
  • 電源ボタンを押下
  • 結果として、確かにロック画面より上にActivityが表示される
となりました。


が、所詮丸パクリのため、一連の動作一回目の電源ボタン押下後に、 何もしていないのに液晶が明るくなって、Activityが表示されます。

二回目以降は問題ないのですが…

どうやら、起動直後のOnResume時にWakelock.acquire(); を読んでいるのが駄目なようです。
ログを見るかぎりは

  • 起動直後のOnResumeでacquire()(※)
  • 電源ボタン押下時のOnPauseで、Wakelock.release()
と呼ばれているのにも関わらず、その後
  • なぜかOnResumeが走る
なんでかは分からないけど※の処理がスタックされていて、OnPauseの直後に呼ばれているのだろう…

なので借り物のクラスをキーロック時のみacquireを呼ぶように修正
これでとりあえずはOKでした。

 public void getUnlock() {

  // acquire wake lock
  _log( "getUnlock:called");

  PowerManager pm = (PowerManager) mContext.getSystemService( Context.POWER_SERVICE);
  mWakelock = pm.newWakeLock( PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "ScreenLockManager");
  // 今回の呼び出し環境だと、ここにあると困る
  // mWakelock.acquire();

  // unlock screen
  KeyguardManager km = (KeyguardManager) mContext.getSystemService( Context.KEYGUARD_SERVICE);
  mKeyguardLock = km.newKeyguardLock( "ScreenLockManager");
  if( km.inKeyguardRestrictedInputMode()){
   // ここに移動
   mWakelock.acquire();
   mKeyguardLock.disableKeyguard();
   isScreenLock = true;
   _log( "getUnlock: disableKeyguard");
  }else{
   isScreenLock = false;
  }
 }

と、ここまでやってみて一つの疑問が。

PowerManagerでWakeLockを制御する必要は本当にあるのか??

ってことです。

上記以外にも、画面を明るくするために…として呼んでいるソースを見かけるのですが、
そもそも

  • スリープ(というのかな?画面暗転)状態で電源ボタン押下すれば、そもそも明るくなる
わけで…

というわけでPowerManager.WakeLock関連全コメントアウトして試してみました。

結果として、何の問題もありませんでした…
個人的には、何故か暗転したままってのを期待したのですが、普通に動いてしまった…

package com.omokageru.ak.screenunlocktest;

import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;

public class ScreenUnlockTest extends Activity {

 private ScreenLockManager slm = null;


 /** Called when the activity is first created. */
 @Override
 public void onCreate( Bundle savedInstanceState) {

  super.onCreate( savedInstanceState);
  setContentView( R.layout.main);
  _log( "onCreate");
  slm = new ScreenLockManager( this);
 }


 @Override
 protected void onDestroy() {

  // TODO 自動生成されたメソッド・スタブ
  super.onDestroy();
  _log( "onDestroy");
 }


 @Override
 protected void onPause() {

  // TODO 自動生成されたメソッド・スタブ
  super.onPause();
  _log( "onPause");
  slm.releaseUnlock();
 }


 @Override
 protected void onResume() {

  // TODO 自動生成されたメソッド・スタブ
  super.onResume();
  _log( "onResume");
  slm.getUnlock();
 }


 private void _log( String str) {

  Log.d( "ScreenUnlockTest Activity", str);
 }
}


/**
 * 以下パクリもの
 */
class ScreenLockManager {

 private Context       mContext;
 private KeyguardManager.KeyguardLock mKeyguardLock;
 private boolean       isScreenLock;


 public ScreenLockManager( Context context) {

  mContext = context;
 }


 public void getUnlock() {

  _log( "getUnlock:called");

  // unlock screen
  KeyguardManager km = (KeyguardManager) mContext.getSystemService( Context.KEYGUARD_SERVICE);
  mKeyguardLock = km.newKeyguardLock( "ScreenLockManager");
  if( km.inKeyguardRestrictedInputMode()){
   // ここに移動
   mKeyguardLock.disableKeyguard();
   isScreenLock = true;
   _log( "getUnlock: disableKeyguard");
  }else{
   isScreenLock = false;
  }
 }


 public void releaseUnlock() {

  _log( "releaseUnlock:called");
  // release screen
  if( isScreenLock){
   mKeyguardLock.reenableKeyguard();
   isScreenLock = false;
   _log( "releaseUnlock: reenableKeyguard");
  }
 }


 private void _log( String str) {

  Log.d( "ScreenLockManager", str);
 }

}

う~ん、ロック解除に関してPowerManagerの利用はどんな意味があるのだろう?

もうちょっと(覚えていたら)調べてみようかな

0 件のコメント:

コメントを投稿