Disabled Keyguard Lock re-enables itself after clicking on a notification - android

In my application I disable the keyguard lock (i.e.Remove Lockscreen) using the code below and it works fine until I click on any notification in the notification bar. If I click on a notification the lock screen is automatically re-enabled. Any help is appreciated.
private void remove_lockscreen() {
final CheckBoxPreference lock = (CheckBoxPreference) findPreference("remove_lockscreen");
KeyguardManager km = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);
KeyguardLock kl = km.newKeyguardLock("keyguard_lock");
if (lock.isChecked()) {
prefEdit("remove_lockscreen", 1);
Toast.makeText(getBaseContext(), "Lockscreen will not be shown", Toast.LENGTH_SHORT).show();
kl.disableKeyguard();
}
else if (!lock.isChecked()) {
prefEdit("remove_lockscreen", 0);
Toast.makeText(getBaseContext(), "Lockscreen will be shown", Toast.LENGTH_SHORT).show();
kl.reenableKeyguard();
android.os.Process.killProcess(android.os.Process.myPid());
}
}

I've noticed the same issue for some time. It only occurs on Honeycomb (Android 3.0) and up. After a great deal of experimentation and hair-pulling, I seem to have found a solution that works for me. It's not clear exactly what's going on or why, but here's what I've figured out.
It seems that on Android 3.0+, after the keyguard is disabled, when a notification is pressed, the old KeyguardLock expires, but thankfully the ACTION_USER_PRESENT Broadcast is fired at that point, so we have a chance to correct the issue.
One point that's not at all obvious from the documentation is that it seems to be necessary to reenable the old KeyguardLock before getting a new one and disabling it again. Another "gotcha" I discovered is that disabling through the new KeyguardLock immediately after reenabling through the old one produces only intermittent success. I resolved this by waiting 300ms before disabling.
Here's a slightly simplified version of my code; it should be easy to adapt to your app:
private KeyguardLock kl;
private KeyguardManager km;
private final Handler mHandler = new Handler();
private final Runnable runDisableKeyguard = new Runnable() {
public void run() {
kl = km.newKeyguardLock(getPackageName());
kl.disableKeyguard();
}
};
private void setEnablednessOfKeyguard(boolean enabled) {
if (enabled) {
if (kl != null) {
unregisterReceiver(mUserPresentReceiver);
mHandler.removeCallbacks(runDisableKeyguard);
kl.reenableKeyguard();
kl = null;
}
} else {
if (km.inKeyguardRestrictedInputMode()) {
registerReceiver(mUserPresentReceiver, userPresent);
} else {
if (kl != null)
kl.reenableKeyguard();
else
registerReceiver(mUserPresentReceiver, userPresent);
mHandler.postDelayed(runDisableKeyguard, 300);
}
}
}
private final BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())){
if (sp_store.getBoolean(KEY_DISABLE_LOCKING, false))
setEnablednessOfKeyguard(false);
}
}
};

Related

Pause TimerTask when android device is locked and resume back when it is unlocked

I have set my timer as below.
Timer t;
TimerTask task;
t = new Timer();
t.schedule(task, 10000);
task = new TimerTask() {
#Override
public void run() {
finish();
try {
t.cancel();
t = null;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
};
Everything works fine now. My issue starts when android device get locked. Timer continues when device locked. I want to pause my timer when device get locks and resume back when it is unlocked.
Thank you, in advance.
Check this. It gives if your device is locked/unlocked
KeyguardManager kgMgr = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
boolean showing = kgMgr.inKeyguardRestrictedInputMode();
Use a countdown timer and onTick() of that check this condition. If true stop timer/save the count else continue.
you can try below code
#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 = powerManager.isScreenOn();
if (!isScreenOn) {
// The screen has been locked
// do stuff...
}
}

How to switch on screen on Android when a particular event occurs?

I'm trying to create an alarm app which is supposed to ring after a given period of time.
It works when the screen is switched on; I open the app and the alarm goes off after 5 second. Which is exactly what I want.
Now, I want my app to function the same way when the screen is switched off. So, if I open my app and then close the screen, I want the app to switch on the screen after 5 seconds and then ring the alarm.
I tried SCREEN_BRIGHT_WAKE_LOCK (did put in the required permissions) but it did not work. The alarm rang for like half a second and then then switched off. The screen did not turn on at all. Also, SCREEN_BRIGHT_WAKE_LOCK has been deprecated and the documentation suggests using FLAG_KEEP_SCREEN_ON which is useful only if the screen is already switched on and we wan to keep it that way. Not turn it on from off state.
What will I have to do to solve the above problem? Use a service? Also, the screen is locked with number lock.
Here is my code which works only when the screen is switched on:
public class AlarmReceiverActivity extends Activity {
private MediaPlayer mMediaPlayer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_alarm_receiver);
Button stopAlarm = (Button) findViewById(R.id.stopAlarm);
stopAlarm.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View arg0, MotionEvent arg1) {
mMediaPlayer.stop();
mMediaPlayer.release();
finish();
return false;
}
});
playSound(this, getAlarmUri());
}
private void playSound(Context context, Uri alert) {
mMediaPlayer = new MediaPlayer();
try {
mMediaPlayer.setDataSource(context, alert);
final AudioManager audioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
try {
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (IOException e) {
System.out.println("Oops");
}
}
} catch (IOException e1) {
System.out.println("OOPS");
}
}
//Get an alarm sound. Try for an alarm. If none set, try notification,
//Otherwise, ringtone.
private Uri getAlarmUri() {
Uri alert = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_ALARM);
if (alert == null) {
alert = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if (alert == null) {
alert = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
}
}
return alert;
}
}
I was dealing with this issue recently.
this is what worked for me:
public class YourActivity extends Activity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_view);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
...
}
helpful links:
Android Activity Not Showing When Screen is Woken Up and Lock Screen Not Disabling
http://weimenglee.blogspot.co.il/2013/04/android-tip-waking-up-screen-and.html
Android Galaxy S4 -- Activity that is visible over lock screen
also do NOT use dialog theme for the activity!!!

Android get Lock Timeout Programmatically

I am writing an app to show an activity over the lock screen when the phone is locked and screen off.
When the user leave the activity, the keyguard should be shown.
The common way to detect whether the phone is locked by by receiver and ACTION.SCREEN_OFF.
It works perfectly if the user press lock button the lock and screen off the phone.
However, after ICS, the phone may not be locked as soon as the phone is screen off.
So, how can I get the lock event or how can I get the value of Automatically lock as the picture below?
I know inKeyguardRestrictedInputMode() is a way to check if the phone is locked.
but it cannot report automatically when the phone is locked just like receiver.
The Screenshot from Setting in Android 4.1.2
you can get the timeout value by following code:
mResolver = this.getContentResolver();
long timeout = Settings.Secure.getInt(mResolver,
"lock_screen_lock_after_timeout",
0);
I solved by using thread to check if the device is locked.
The part of code in the service:
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.d("Receiver", "Screen ON");
} else {
new Thread(new mRunnable()).start();
}
}
};
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
Intent i = new Intent();
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setClass(getBaseContext(), activity.class);
startActivity(i);
break;
}
super.handleMessage(msg);
}
};
class mRunnable implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
if (isLocked()) {
mHandler.sendEmptyMessage(1);
Thread.currentThread().interrupt();
}
else {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
}
private boolean isLocked() {
mKeyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
return mKeyguardManager.inKeyguardRestrictedInputMode();
}
I listed it here for the others who are finding the answer. I just draft as a solution and I have not consider the performance of the code and program yet.

Unlock device, display a text, then lock again

For the need of my application, I need to display a message on the screen even if the lockscreen is enabled, then wait 3 seconds, than I have to lock again the phone as I don't want it to make unwanted phone calls in your pockets.
First part is easy:
if (PreferenceManager.getDefaultSharedPreferences(
getBaseContext()).getBoolean("wake", false)) {
KeyguardManager kgm = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
boolean isKeyguardUp = kgm.inKeyguardRestrictedInputMode();
WakeLocker.acquire(ProtoBenService.this);
Intent myIntent = new Intent(ProtoBenService.this,LockActivity.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (isKeyguardUp) {
ProtoBenService.this.startActivity(myIntent);
} else
Toast.makeText(ProtoBenService.this.getBaseContext(), intention, Toast.LENGTH_LONG).show();
WakeLocker.release();
}
With this class:
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context ctx) {
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, "CobeIm");
wakeLock.acquire();
}
public static void release() {
if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}
And the Activity:
public class LockActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
TextView tv = new TextView(this);
tv.setText("This is working!");
tv.setTextSize(45);
setContentView(tv);
Runnable mRunnable;
Handler mHandler = new Handler();
mRunnable = new Runnable() {
#Override
public void run() {
LockActivity.this.finish();
}
};
mHandler.postDelayed(mRunnable, 3 * 1000);
}
}
So, this is nice, the phone can display my text!
The only problem comes when I want to lock again the phone, it seems that locking the phone is protected by the system...
Programmatically turning off the screen and locking the phone
how to lock the android programatically
I think that my users won't understand the Device Admin and won't be able to activate it. Is there any workaround to lock the screen without the Device Admin stuff?
I used the following method for locking and unlocking phone.
initializing
KeyguardLock keyguard;
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
keyguard = km.newKeyguardLock("MyApp");
to unlock phone
keyguard.disableKeyguard();
to lock phone again
keyguard.reenableKeyguard();
to turn screen on
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
and dont forget to use the following permission
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
I am pretty sure that you have to use the Device Admin Features to lock the screen.
protected static void initiateDeviceLock(Context context) {
ComponentName componentName = new ComponentName(context, MyDeviceAdminReceiver.class);
DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
boolean active = dpm.isAdminActive(componentName);
Log.i(context.getClass().getSimpleName(), "Active (in initiateDeviceLock) = " + String.valueOf(active));
if (active) {
dpm.lockNow();
}
}
To help the user's setup the Device Admin features you can take them to the settings page:
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
ComponentName componentName = new ComponentName(TestActivity.this, MyDeviceAdminReceiver.class);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName);
startActivityForResult(intent, CODE);

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
}

Categories

Resources