@Azrael: ロックスクリーン(風)アプリを作る

ページ

2011年3月10日木曜日

ロックスクリーン(風)アプリを作る

ロックスクリーン自体をカスタマイズすることは(ざっとソースを見た感じ)出来なさそうですが、同じような動作をする画面(?)なら作ることが可能です。


まずはロック画面として表示するViewのレイアウトを作成
中央にTextView、その下にロック解除用のButtonがあるだけのレイアウト

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
    android:id="@+id/text_lock"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:text="lock screen??"
  />
  <Button
    android:id="@+id/button_unlock"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/text_lock"
    android:layout_centerHorizontal="true"
    android:text="unlock"
  />
</RelativeLayout>

上記のViewをWindowManager経由で表示する。
重要なのは
params.type = LayoutParams.TYPE_SYSTEM_ALERT;
の部分、このタイプが指定されたViewは通常のウィンドウよりも手前に表示されます。また、Activityではないため、Backキーで閉じたり、Homeキーで裏に回ったりしません。

ぱっと見で分かりやすいように
params.format = PixelFormat.TRANSLUCENT;
params.flags = LayoutParams.FLAG_BLUR_BEHIND;
を設定してあります。

private View mLockView = null;
private WindowManager mWindowManager = null;

public void lock( Context _c ){

  mLockView = LayoutInflater.from(_c).inflate(R.layout.lock, null);
  mLockView.findViewById(R.id.button_unlock).setOnClickListener(this);
  
  // android.view.WindowManager.LayoutParams
  LayoutParams params = new LayoutParams();
  params.width = LayoutParams.FILL_PARENT;
  params.height = LayoutParams.FILL_PARENT;
  params.type = LayoutParams.TYPE_SYSTEM_ALERT;
  params.format = PixelFormat.TRANSLUCENT;
  params.flags = LayoutParams.FLAG_BLUR_BEHIND;

  mWindowManager = (WindowManager)_c.getSystemService(Context.WINDOW_SERVICE);
  mWindowManager.addView(mLockView, params);

}

public void unlock(){

  mWindowManager.removeView(mLockView);
  
}

@Override
public void onClick(View v) {

  switch ( v.getId() ){
  case R.id.button_unlock:
    unlock();
  }
}

また上記のタイプのViewを使用するためには下記のパーミッションが必要です。
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

適当な画面から起動した状態


BackキーやHomeキーで閉じることは出来ません。
後はKeyguardManagerを使ってロックスクリーンを無効化し、ロック時(スクリーンオフ)や端末起動時に上記Viewを表示するようにすればそれっぽく動くようにはなります。

ロックスクリーンを解除して別のViewを表示しているため、Keyguard周りはほぼ全滅ですが、通常のロックスクリーンと異なる点は、
・アプリを強制終了(空きメモリ取得のための終了も含む)、アンインストールされた場合、画面が消え、通常のロックスクリーンが表示される。
・KeyguardManagerから見ると、ロックスクリーンは表示されて無いように見える。
・KeyguardManager.KeyguardLock#disableKeyguardで解除できない。
・LayoutParams.FLAG_SHOW_WHEN_LOCKEDやLayoutParams.FLAG_DISMISS_KEYGUARDが有効じゃない(アラーム系のアプリがロックスクリーンを解除して通知してこれない)

この後は拡張次第ですが、ShortcutやAppWidgetの配置も可能です。ロックスクリーンカスタマイズ系のアプリも、パーミッションや実際の動作を見た感じでは、同じ仕組みだと思われます。

下記にロック時や起動時にも表示する処理も含めたソースを置いておきます。参考にどうぞ。
android.hamachi.jp/demo/TestLock.zip

※あくまで参考にとどめてください。チェック処理、エラー処理が不十分です。アプリの更新後等、そのままでは正しく動かない部分があります。

.

0 件のコメント:

コメントを投稿