25

コンテキスト

最近、安全な Android Keyguard を制御する信頼できる方法を探していました。主にカスタムロック画面を表示します。カスタムロック画面はプラットフォームで公式にサポートされておらず、問題が発生することが予想されるとGoogleが述べていたことは知っていますが、既存のAPIを使用すると、これを行う方法があるに違いないと思います. 私は約 1 週間にわたって大量の調査を行ってきましたが、まだあちこちで問題が発生しています。安全なキーガードが有効になっていると仮定して、私が実装したことは、これまでのところ、

  • WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED を使用すると、キーガードを背後に置き、アクティビティ (ウィンドウ) を画面に表示することができ、すべての危険なアクションが防止されます。通知パネルが無効になっています。アクティビティを終了すると、キーガードが表示されます。ロック画面のアクティビティで次のように実装しました。

    @Override
    public void onAttachedToWindow() {
        window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    }
    
  • KeyguardManagerKeyguardManager.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_ONACTION_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歳です。^_^"

4

5 に答える 5

15

私はこれを使用して、Gingerbread と ICS の両方である程度の成功を収め、アクティビティを開始しました (それを開始するバックグラウンド サービスを介して)。開始されているアクティビティで:

@Override
public void onAttachedToWindow() {
    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | 
            WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | 
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | 
            WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
            WindowManager.LayoutParams.FLAG_FULLSCREEN | 
            WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | 
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | 
            WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
于 2013-03-12T17:05:42.480 に答える
1

デバイスのロックを解除しているときに HOME ボタンをクリックしても同じ問題が発生しました。これは、パスワードを空白 (つまり "") にリセットすることで解決できます。

DevicePolicyManager devicePolicyManager;
ComponentName demoDeviceAdmin;


devicePolicyManager.setPasswordQuality(demoDeviceAdmin,DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
devicePolicyManager.setPasswordMinimumLength(demoDeviceAdmin, 0);

devicePolicyManager.resetPassword("",DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);

次にキーガードを無効にします:

this.keyGuardLock = ((KeyguardManager)getSystemService("keyguard")).newKeyguardLock("keyguard");
keyGuardLock.disableKeyguard();

これで問題が解決したことを願っています。\m/ コーディングを続けてください!

于 2013-07-17T10:19:35.740 に答える
0

LockScreenActivity で検証コードを終了するfinish();と、LockscreenActivity が強制終了され、アプリ全体が強制終了されます。その代わりに、次のようにメイン アクティビティ (またはその他のアクティビティ) を起動することができます。

startActivity(new Intent(LockScreenActivity.this, MainActivity.class));
于 2013-03-28T16:24:38.787 に答える
0

AOSP があなたの管理下にある場合、単純なフラグを設定する必要があり、keyguard() は永久になくなります。これを行うための詳細は次のとおりです。ファイル「overlay/frameworks/base/packages/SystemUI/res/values/config.xml」に入り、「config_enableKeyguardService」を検索して、フラグを false に設定します。

キーガードはもう必要ない

于 2016-06-24T21:46:37.787 に答える
0

WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED を使用すると、キーガードを背後に置いて、アクティビティ (ウィンドウ) を画面に表示できます。

これを取得しようとしましたが、アクティビティの前に常にシステム ロック画面が表示されます。isOrderdBroadcast() は、 ACTION_SCREEN_NO が順序付きブロードキャストであることを示しています。

アクティビティにフラグを追加しました:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);

onAttachedView() で。しかし、システム ロックはカスタム画面ロック アクティビティよりも優先されます。

システム ロック画面が表示される前に、どのようにしてアクティビティを取得しましたか?

編集 後から考えると、ロック画面の概念に対する私の理解は間違っていたと思います。私の放送受信機は、最初に放送を受信して​​いました。しかし、その前に表示されていたのは、SCREEN_OFF が受信されたときに起動されるシステム ロック画面でした。今のところその問題を修正しました。

しかし、ホームボタンの動作のあいまいさに困惑しました。これは、すべてのハード ボタンが推奨されないため、ポスト ICS デバイスでは問題になりません。

于 2012-08-31T05:22:59.543 に答える