Dissable_keyGuard flag not working - android

I'm trying to disable screen lock. I want the screen to go off after timeout, but to go on again with my app when touched.
Since keywardlock is deprecated, I tried the following in onCreate():
final Window win = getWindow();
win.setFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
Just in case, I added the following in the manifest (is this needed??):
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.FLAG_SHOW_WHEN_LOCKED" />
Still, after my usual timeout, the screen is locked...
What am I doing wrong??
Thanks!

SetFlags takes the flags and a mask you are not using it that way. The easyest thing is to use the helper method addFlags I am using the following code.
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);

Related

Android O - FLAG_SHOW_WHEN_LOCKED is deprecated

I'm targetting my application to Android O.
In my application I have a job service that shows a window over all other applications, so when it triggered it needs to show this window even when the screen is turned off & unlocked and turn it on.
I've achieved this behaviour in preior Android versions, but in Android O it doesn't work as I expected.
I've read that I need to use the flag TYPE_APPLICATION_OVERLAY and added also the permission <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>in the manifest file.
So it works fine when the screen is on, but when the screen is off I've noticed that it doesn't turn the screen on, and when I turned the screen I saw that the window was created on top of other applications.
So my question is since the flags FLAG_TURN_SCREEN_ON and FLAG_SHOW_WHEN_LOCKED are deprecated in Android API 27, what are the alternatives way of doing that?
this is my current code:
private void showView()
{
if (!wakeLockAcquired)
{
wakeLock.acquire();
wakeLockAquired = true;
}
windowManager = (WindowManager)context.getSystemService(WINDOW_SERVICE);
final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON ,
PixelFormat.RGBA_8888);
RelativeLayout layout = buildView();
windowManager.addView(layout, layoutParams);
windowManager.updateViewLayout(layout, layoutParams);
}
Notes:
buildView is a function that returns a relativeLayout, in this function I'm adding the content dynamically (TextView, ImageView, etc...).
wakeLockAcquired is a boolean member, and it sets to false when the view is destroyed.
KeyguardManager turn on screen if attr turnScreenOn is true, so order of methods and call requestDismissKeyguard is necessary. I use this code for activity, hope it'll help:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true)
setTurnScreenOn(true)
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
keyguardManager.requestDismissKeyguard(this, null)
} else {
this.window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
}
}
OK so I've managed to solved it with some workaround and the help from the answer of #Umair.
As I said I'm displaying a view that was created in a background service using the WindowManager and with the code I've added to my question above, the view is displayed above all the other applications but not turning the screen on when Android version is Android 8.
The methods that now replaceing the Flags: FLAG_SHOW_WHEN_LOCKED FLAG_TURN_SCREEN_ON are visible to activities and not for services or for the WindowManager, and casting the context to Activity is not a good idea and will not help you :)
So What I did for now (temporary solution) is to create a transparent activity and when I'm calling to showView() method from my background service, I'm also starting the transparent activity.
In the activity - inside the onCreate method, I'm calling to the methods:
setShowWhenLocked(true)
setTurnScreenOn(true)
and when the view is destroyed, the activity will also get destroyed with the help of broadcast receiver :)
so the screen is now turned on and the view is above all the other applications.
I know that you can tell me that I can move my code that inside my service into the new activity.
The reason I did it in that way:
I'm using speech recognizer.. and when I coded it in the activity, things didn't work. I mean when the screen is locked with pattern, the activity goes to pause state and I can't get the results. so the pattern dismissed my activity..
So I decided to create a view using the window manager and it worked fine until now - when Google (Android team) decided to deprecate these flags.
So this is my solution for now.. and I hope that someone will find a better solution for this problem.
So according to android documentation these methods were deprecated so you need to use showWhenLocked or setShowWhenLocked(boolean) instead.
FLAG_TURN_SCREEN_ON
int FLAG_TURN_SCREEN_ON
This constant was deprecated in API level 27.
Use turnScreenOn or setTurnScreenOn(boolean) instead to prevent an
unintentional double life-cycle event.
Window flag: when set as a window is being added or made visible, once
the window has been shown then the system will poke the power
manager's user activity (as if the user had woken up the device) to
turn the screen on.
And FLAG_SHOW_WHEN_LOCKED
int FLAG_SHOW_WHEN_LOCKED
This constant was deprecated in API level 27.
Use showWhenLocked or setShowWhenLocked(boolean) instead to prevent an unintentional double life-cycle event.
Window flag: special flag to let windows be shown when the screen is
locked. This will let application windows take precedence over key
guard or any other lock screens. Can be used with FLAG_KEEP_SCREEN_ON
to turn screen on and display windows directly before showing the key
guard window. Can be used with FLAG_DISMISS_KEYGUARD to automatically
fully dismisss non-secure keyguards. This flag only applies to the
top-most full-screen window.
So according to documentation the reason to deprecate these methods was to avoid an unintentional double life-cycle event. You can read more about them here.
https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html
Do you experience that
setShowWhenLocked(true)
setTurnScreenOn(true)
do not turn screen on any longer in Android 9? Or is it just my case?
Up to date Kotlin code with if-else for handling deprecation:
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
keyguardManager.requestDismissKeyguard(this, null)
setShowWhenLocked(true)
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD)
}
More explanation can be found here here.
as Dmitry Ognyov posted above - besides these:
setShowWhenLocked(true); setTurnScreenOn(true);
you need to dismiss the keyguard too keyguardManager.requestDismissKeyguard(...

Wake up device programmatically

I want to wake up and unlock a device. Then, I'd like show an activity when the user has new message from Firebase.
I wrote this on onResume() method:
window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
This works for devices with API > 19. The problem is that in KitKat, it either does nothing or it wakes up the screen but doesn't unlock the device.
Also I set the right permissions in the AndroidManifest.xml:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
Also in MyFirebaseMessagingService.class, I'm starting an activity with FLAG_ACTIVITY_NEW_TASK as flag.
Does anyone know what am I missing?
Thanks for the help.
Ok i found it. I just add that piece of code and it worked
KeyguardManager manager = (KeyguardManager) this.getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock lock = manager.newKeyguardLock("abc");
lock.disableKeyguard();

Start an activity even if we lock the device

I'm developing an alarm aplication, so when the alarm goes on it start an activity with an off button
It's very simple, but my question, is there a way to start the activity even if the device is locked???
You need to use the WakeLock and also disable your keyboard for the respective Activity. They can be achieved by help of WindowManager.LayoutParams class.
WakeLock allows your app to wake up the screen i.e. turn the display on while your Activity or your complete app is running in the foreground. To learn more about implementing the WakeLock go through the following link:
http://developer.android.com/training/scheduling/wakelock.html
To disable your keyguard you need to use WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED and/or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD flags for the respective Activity.
To know more about them, go to the following links:
http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_DISMISS_KEYGUARD
http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_SHOW_WHEN_LOCKED
You will also need to use the following permissions in the Manifest file of your Android Project:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
You need the following permission in AndroidManifest.xml file:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
Check this link

Starting activity from service on lock screen turns on the screen but does not show the activity itself

I'm trying to start an activity from a service I had already acquired the lock for as follows:
Intent i = new Intent(context, MyActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
startActivity(i);
The activity manifest is declared as follows:
<activity
android:name=".MyActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard|navigation"
android:excludeFromRecents="true"
android:launchMode="singleInstance"
android:screenOrientation="nosensor"
android:showOnLockScreen="true"
android:taskAffinity=""
android:theme="#style/MyTheme" />
And finally, on onCreate() or on onAttachedToWindow() (I tried on both), I add the following flags:
final Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
The problem is that the first time I call startActivity() from my service, the screen turns on but the activity itself does not show up. It shows the lock screen instead. Every subsequent call of startActivity() works properly but I can't find a reason for this odd behavior.
I tried already suggestions to get a full wakelock instead of partial, change the flags and values in the manifest according to the following SO answers:
Android Activity Not Showing When Screen is Woken Up and Lock Screen Not Disabling
how to unlock the screen when BroadcastReceiver is called?
Programmatically turn screen on in android
Android Galaxy S4 -- Activity that is visible over lock screen
Note that my theme is not a dialog but a fullscreen activity.
Any other ideas?
I'm facing the same problem, after a lot of searching here and google, found this which unlocked the screen and popped my activity but it only works for me when the app is running (foreground/background).
import android.view.Window;
import android.view.WindowManager.LayoutParams;
Window window = this.getWindow();
window.addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED);
window.addFlags(LayoutParams.FLAG_TURN_SCREEN_ON);
i'm trying to start an activty when app is closed... (using broadcast receiver)
in the docs (for example here) and most of the answers on SO the flags are added this way:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
but when i tried the way it is like in the example it unlocked the screen instead of just turning on the screen.
hope this help . it still didn't solve my problem completely.
EDIT:
found this post which solved my problem.
there is a comment there on NOT using a dialog theme which solved it for me
Step 1: Add below code in your activity before
setContentView(R.layout.activity_about_us);
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);
Step 2: Lock your mobile than you will see activity in which you have added this code.
You can implement this if you want to open particular screen by notification occurrence like skype call.
Since my application already includes a Service, this is what I do: if the screen is locked, I register a broadcast receiver (a bit simpler than this one, since it reacts only on unlocking) that starts the Activity as soon as the screen gets unlocked.

How to create always-top fullscreen overlay activity in Android

I'd like to be able to create an Activity that is always at the front of display of Android.
It should receive no input, just pass it down to whatever application is next below it. Something like a HUD.
I was able to research that I need to set underlying window type to TYPE_SYSTEM_ALERT but it looks like Android is ignoring my code - no exception thrown even if I delete android.permission.SYSTEM_ALERT_WINDOW permission from manifest. (it is required to use this window type). When I tried to use ALERT type on dialog, it worked OK, but I cannot make dialog into full screen transparent entity.
Here is my code, maybe there is something simple missing.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
getWindow().setBackgroundDrawableResource(android.R.color.transparent);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
setContentView(R.layout.main);
}
Translucent setting has to be enabled externally in xml manifest, otherwise it also didn't work.
<item name="android:windowIsTranslucent">true</item>
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
WindowManager wm = (WindowManager) getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);
ViewGroup mTopView = (ViewGroup) App.inflater.inflate(R.layout.main, null);
getWindow().setAttributes(params);
wm.addView(mTopView, params);
I found that the accepted answer (by tmouse) did not quite work for me. Maybe it worked for an older API level? I'm using API level 24.
That particular answer had recommended:
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT
);
There is a problem with this. The constructors that exist for WindowManager.LayoutParams are as follows:
So the WindowManager.LayoutParams.FLAG_FULLSCREEN flag gets used as an explicit value for int w and int h. This is no good! Your view's dimensions get set to 1024*1024 — so it does not fill the screen. And even if you explicitly set the layout's width and height to match the device's dimensions: they will not update when the screen orientation changes. We need a different approach…
I found that the correct construction for a full-screen overlay is like so:
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, // TYPE_SYSTEM_ALERT is denied in apiLevel >=19
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT
);
This means we no longer explicitly specify a width and height. The layout relies entirely on our flags instead.
Yes, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN is a required flag still; it is necessary if you want to draw over decorations such as the status bar.
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY should be used instead of TYPE_SYSTEM_ALERT in API level >=19. This is a note I wrote a while ago, sadly I've been unable to find citation to corroborate why I thought that, so take that with a pinch of salt.
Bonus notes (if you're reading this, you're probably trying to make a full-screen overlay):
Your manifest will need these permissions (explanation here):
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
My understanding is that SYSTEM_ALERT_WINDOW is the actual permission required, but that ACTION_MANAGE_OVERLAY_PERMISSION is needed also: it lets you request at runtime that the user grant the SYSTEM_ALERT_WINDOW privilege.
I provide here the source code to my working API level 24 app that creates a full-screen overlay.
Check out this
mention it in your AndroidManifest.xml file
<activity android:name=".MyActivity" android:theme="#android:style/Theme.NoTitleBar.Fullscreen" />
if you want to make your Activity full screen and transparent also
check out this
<activity android:name=".MyActivity" android:theme="#android:style/Theme.Translucent.NoTitleBar.Fullscreen" />

Categories

Resources