コンテキスト
最近、安全な Android Keyguard を制御する信頼できる方法を探していました。主にカスタムロック画面を表示します。カスタムロック画面はプラットフォームで公式にサポートされておらず、問題が発生することが予想されるとGoogleが述べていたことは知っていますが、既存のAPIを使用すると、これを行う方法があるに違いないと思います. 私は約 1 週間にわたって大量の調査を行ってきましたが、まだあちこちで問題が発生しています。安全なキーガードが有効になっていると仮定して、私が実装したことは、これまでのところ、
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED を使用すると、キーガードを背後に置き、アクティビティ (ウィンドウ) を画面に表示することができ、すべての危険なアクションが防止されます。通知パネルが無効になっています。アクティビティを終了すると、キーガードが表示されます。ロック画面のアクティビティで次のように実装しました。
@Override public void onAttachedToWindow() { window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); }
KeyguardManager
、KeyguardManager.KeyguardLock
非推奨のクラスですが、Jelly Bean まで引き続き機能します。これを行うためにService
、静的KeyguardManager
オブジェクトと関連オブジェクトを保持する 2 つの処理を行う がありBroadcastReceiver
、受信するIntent.ACTION_SCREEN_ON
とを保持しますIntent.ACTION_SCREEN_OFF
。(すべてのオブジェクトが適切に初期化されています)
為にScreenReceiver
public static synchronized void disableKeyguard() {
if ( isLocked ) {
if ( keyguardLock == null ) {
keyguardLock = keyguardManager.newKeyguardLock(LOG_TAG);
}
keyguardLock.disableKeyguard();
isLocked = false;
}
}
public static synchronized void reenableKeyguard() {
if ( !isLocked ) {
if ( keyguardLock == null ) {
keyguardLock = keyguardManager.newKeyguardLock(LOG_TAG);
}
keyguardLock.reenableKeyguard();
keyguardLock = null;
isLocked = true;
}
}
為にBroadcastReceiver
@Override
public void onReceive( Context context, Intent intent ) {
if ( intent.getAction().equals(Intent.ACTION_SCREEN_ON) ) {
Intent start = new Intent(context, LockScreen.class);
start.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(start);
} else if ( intent.getAction().equals(Intent.ACTION_SCREEN_OFF) ) {
ScreenReceiverService.reenableKeyguard();
}
}
の場合LockScreenActivity
、ユーザーが正しいパスコードを入力すると、
window.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
ScreenReceiverService.disableKeyguard();
finish();
問題
機能するもの
ACTION_ON
ACTION_OFF
確実に受信されます。- Keyguard の前に LockScreenActivity が表示されます (電話状態の処理はまだありません)。
- 通知をプルダウンすることはできません。何らかの方法でアクティビティを終了すると、ロック画面が表示されます。
うまくいかないこと
- 無効
Keyguard
にしてfinish()を呼び出すと、アプリが終了し、ホームスクリーンまたは画面がオフになる前の最後のアクティビティが表示されます。ただし、ホームキーを押すたびに、キーガードが画面に点滅し、すぐにすぐに消えてしまい、通常のホームキー機能/イベントは処理されません (点滅後にホーム画面に戻りません)。これは、ホーム キーをすばやく繰り返しタップしたときに観察されます。
- 無効
Android のソース コードを調べてホーム キーの処理を調べましたが、ウィンドウ タイプがWindowManager.LayoutParams.TYPE_KEYGUARD
またはWindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
でない限り、サードパーティ アプリケーションに送信されることはありません。以前のプラットフォームで動作していたとしても、4.0 以降では SecurityException がスローされます。についてはKeyguard
、許可の使用を宣言しましたが、DISABLE_KEYGUARD
これは問題ではありません。私の推測では、フラグは、他の無効化呼び出しと競合するいくつかの方法でFLAG_SHOW_WHEN_LOCKED
処理するようにシステムに指示します。Keyguard
このフラグは主にアラーム/SMS タイプのアプリケーションで使用されるため、限られた情報をユーザーに表示するため、自分自身を閉じてKeyguard
. しかし、私の場合、ユーザーにロック画面のロックを解除してからシステムのロック画面のロックを解除させると、アプリの目的が無効になります。
Keyguard
問題は、ホームを無効にした後にホームを押すたびに点滅するのはなぜですか? この問題の回避策/解決策はありますか?
PS長い質問を読んでくれてありがとう。ここで質問するのはこれが初めてです。何か間違っていることがあれば教えてください (形式、文法、コード規則、タグなど)。また、プログラミングの知識もまったくなかったので、Java が何かを知る前に Android から始めました。だから、私はまだ適切なコースやトレーニングを受けていません。このコミュニティは素晴らしいもので、私のような人々が簡単な質問であっても助けてくれることがよくあります。もちろん、Google I/O ビデオを見たり、ブログを読んだり、他の人のコードを読んだりすることは、私を大いに助けてくれます。 . したがって、愚かな間違い/明らかなバグ/愚かな質問は容認してください。私はまだ16歳です。^_^"