Android detect phone lock event - android

I want to be able to detect the phone lock event. When my app is running, if I press the red button (call end button/power button), the phone gets locked and the screen goes blank. I want to be able to detect this event, is it possible?

Alternatively you could do this:
#Override
protected void onPause()
{
super.onPause();
// If the screen is off then the device has been locked
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
boolean isScreenOn;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
isScreenOn = powerManager.isInteractive();
} else {
isScreenOn = powerManager.isScreenOn();
}
if (!isScreenOn) {
// The screen has been locked
// do stuff...
}
}

Have a Broadcast Receiver
android.intent.action.SCREEN_ON
and
android.intent.action.SCREEN_OFF
Related: Read CommonsWare's Answer Here.

Register a broadcast with IntentFilter filter.addAction(Intent.ACTION_USER_PRESENT)
works pretty well even screen is turned on/off

Koltin format of Robert's solution.
override fun onPause() {
super.onPause()
// If the screen is off then the device has been locked
val powerManager = getSystemService(POWER_SERVICE) as PowerManager
val isScreenOn: Boolean = powerManager.isInteractive
if (!isScreenOn) {
// The screen has been locked
// do stuff...
}
}
I am assuming Kitkat version is quite old already.

Related

To detect the screenlock even when the app is sleeping

I have an android application that needs to be locked (redirect to the login page) whenever the user presses the lock button. The user can lock the phone while on my application or while on other applications/home screen. In both of these scenarios, I need my application to be locked.
This is working fine in case the phone is locked from an application :
#Override
protected void onStop() {
super.onStop();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isInteractive();
if (!isScreenOn) {
LogUtils.logD(TAG, "Screen is off, Locking the application");
// Lock the application code
}
}
But I am not able to figure out the second scenario when the user has moved away from the application and then locks it. I do not want to start a service or any background thread for this purpose.
Try to add else and return at the end of the code so the activity will still awake in background process
#Override
protected void onStop() {
super.onStop();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isInteractive();
if (!isScreenOn) {
LogUtils.logD(TAG, "Screen is off, Locking the application");
// Lock the application code
} else{
return true;
}

Check whether onPause state of activity is called due to screen lock

If my app is running and I press lock screen button, it will put the app in background.What is the method to check whether onPause() is called by screen lock?.Thanks in advance.
All you have to do is check if the screen is on or not.
#Override
protected void onPause() {
super.onPause();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean screenOn;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
screenOn = pm.isInteractive();
} else {
screenOn = pm.isScreenOn();
}
if (screenOn) {
// Screen is still on, so do your thing here
}
}
You Can Simply Know It By Using This Method
#Override
public void onPause() {
super.onPause(); // Always call the superclass method first
System.out.println("On Pause called");
}
For Keeping The Device Awake while lock screen. Documentation.
Ok in your case you would need Wake_Lock
To use a wake lock, the first step is to add the WAKE_LOCK permission to your application's manifest file:
<uses-permission android:name="android.permission.WAKE_LOCK" />
If your app includes a broadcast receiver that uses a service to do some work, you can manage your wake lock through a WakefulBroadcastReceiver, as described in Using a WakefulBroadcastReceiver. This is the preferred approach. If your app doesn't follow that pattern, here is how you set a wake lock directly:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
Wakelock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyWakelockTag");
wakeLock.acquire();
To release the wake lock, call wakelock.release(). This releases your claim to the CPU. It's important to release a wake lock as soon as your app is finished using it to avoid draining the battery.
DO this after setting powermanager.
boolean screenOn;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
screenOn = powerManager.isInteractive();
} else {
screenOn = powerManager.isScreenOn();
}
if (screenOn) {
// Screen is still on, so do your thing here
}
You just want to know when onPause is called? You could override the super function and add logging to the function:
#Override
public void onPause() {
super.onPause();
System.out.println("On Pause called");
}

how to check screen on/off status in onStop()?

as mentioned here, when the screen goes off, the onStop() of current Activity will be called. I need to check the screen on/off status when the onStop() of my Activity is called. so I have registered a BroadcastReceiver for these actions(ACTION_SCREEN_ON AND ACTION_SCREEN_OFF) to record the current on/off status(and they work properly, I have logged!).
but when I turn off the screen and check the on/off status in the onStop , it says the screen is on. why? I think the receiver must receive the ACTION_SCREEN_OFF before onStop is called so what's wrong?
You can try to use PowerManager system service for this purpose, here is example and official documentation (note this method was added in API level 7):
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isScreenOn();
EDIT:
isScreenOn() method is deprecated API level 21. You should use isInteractive instead:
boolean isScreenOn = pm.isInteractive();
http://developer.android.com/reference/android/os/PowerManager.html#isInteractive()
As mentioned in this answer to a similar question.
In API 21 and above we can use the DisplayManager to determine the state of the display. This has the advantage of supporting the querying of multiple displays:
DisplayManager dm = (DisplayManager)
context.getSystemService(Context.DISPLAY_SERVICE);
for (Display display : dm.getDisplays()) {
if (display.getState() != Display.STATE_OFF) {
return true;
}
}
return false;
Depending upon your circumstance it might be more appropriate to query the display that a particular view is being displayed on:
myView.getDisplay().getState() != Display.STATE_OFF
PowerManager pm = (PowerManager) mMainActivity.getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = Utils.hasLollipop() ? pm.isInteractive() : pm.isScreenOn();
If you want to manually check the screen state instead of the broadcast receiver, you should consider some situations.
Screen may be active with Doze mode (Samsung's Always-on-Display feature)
VR mode may be active
In order to check that the screen is not turned off and the user is actively using the phone, the screen state must not be Display.STATE_OFF and not in the keyguardManager.isKeyguardLocked() state.
public static boolean isDeviceActive(
#NonNull DisplayManager displayManager,
#NonNull KeyguardManager keyguardManager
) {
for (Display display : displayManager.getDisplays()) {
if (display.getState() != Display.STATE_OFF) {
return !keyguardManager.isKeyguardLocked();
}
}
return false;
}

Detecting when screen is locked

I've seen a couple of posts on here on how to check if the screen is locked, but none of it has been working for me. It all detects if the actual screen is off or not (not if it's locked).
I have a game in which music plays. When the lock button is pressed, it continues to play. I originally had the music stopping in OnStop, but the application would restart after getting locked, so the music would eventually start up again.
Then, I added KeyboardHidden|orientation to the manifest. This makes it so it doesn't restart the app, but OnStop doesn't seem to get called anymore.
I've tried using PowerManager to see if the screen is on/off, which works, but doesn't help. (I can get the music to stop there, but as soon as you hit the lock button again, the music starts right back up)
There is a better way:
KeyguardManager myKM = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if( myKM.inKeyguardRestrictedInputMode()) {
//it is locked
} else {
//it is not locked
}
No need for broadcastRecievers, permissions or anything similar.
Note: It doesn't work when user has set his/her screen lock to none
in settings-->security-->screenlock-->none
This link might be helpful to others for two things at one place.
Check if the Device is Locked Or Not:
KeyguardManager myKM = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
boolean isPhoneLocked = myKM.inKeyguardRestrictedInputMode();
(Note: above method doesn't work if screenlock is set to none in settings-->security-->screenlock.)
Check If Device is Awake or in Sleep Mode:(for Sdk Version > L Preview < Sdk Version)
PowerManager powerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
isScreenAwake = (Build.VERSION.SDK_INT < 20? powerManager.isScreenOn():powerManager.isInteractive());
The Above solution is correct but when i get output it gave me an output locked when screen off and and locked when screen on but doesn't gave unlock output when i unlocked device after putting pattern for unlock.
So Here is my solution.
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);
}
after that this will give me output like
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
Taken from this link: 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;
}
You can use KeyguardManager class to check if the screen is locked or not. Below is the code snippet written in Kotlin.
val keyguardManager: KeyguardManager = context?.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
if (keyguardManager.isDeviceLocked) {
// device locked logic goes here
} else {
// device unlocked case
}
I would suggest this:
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);
}
The above answer from #Shaul Rosenzweig combined with the other post available to detect screen on and off status. I tested this solution on Samsung Galaxy S4 Mini and worked well for me.
The Below code shows if the screen is locked or not.
private void checkPhoneScreenLocked(){
KeyguardManager myKM = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
if( myKM.isKeyguardLocked()) {
System.out.println("Phone is locked");
} else {
System.out.println("Phone is not locked");
}
}
DrawBack:-We can check the phone is locked or not.only if the user has selected the any security patters other than none.
Luv Kumar's answer works but it only registers when user explicitly locks the screen (by pressing the lock button). Besides that, I want my app to tell when screen goes off (e.g. screen timeout) just did that:
Just added another option to myKM.inKeyguardRestrictedInputMode()
if( myKM.inKeyguardRestrictedInputMode() || (strAction.equals(Intent.ACTION_SCREEN_OFF))
Use KeyguardManager.isDeviceLocked to detect if the device is currently locked and requires a PIN, pattern or password to unlock.
Ref: https://developer.android.com/reference/android/app/KeyguardManager#isDeviceLocked()
fun isDeviceLocked(context: Context): Boolean {
return (context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager).isDeviceLocked
}

Programmatically check if PIN lock is active in Android

Here's the thing - I'm doing a security app that needs to be able to check if the PIN code is set or not. The official API returns the same value regardless of the PIN state, and I've been experimenting with ITelephony, but can't seem to get it to work. Any help, please?
Workaround!
#override
protected void onPause() {
super.onPause();
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
boolean isScreenOn = powerManager.isScreenOn();
if (!isScreenOn) {
// do stuff...
}
}

Categories

Resources