I've been trying to use FLAG_SHOW_WHEN_LOCKED and FLAG_DISMISS_KEYGUARD to display an activity each time someone turn the screen on. It works well most of the time but there is some case causing strange behaviour. This happens when the activity is already existing and I send it a intent after it has been moved back in the history stack, by using the Home button.
First, if I press the Home button when on my activity, then switch the screen off and on, the activity is expected to be displayed right away as it was. However what is displayed instead is the basic android lockscreen. My activity is behind.
Worst, sometime, if I touch the home screen, then turn the screen off and on, the home screen overlay (all appli logo and widgets) are displayed with my activity in the background!
The intent I am using each time the screen is turned off to laucn and recall the activity :
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
context.startActivity(intent);
So, it seems that when my activity is in the history stack, it sometimes does not correctly get recalled and bypass the android lockscreen. Is there something wrong with my intent?
Add more flags :
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
Wither via Intent.addFlags() or using getWindow().addFlags() from your activity. These flag will disable lockscreen when your activity is started
This will solve your query
Reference Answer : Here
You can integrate the Adenda SDK in your app to achieve what you're after. They let you display what you want on the lock screen relatively easily.
I'm affiliated with Adenda, for full disclosure
I have Activity1 which is a list screen of items. Each item can be viewed in a separate Activity2 which is displayed as a popup. Activity1 can be launched from the background and displayed even when the screen is locked. Activity1 may also choose to automatically display the contents of an item in the list screen by starting Activity2. We can bypass the lock screen because both activities have the WindowManagerFlags.DismissKeyguard enabled in the OnCreate method.
Before Android Lollipop everything worked as expected. But now the popup Activity2 is not visible unless the device is manually unlocked. If I change Activity2 to be a full screen Activity then everything seems to work (Except transitioning from one activity to another will briefly display the lock screen). Any ideas on how to fix this cleanly?
Also, I have only tried the Galaxy S6/S6 Edge devices which have this new Knox security feature on them.
Edit I have changed Activity2 to be a DialogFragment instead of an Activity. This worked for me best because the suggested answer used code that is deprecated or obsolete depending on the target sdk. Activity1 is using the following flags to bypass the lock screen when needed.
getWindow().addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED);
Since Activity2 is now just a DialogFragment, it uses the window flags of the parent Activity1. I also remove those flags on the "android.intent.action.SCREEN_OFF" action so that the activity bypasses the lock screen only when launched as a notification and not every time the activity is at the top of the stack. Permissions mentioned in the answer are required.
For sure this snippet should help You (works with Lollipop):
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "My Tag");
wl.acquire();
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
keyguardLock = keyguardManager.newKeyguardLock("TAG");
keyguardLock.disableKeyguard();
and when leaving Your activity (i.e. onStop(), onPause() and onDestroy()):
keyguardLock.reenableKeyguard();
Also, don't forget about permissions:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
I know an activity will get killed when the screen is locked. So wanna use service i guess. how to display an activity or ring a sound over the lock screen by pressing power button twice? I tried many questions related to it here but i don't find solution at all.
Here is the question I posted before.
https://stackoverflow.com/questions/28242776/toast-is-not-displayed-over-the-lock-screen
to show your Activity on lock screen you need to register reciever for off/on screen, then in onReceive() method start your activity on lock screen and keep screen on and ... .
see this Link . it should help you.
call this method at your Activity onCreate()
public void aboveLockScreen() {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
I have set up an AlarmManager to start up an activity. This activity also plays a sound, similar to an alarm app or an incoming call.
It works ok if the screen is on, even if the screen is locked.
If the screen is off, it doesn't work at all. I tried using the following as the first thing in onCreate
getWindow().setFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON, WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
If the screenlock is not enabled, this turns on the screen and I can see my activity closing. I can't hear the sound playing. If the screenlock is enabled, the screen won't turn on at all.
Sometimes I get the following, but not always:
07-18 23:52:13.685: E/OpenGLRenderer(14148): GL_INVALID_OPERATION
How can I make it start properly when the screen is off?
I got my answer partially from here.
lock = ((KeyguardManager) getSystemService(Activity.KEYGUARD_SERVICE)).newKeyguardLock(KEYGUARD_SERVICE);
powerManager = ((PowerManager) getSystemService(Context.POWER_SERVICE));
wake = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
lock.disableKeyguard();
wake.acquire();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
A while back I read that your app must be in full screen for the FLAG_TURN_SCREEN_ON to work.
"** One important note. Your activity must be full screen in order for the above flag combination to work. In my app I tried to use these flags with an activity which is not full screen (Dialog Theme) and it didn't work. After looking at the documentation I found that these flags require the window to be a full screen window." -Wake Android Device up
Quote from someone who posted their about a similar issue with FLAG_X.
Look into running a service, activity is going to be stopped when not in foreground.
Also look into the Activity lifecycle. http://developer.android.com/reference/android/app/Activity.html
The Context
Recently, I have been looking for reliable ways to control a secured Android Keyguard. Mainly to display a custom lock screen. I know that Google had stated custom lock screens are not officially supported by the platform and should expect things to break, however, with the existing APIs, I believe there must be ways to do this. I have done tons of research for about a week but still having problem here and there. What I have implemented, assuming a secured Keyguard is enabled, so far are,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED allows an activity(a window) to be displayed on screen on, putting the Keyguard behind, and all unsafe actions are prevented. Notification panel is disabled, finishing the activity will bring up the Keyguard. I implemented as following in my lock screen activity.
#Override
public void onAttachedToWindow() {
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
}
KeyguardManager, KeyguardManager.KeyguardLock are deprecated classes, but they still work all the way to Jelly Bean. To do this, I have a Service that handles two things, holding a static KeyguardManager and the related objects, and have it hold a BroadcastReceiver to receive Intent.ACTION_SCREEN_ON and Intent.ACTION_SCREEN_OFF. (all the objects are initialized properly)
For 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;
}
}
For 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();
}
}
For LockScreenActivity, when the user had input the correct passcode,
window.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
ScreenReceiverService.disableKeyguard();
finish();
The Problem
Things that works
ACTION_ON and ACTION_OFF are received reliably.
LockScreenActivity is shown before the Keyguard (without telephone state handling yet)
Notification cannot be pulled down, exiting the activity in any way would display the lockscreen.
Things that does not work
After I disable Keyguard and call finish(), my app exits and homescreen or the last activity before the screen went off is shown. However, whenever I press the Home Key, the Keyguard will flash into the screen, quickly dismissing itself immediately, and the normal Home Key function/event is not handled (will not return to homescreen after flashing). This is observed when I rapidly tapped the Home Key repeatedly.
I even looked into the Android source code to find out the Home Key handling, but it is never sent to third-party applications unless the window type is WindowManager.LayoutParams.TYPE_KEYGUARD or WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, which will throw SecurityException on 4.0+ even it worked on earlier platforms. And for the Keyguard, I have declared DISABLE_KEYGUARD permission use this shouldn't be the problem. My guess is the flag FLAG_SHOW_WHEN_LOCKED will tell the system to handle to Keyguard in some ways that would conflict with other disable calls. Since this flag is mostly used for Alarm/SMS type application, which is to show limited information to the user, then dismiss themselves and bring up the Keyguard. But in my case, having the user unlock my lock screen then unlock the system lockscreen simply defeats the purpose of my app.
So the question is why would the Keyguard flashes whenever I press Home after I disabled it? Is there any workaround/solution for this issue?
P.S. Thank you for reading such a long question. This is my first time asking a question here, if there is anything that I did wrong, please tell me (i.e. format, grammar, code convention, tags, etc.). Also I had no experience with any programming knowledge, I started with Android before I know what Java is. So I have not taken any proper course/training yet, this community is awesome and often help people like I even if they are simple questions, and of course watching Google I/O videos, reading blogs, read others' code help me a lot. So please tolerate any dumb mistakes/obvious bugs/stupid questions. I am only 16. ^_^"
I have used this with some success in both Gingerbread and ICS to open my activity (via a background service which is starting it). In the activity being started:
#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);
}
I had the same problem for the click of HOME button while unlocking the device. This can be solved by reseting the password to blank (ie "") :
DevicePolicyManager devicePolicyManager;
ComponentName demoDeviceAdmin;
devicePolicyManager.setPasswordQuality(demoDeviceAdmin,DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
devicePolicyManager.setPasswordMinimumLength(demoDeviceAdmin, 0);
devicePolicyManager.resetPassword("",DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
and then disabling the keygaurd :
this.keyGuardLock = ((KeyguardManager)getSystemService("keyguard")).newKeyguardLock("keyguard");
keyGuardLock.disableKeyguard();
Hope this solved your problem. \m/ keep coding!
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED allows an activity(a
window) to be displayed on screen on, putting the Keyguard behind
I tried to get this but my activity always preceded by the system lock screen. isOrderdBroadcast() says that ACTION_SCREEN_NO is an ordered broadcast.
I added flag to the activity :
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
in onAttachedView(). But still the system lock is getting the preference over my Custom screen lock activity.
How did you get your activity before the system lock screen?
EDIT
On a hindsight, I think my understanding of the lock screen concept was wrong. My broadcast receiver was getting the broadcast first. But what was showing before that was the system lock screen launched when SCREEN_OFF is received. Fixed that problem as of now.
But stumped by the ambiguity of home button behavior. This won't be a problem in post ICS devices as all hard buttons are discouraged.
In your LockScreenActivity, ending the validation code by finish(); kills the LockscreenActivity and thus the whole app. Instead of that, you could just launch back your main activity (or any other) like this :
startActivity(new Intent(LockScreenActivity.this, MainActivity.class));
If AOSP is in your control then you need to set the simple flag and keyguard() is gone for good.
Here is the details to do that, get into the file
"overlay/frameworks/base/packages/SystemUI/res/values/config.xml"
and search for "config_enableKeyguardService" then set the flag to false.
NO MORE keyGuard, pheww