web-dev-qa-db-ja.com

画面がロックされていることを検出する

許してください、これは私を狂気にさせてしまいました。

ここで、画面がロックされているかどうかを確認する方法についての記事をいくつか見ましたが、どれも機能していません。実際の画面がオフかどうかをすべて検出します(ロックされているかどうかではありません)。

音楽を再生するゲームがあります。ロックボタンを押すと、再生が続行されます。元々OnStopで音楽が停止していましたが、ロックされた後にアプリケーションが再起動するため、最終的に音楽が再び起動しました。

次に、KeyboardHidden | orientationをマニフェストに追加しました。これにより、アプリが再起動されなくなりますが、OnStopはもう呼び出されないようです。

PowerManagerを使用して、画面のオン/オフを確認しようとしましたが、機能しますが、役に立ちません。 (音楽をそこで止めることができますが、ロックボタンをもう一度押すとすぐに音楽が元に戻ります)

50
Ryan

より良い方法があります:

KeyguardManager myKM = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if( myKM.inKeyguardRestrictedInputMode()) {
 //it is locked
} else {
 //it is not locked
}

BroadcastRecievers、許可、または同様のものは必要ありません。

注:ユーザーが設定で画面ロックをnoneに設定している場合は機能しません-> security-> screenlock-> none

96

上記の解決策は正しいですが、出力を取得すると、画面がオフのときに出力がロックされ、画面がオンのときに出力がロックされますが、ロックを解除するためのパターンを入れた後にデバイスをロック解除すると出力がロック解除されませんだからここに私の解決策があります。

private void registerBroadcastReceiver() {

     final IntentFilter theFilter = new IntentFilter();
    /** System Defined Broadcast */
    theFilter.addAction(Intent.ACTION_SCREEN_ON);
    theFilter.addAction(Intent.ACTION_SCREEN_OFF);
    theFilter.addAction(Intent.ACTION_USER_PRESENT);

    BroadcastReceiver screenOnOffReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String strAction = intent.getAction();

            KeyguardManager myKM = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if(strAction.equals(Intent.ACTION_USER_PRESENT) || strAction.equals(Intent.ACTION_SCREEN_OFF) || strAction.equals(Intent.ACTION_SCREEN_ON)  )
                if( myKM.inKeyguardRestrictedInputMode())
                {
                    System.out.println("Screen off " + "LOCKED");
                } else
                {
                    System.out.println("Screen off " + "UNLOCKED");
                }

        }
    };

    getApplicationContext().registerReceiver(screenOnOffReceiver, theFilter);
}

その後、これは私に次のような出力を与えます

I/System.out:LOCKED 
when i off the mobile screen
I/System.out:LOCKED
when i on the mobile screen
I/System.out:UNLOCKED
when i unlock the mobile after pattern lock
9
Love

このリンクから: https://Gist.github.com/Jeevuz/4ec01688083670b1f3f92af64e44c112

/**
 * Returns true if the device is locked or screen turned off (in case password not set)
 */
public static boolean isDeviceLocked(Context context) {
    boolean isLocked = false;

    // First we check the locked state
    KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
    boolean inKeyguardRestrictedInputMode = keyguardManager.inKeyguardRestrictedInputMode();

    if (inKeyguardRestrictedInputMode) {
        isLocked = true;

    } else {
        // If password is not set in the settings, the inKeyguardRestrictedInputMode() returns false,
        // so we need to check if screen on for this case

        PowerManager powerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat_WATCH) {
            isLocked = !powerManager.isInteractive();
        } else {
            //noinspection deprecation
            isLocked = !powerManager.isScreenOn();
        }
    }

    Loggi.d(String.format("Now device is %s.", isLocked ? "locked" : "unlocked"));
    return isLocked;
}
7

私はこれをお勧めします:

private void registerBroadcastReceiver() {
    final IntentFilter theFilter = new IntentFilter();
    /** System Defined Broadcast */
    theFilter.addAction(Intent.ACTION_SCREEN_ON);
    theFilter.addAction(Intent.ACTION_SCREEN_OFF);

    BroadcastReceiver screenOnOffReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String strAction = intent.getAction();

            KeyguardManager myKM = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);

            if (strAction.equals(Intent.ACTION_SCREEN_OFF) || strAction.equals(Intent.ACTION_SCREEN_ON)) 
            {
                if( myKM.inKeyguardRestrictedInputMode()) 
                {
                    System.out.println("Screen off " + "LOCKED");
                } else 
                {
                    System.out.println("Screen off " + "UNLOCKED");
                }
            }
        }
    };

    getApplicationContext().registerReceiver(screenOnOffReceiver, theFilter);
}

@Shaul Rosenzweigからの上記の回答は、画面のオン/オフステータスを検出するために利用可能な他の投稿と組み合わされています。このソリューションをSamsung Galaxy S4 Miniでテストし、うまく機能しました。

2
class Android

Luv Kumarの答えは機能しますが、ユーザーが(ロックボタンを押して)画面を明示的にロックした場合にのみ登録されます。それに加えて、画面が消えたとき(画面のタイムアウトなど)にアプリにそれを知らせてほしい:

MyKM.inKeyguardRestrictedInputMode()に別のオプションを追加しました

if( myKM.inKeyguardRestrictedInputMode() || (strAction.equals(Intent.ACTION_SCREEN_OFF)) 
0
danjar