I've noticed very interesting behavior of Android that I cannot explain. I'm using the following code to wake up the phone and disable keyguard:
PowerManager.WakeLock mFullWakelock = mPowerManager.newWakeLock(
(PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP),
LOCK_TAG
);
mFullWakelock.acquire();
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock keyguardLock = keyguardManager.newKeyguardLock(LOCK_TAG);
keyguardLock.disableKeyguard();
Imagine there is cycle of wake (programmatically)->disable keyguard (programmatically)->press power button (manually)->wake->disable keyguard. The cycle works great until I manually press Home button while the phone's keyguard is disabled. After that, phone does wake up but keyguard is no longer disabled programmatically. I'd appreciate any ideas!
The problem is that a keylock seems to expire whenever the user presses home button or opens a notification. So whenever this happens, you have to create a new keylock.
I used this solution and it worked great:
https://stackoverflow.com/a/14519861/4098821
I had the same problem and i solved it using reflection and making my application as system signed app.
Here's the code:
try{
Class lockPatternUtilsCls = Class.forName("com.android.internal.widget.LockPatternUtils");
Constructor lockPatternUtilsConstructor =
lockPatternUtilsCls.getConstructor(new Class[]{Context.class});
lockPatternUtilsConstructor.setAccessible(true);
Object lockPatternUtils = lockPatternUtilsConstructor.newInstance(ChangeDeviceLockMode.this);
Method clearLockMethod = lockPatternUtils.getClass().getMethod("clearLock", boolean.class);
clearLockMethod.setAccessible(true);
Method setLockScreenDisabledMethod = lockPatternUtils.getClass().getMethod("setLockScreenDisabled", boolean.class);
setLockScreenDisabledMethod.setAccessible(true);
clearLockMethod.invoke(lockPatternUtils, false);
setLockScreenDisabledMethod.invoke(lockPatternUtils, true);
Toast.makeText(ChangeDeviceLockMode.this,"none", Toast.LENGTH_LONG).show();
}catch(Exception e){
System.err.println("An InvocationTargetException was caught!");
Throwable cause = e.getCause();
Toast.makeText(ChangeDeviceLockMode.this,"none--"+cause, Toast.LENGTH_LONG).show();
Toast.makeText(ChangeDeviceLockMode.this,"none--"+e, Toast.LENGTH_LONG).show();
}
You also need to add a permission in manifest
android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
This permission requires app to be system signed.
Related
My service starts an Activity like this:
Intent intent = new Intent(context, CallMonitor.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
this happens in CallMonitor.onCreate():
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
On most devices, the activity (called up from service) wakes up the device, turns on the screen and is displayed.
But - for example - on Galaxy Tab 4, the activity is only called if the screen is already switched on.
If the screen is switched off and the service calls up the activity, it is displayed with a delay - It will be displayed immediatly after turning the screen on.
There is also a voice output in the activity. When the Galaxy S4 is switched off, it will not be played back - but immediatly after turning the screen on again.
Any suggestions?
I don't want to use WakeLock!
It looks like that's a device limitation and I don't know how you could work around that without using a WakeLock. We have a really old piece of code which you could modify to your needs which pretty much always worked for us:
public static void bringToFront() {
try {
PowerManager pm = (PowerManager) MainActivity.getAppContext().getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "ALARM");
wl.acquire();
KeyguardManager keyguardManager = (KeyguardManager) MainActivity.getAppContext().getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
lock.disableKeyguard();
if (MainActivity.getAppActivity() != null) {
MainActivity.getAppActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
} catch(Exception e){
e.printStackTrace();
Log.w(TAG, "bringToFront Err: "+e.toString());
}
}
I want my app or a part (any activity) of the app to be launched on opening the lockscreen, i.e, when we unlock the keypad of our phone, my activity should start running.. Thanks in advance. :D enter image description here
Try this one
A way to get unlock event in android?
It's using ACTION_USER_PRESENT receiver, but stil could help you.
To unlock the keyguard.
add this permission <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
// createWakeLocks();
KeyguardManager kgm = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
boolean isKeyguardUp = kgm.inKeyguardRestrictedInputMode();
KeyguardLock kgl = kgm.newKeyguardLock("QuickPopup");
if (isKeyguardUp) {
kgl.disableKeyguard();
isKeyguardUp = false;
}
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
// getWindow()
// .addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow()
.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
//wakeDevice();
}
For my application, I need to know that the screen is locked. How to check this is problematically. I used following flag:
if(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON != 0){
// some code
}else if((WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)!= 0){
// some code
}
But this always executing both if and else part... which flag I have to use to check the screen is locked or not?
I'll try to answer this though the question is already old since it is unresolved and could help other googlers. ;)
First you must register a BroadcastReceiver for Intent.ACTION_SCREEN_OFF & Intent.ACTION_SCREEN_ON. Note that this receiver must be registered in codes and will not work when declared in the manifest.
In your broadcast receiver, when you receive Intent.ACTION_SCREEN_ON, you can check if the screen is locked by using the below codes:
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
boolean locked = km.inKeyguardRestrictedInputMode();
KeyguardManager myKeyManager = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
if( myKeyManager.inKeyguardRestrictedInputMode()) {
//screen is locked
} else {
//screen is not locked
}
Register a broadcast receiver with action android.intent.action.ACTION_SCREEN_OFF and write your code in onReceive() method of receiver.
If you are using an activity, onPause() will be called when the screen locked and onResume() will be called when the screen unlocked.
In your code you are checking some flags, i don't know where you will do that checking ? is it continuous verification ? If you are using an activity in your app, the above procedure will happen, just check it in Android Developers website.
I guess you may have already found the answer, but if not (and for other developers), you can do it like this:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
boolean isScreenOn = powerManager.isScreenOn();
if (!isScreenOn) {
//Screen is in OFF State
//Code to power on and release lock
KeyguardManager km = (KeyguardManager) this
.getSystemService(Context.KEYGUARD_SERVICE);
final KeyguardManager.KeyguardLock kl = km
.newKeyguardLock("MyKeyguardLock");
kl.disableKeyguard();
PowerManager pm = (PowerManager) this
.getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
wakeLock.acquire();
}
There are broadcasted intents for screen lock & unlock.
Check it like :
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){//LOGIC Here}
Let me know!
Here is what I did:
This handles if the user has unlocked the screen, but not yet entered the home screen or the user's screen is turned off say during a call.
if (Intent.ACTION_SCREEN_ON.equals(pIntent.getAction()) ||
Intent.ACTION_USER_PRESENT.equals(pIntent.getAction())) {
if(mListener!=null) {
KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
boolean locked = km.inKeyguardRestrictedInputMode();
Log.v(TAG, ": Phone lock state from KEYGUARD_SERVICE: Current state:" + (locked ? "LOCKED":"UNLOCKED"));
mIsPhoneLocked = locked;
}
}
How to lock a android device or screen??. Here is my code.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context = this;
Button b = new Button(context);
b = (Button)findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
System.out.println("inside button");
PowerManager pManager = (PowerManager)
getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pManager.newWakeLock(PowerManager.
PARTIAL_WAKE_LOCK, "lock screen");
wl.acquire();
wl.release();
}
});
}
Here I am using a button. when user clicks on then the screen should be lock. But this code is not working. Is have to use BraodCastRecievr??. I included this permmission in manifest
<uses-permission android:name="android.permission.WAKE_LOCK" />
But also not working
KeyguardManager keyguardManager = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
For locking the screen use,
lock.reenableKeyguard();
and for disabling the lock use,
lock.disableKeyguard()
This will just hide the lock screen and will display if any incoming call or any such event is happening, it will display that screen. It wont display the lock screen.
When running the application, to disable from going to the lock state, just use
setKeepScreenOn() is set to true. or use the xml attribute android:keepScreenOn="true"
Another way to prevent the device to go to the sleep or lock mode when the application is running is set this api to true - setKeepScreenOn()
And of course we need to give permission android.permission.DISABLE_KEYGUARD
Try out the example shown here:
http://developer.android.com/reference/android/os/PowerManager.html
Lock the android device programmatically
I am trying to show a activity or a dialog when the phone is locked.
I have tried using a WakeLock but it did not work and I can only see the activity once my phone is unlocked?
What is the proper way to do this?
To show activity without dismissing the keyguard try this:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView();
You should use the KeyGuardManager to unlock the device automatically and then acquire your Wake Lock.
KeyguardManager kgm = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
boolean isKeyguardUp = kgm.inKeyguardRestrictedInputMode();
KeyguardLock kgl = kgm.newKeyguardLock("Your Activity/Service name");
if(isKeyguardUp){
kgl.disableKeyguard();
isKeyguardUp = false;
}
wl.acquire(); //use your wake lock once keyguard is down.
To show a popup on top of a lock screen try this, from my other answer:
AlertDialog alertDialog = new AlertDialog.Builder(context).create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
alertDialog.show();
To show activity on top of a lock screen, or basically remove the lock screen when activity is starts, try this:
public void onCreate(Bundle savedInstanceState){
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
...
}
Both of those options require api 5+