My goal is to have a simple program which fetches the contents of an image URL every X seconds, writes it to the /media/screensavers/Messages directory, then unlocks and relocks the device (Nook Simple Touch) so the new downloaded img is displayed.
The alarm fires off when it should and the image downloads (I can see via Android Studio logcat). The problem is the nook does not unlock. (the screen does not update).
Here is my code from AlarmReceiver.java
#Override
public void onReceive(Context context, Intent intent) {
// Log to logcat
Log.i("AlarmReceiver", "onReceive() -- onReceive fired! ");
// Create the dummy image url
String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
String imgPath = new String();
imgPath = "http://dummyimage.com/600x800/fff/000.jpg&text=" + currentDateTimeString ;
imgPath = imgPath.replaceAll(" ", "+");
// Download and save the image (works great)
new DownloadImageTask().execute(imgPath);
// Now how do I a) unlock the device, then b) put it back to sleep?
}
I tried this code from How to programmatically dismiss the screensaver/lock screen on Android (Nook Simple Touch)
Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
but getWindow() is RED (Can't resolve method).
I've tried using context.getWindow(), but that also has errors. How do I access getWindow from within the onReceiver context?
Goal: Refresh the 'Screensaver' image via
Download Image (done)
Write image to directory (done)
Unlock device
Lock devive
Thanks!
I had to switch to using an Activity as the intent, rather than a receiver.
Once I did that, I put the following code in the alarm activity:
KeyguardManager km = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
final KeyguardManager.KeyguardLock kl = km.newKeyguardLock("MyKeyguardLock");
kl.disableKeyguard();
PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
wakeLock.acquire(1000);
The above code unlocks the Nook!
Note that the getWindow() method with flags does not seem to work on the nook touch. Not sure why.
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());
}
}
hi i need to keep the device screen on mood, while application running.
disable the power button functionality to off the screen.
I have tried following codes
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
and wake locks
#Override
public void onReceive(Context context, Intent intent) {
if ((intent.getAction().equals(Intent.ACTION_SCREEN_OFF))) {
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "TEST");
wakeLock.acquire();
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent inten = new Intent(context,NewActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 0, inten, 0);
alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 100, pi);
}
}
// Finish your WakeLock HERE. call this method after U put the activity in front or when u exit from the new activity.
public void finishWakeLocker(){
if (wakeLock != null)
wakeLock.release();
}
Thanks in advance
This is not possible, for security reasons. HOME and POWER buttons are two things you will not be able to directly override without system-grade permissions. After all, the user wouldn't like your app to take control of their device, would they? ;-)
You should plan the functionality in such a way that a wakelock or
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
is enough :-)
EDIT:
There are tutorials such as the one uday linked, but the effects are generally unreliable and work only on some devices. I have developed an app like that and trust me, you do not want to have to debug this ;-)
Am developing a voip application. There is a background service which shows incoming call notifications, which works as expected (showing an incoming call dialog) when the phone is not locked and app is in background state.
How can i generate a dialog with interactive buttons, like whatsapp incoming call notification; even when the phone is locked?
Any heads up on this one or documentation that i can look up?
I can send an inapp notification for an incoming call, but that seems to be not enough for the purpose. I would need a full blow dialog interface which has a button or similar that would in turn open the application.
I am using Quickblox as the voip service provider.
Thanks in advance
I have tried unlocking the phone, on a button press
Here is my code to open a dialog from the background service.
viewToShowOnLockedScreen = View.inflate(getApplicationContext(), R.layout.activity_background_call, null);
viewToShowOnLockedScreen.setTag(TAG);
int top = getApplicationContext().getResources().getDisplayMetrics().heightPixels / 2;
final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, Utils.dpToPx(300), 0, 0,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
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);
viewToShowOnLockedScreen.setVisibility(View.VISIBLE);
Animation mAnimation = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.abc_slide_in_top);
viewToShowOnLockedScreen.startAnimation(mAnimation);
mWindowManager.addView(viewToShowOnLockedScreen, mLayoutParams);
mWindowManager.updateViewLayout(viewToShowOnLockedScreen, mLayoutParams);
And here is the code to unlock the device on a button press. Though this looks like it unlocks the phone, the screen is on, but the phone is still locked. Home button does'nt work.
KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
final KeyguardManager.KeyguardLock kl = km .newKeyguardLock("MyKeyguardLock");
kl.disableKeyguard();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
wakeLock.acquire();
Not really an answer, a work around i should say.
I coul'dnt unlock the screen. However I have updated the application to listen to Intent.ACTION_USER_PRESENT and added necessary to logic in the app to answer calls once the user has unlocked the device at the point of incoming call. Here is the code.
mUnlockStatusFilter = new IntentFilter();
mUnlockStatusFilter.addAction(Intent.ACTION_USER_PRESENT);
mUnlockStateIntentReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent i) {
if (i.getAction().equals(Intent.ACTION_USER_PRESENT)) {
//Do something phone is unlocked
Log.d(TAG,"Screen unlocked");
if(isWaitingForUnlock){
stopCallNotification();
if(Foreground.get().isForeground()){
Log.d(TAG, "App is in foreground; Sending a broadcast");
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.setAction(BaseActivityWithSignalling.onReceiveNewSession);
intent.putExtra("code", BaseActivityWithSignalling.onReceiveNewSessionCode);
sendBroadcast(intent);
Log.d(TAG, "Send broadcast for onReceiveNewSession");
}else{
Log.d(TAG, "App is in background; Showing activity");
Intent showCallingFromBG = new Intent(LMService.this, BackgroundCall.class);
showCallingFromBG.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(showCallingFromBG);
}
}
}
}
};
registerReceiver(mUnlockStateIntentReceiver, mUnlockStatusFilter);
I can lock my device with below code like
// Initialize Device Policy Manager service and our receiver class
devicePolicyManager =(DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
demoDeviceAdmin = new ComponentName(this, DemoDeviceAdminReceiver.class);
devicePolicyManager.lockNow();
But once i did it (means lock my device in android by above code ) how can i open this lock programmatically in android whenever i required ? To lock a device i used background service so is there any solution to create any services to re-open a lock of my device ?
Look at this:
//Get the window from the context
WindowManager wm = Context.getSystemService(Context.WINDOW_SERVICE);
//Unlock
//http://developer.android.com/reference/android/app/Activity.html#getWindow()
Window window = getWindow();
window.addFlags(wm.LayoutParams.FLAG_DISMISS_KEYGUARD);
try this
PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE), "TAG");
wakeLock.acquire();
wakeLock.release();
I used this working for me.
i start an activity from a BroadcastReceiver, which is triggered by an alaram (RTC_WAKEUP type). in onCreate of that activity i add these flags
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
);
problem is that sometimes (approximately 10% cases) the screen does not turn on. the alarm is correctly triggered (i here the sound of a notification, which is also fired in the receiver's onReceive(). then, if i hit the phone's power button, the screen turns on, showing my activity, and instantly turns off. after that, the power button works good. this happen on android 2.3.7 and here is the onReceive() method
#Override
public void onReceive(Context context, Intent intent) {
m_Context = context;
Bundle extras = intent.getExtras();
final int id = extras.getInt("timer_id");
Intent activityIntent = new Intent(m_Context, MyActivity.class);
activityIntent.putExtra("timer_id", id);
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
m_Context.startActivity(activityIntent);
// and now load the alarm sound and play it for the desired time
showFinishedNotification();
}
i would like to avoid using PowerManager, as it needs a permission, and the flags are the prefered way.
what could be a problem? logcat does not show any problems...
From my experience and research on this topic:
The FLAG_TURN_SCREEN_ON can not be used to turn the screen ON and OFF multiple times in your application.
The FLAG_TURN_SCREEN_ON can only be used once to turn the screen ON when creating a new activity (preferably in the onCreate() method) or when re-creating a view.
Now, you can get around this limitation by:
Launching a new activity and setting the flag there, then finishing the activity (by the user or programmatically) to let the screen turn off.
Setting the params.screenBrightness parameters to as "dim" as possible, sometimes the screen "appears OFF". You can then increase the brightness to "turn ON" the screen. However, this often does not work as the screen is still dim but visible, also this doesn't work if the user locks the phone.
Using the Power Manager Wakelock (this still works but Android deprecated this functionality, so they are discouraging the use of this technique). However, as far as I can tell this is the only way I can get my application to turn the screen ON/OFF reliably.
None of these are ideal (in fact they feel like hacks) but just use the one that better suits your application needs.
You can read more here:
Android Alarm Clock Source Code
Android Desk Clock Source Code
Dimming the screen to appear OFF/ON
Using a wakelock to keep the screen ON/OFF
Waking up device and turning screen ON multiple options
I'm a bit late to the party here but I've been fighting this for a while now and finally found a way to get the screen to unlock every time. I add the flags in the onAttachToWindow() event. Typically I do this from a WakefulBroadcastReceiver so the screen transitions smoothly but that's use-case dependent.
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
//Screen On
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);
}
private void clearFlags() {
//Don't forget to clear the flags at some point in time.
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
problem is that sometimes (approximately 10% cases) the screen does not turn on
If I had to guess, the device is falling back asleep before the activity starts up. Once onReceive() returns, the device can and will fall back asleep, and it will be some time after onReceive() returns before your activity will start.
This same scenario, but replacing startActivity() with startService(), is why I had to write WakefulIntentService, which uses a WakeLock to ensure that the device stays awake long enough for it to do its work, then releases the WakeLock.
Late answer But it will help for anyone.
For higher and lower versions use following code (it working fine)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
keyguardManager.requestDismissKeyguard(this, null);
}
else{
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);
}
setContentView(R.layout.activity_incoming_call);
}
Important Note: you should place before setContentView()
I use these three methods simultaneously which works at almost any device.
public static void turnScreenOnThroughKeyguard(#NonNull Activity activity) {
userPowerManagerWakeup(activity);
useWindowFlags(activity);
useActivityScreenMethods(activity);
}
private static void useActivityScreenMethods(#NonNull Activity activity) {
if (VERSION.SDK_INT >= VERSION_CODES.O_MR1) {
try {
activity.setTurnScreenOn(true);
activity.setShowWhenLocked(true);
} catch (NoSuchMethodError e) {
Log.e(e, "Enable setTurnScreenOn and setShowWhenLocked is not present on device!");
}
}
}
private static void useWindowFlags(#NonNull Activity activity) {
activity.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);
}
private static void userPowerManagerWakeup(#NonNull Activity activity) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
WakeLock wakelock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, tag);
wakeLock.acquire(TimeUnit.SECONDS.toMillis(5));
}
Targeting sdk 30
Following code enables to open Activity from PendingIntent, even if application
was cleared from recent apps
and screen is dimmed
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(view)
turnOnScreen()
}
private fun turnOnScreen() {
window.addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
)
setTurnScreenOn(true)
setShowWhenLocked(true)
val keyguardManager = getSystemService(KEYGUARD_SERVICE) as KeyguardManager
keyguardManager.requestDismissKeyguard(this, null)
}