How do I prevent an Android device from going to sleep programmatically?
If you just want to prevent the sleep mode on a specific View, just call setKeepScreenOn(true) on that View or set the keepScreenOn property to true. This will prevent the screen from going off while the View is on the screen. No special permission required for this.
One option is to use a wake lock. Example from the docs:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
wl.acquire();
// screen and CPU will stay awake during this section
wl.release();
There's also a table on this page that describes the different kinds of wakelocks.
Be aware that some caution needs to be taken when using wake locks. Ensure that you always release() the lock when you're done with it (or not in the foreground). Otherwise your app can potentially cause some serious battery drain and CPU usage.
The documentation also contains a useful page that describes different approaches to keeping a device awake, and when you might choose to use one. If "prevent device from going to sleep" only refers to the screen (and not keeping the CPU active) then a wake lock is probably more than you need.
You also need to be sure you have the WAKE_LOCK permission set in your manifest in order to use this method.
I found another working solution: add the following line to your app under the onCreate event.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
My sample Cordova project looks like this:
package com.apps.demo;
import android.os.Bundle;
import android.view.WindowManager;
import org.apache.cordova.*;
public class ScanManActivity extends DroidGap {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
super.loadUrl("http://stackoverflow.com");
}
}
After that, my app would not go to sleep while it was open. Thanks for the anwer goes to xSus.
android:keepScreenOn="true" could be better option to have from layout XML.
More info: https://developer.android.com/training/scheduling/wakelock.html
Set flags on Activity's Window as below
#Override public void onResume() {
super.onResume();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
#Override public void onPause() {
super.onPause();
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
From the root shell (e.g. adb shell), you can lock with:
echo mylockname >/sys/power/wake_lock
After which the device will stay awake, until you do:
echo mylockname >/sys/power/wake_unlock
With the same string for 'mylockname'.
Note that this will not prevent the screen from going black, but it will prevent the CPU from sleeping.
Note that /sys/power/wake_lock is read-write for user radio (1001) and group system (1000), and, of course, root.
A reference is here: http://lwn.net/Articles/479841/
what #eldarerathis said is correct in all aspects, the wake lock is the right way of keeping the device from going to sleep.
I don't know waht you app needs to do but it is really important that you think on how architect your app so that you don't force the phone to stay awake for more that you need, or the battery life will suffer enormously.
I would point you to this really good example on how to use AlarmManager to fire events and wake up the phone and (your app) to perform what you need to do and then go to sleep again: Alarm Manager (source: commonsware.com)
If you are a Xamarin user, this is the solution:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle); //always call superclass first
this.Window.AddFlags(WindowManagerFlags.KeepScreenOn);
LoadApplication(new App());
}
Related
I'm creating an application that needs to keep track of a lot of things the user is doing. This all needs to happen in the background and needs to be running continiously. To mention two: constant tracking of activity with google activity API and location tracking with google's geofence API.
I have created a (Intent)Service for each parameter I am tracking and everything is going well. Even when you kill the application, the service will start again on the background and perform as expected.
MY PROBLEM: As soon as I lock my phone, it stops tracking. As soon as I light up my screen or unlock it works again.
NOTE1: I'm using one main service which controls all other (intent)services sensing the parameters. (I'm not sure if this is the best way to do it or if I should create one big service?...).
What I've tried is the PARTIAL_WAKE_LOCK to keep awake my main service controlling all other services. This didn't work. I've also tried to use the PARTIAL_WAKE_LOCK to keep awake the services sensing the parameters. This did not work either.
NOTE2: I know this should not be done in real applications but it's a must. It's an application for an experiment and will never go in the playstore. Also all users will be notified what will be tracked and how this can effect their battery during the experiment.
#Override
public void onCreate() {
super.onCreate();
...
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyWakelockTag");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (! keepCPUOn){
wakeLock.acquire();
keepCPUOn = true;
}
}
Manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Many thanks!
Beginning with Android 6 and its new Doze mode the wake locks don't prevent the device to enter sleep mode, they are ignored
Proposed solution: Your service need to be a foreground service, that's it should call startForeground() and show a non dismissable notification, and you need to acquire a partial wake lock too.
I am also creating app like your. location tracking work in background and UI screen doesn't lock. in which UI screen you are start location service please put below code in that java file.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_current_ride_new);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyWakelockTag");
wakeLock.acquire();
}
This code is working perfectly for me.
I've just add my app in Protected apps in settings my phone Android 4.4 (this flug allow to keep running after the screen is turned off)
I develop a small app, this one have to run always over all when the device is sleep or deep sleep (press right button to turn off the screen) I read many posts about it, and all tell me that the way is use PowerManager, and my question is if I use fine this command, my structure is> myActivity.class, ReceiverBoot.class and ServiceBoot.class, I use the POwerManager class on myActivity.class like this:
PowerManager mgr = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
PowerManager wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP , "MyWakeLock");
on onCreateMethod after of this one put
wakeLock.acquire();
and after of this one I have a
super.onCreate(savedInstanceState);
this.mTimer.scheduleAtFixedRate(
new TimerTask(){
#Override
public void run(){doTask();}
} , 0, 1000);
wakeLock.release();
on Manifest XML code I have
<uses-permission android:name="android.permission.WAKE_LOCK" />
and on layout XML code have
android:keepScreenOn="true"
but after to 10seg the creen es OFF always but the app is running, jut with wifi.
the app work very fine with wifi conn, but when change to 3G conn, the app is gone, I use fine this command?? the problem is the kind of conn to Internet??? thanks a lot!
I'm not 100% clear on your issue. Whether its the data issue, or the screen issue. (Or if the screen issue is what you are doing to try and fix the data issue?).
For the screen
You are not using the right lock to keep the screen on. PARTIAL_WAKE_LOCK only requests that you can use the processor. To keep the screen on your app use one of SCREEN_DIM_WAKE_LOCK, SCREEN_BRIGHT_WAKE_LOCK or FULL_WAKE_LOCK depending on what you want. This lock should be held for as long as you need the lock. Currently you are releasing it in onCreate(). Keep in mind that if the user presses the power button though that your lock is released (with PARTIAL being the exception to this).
If your intent is just to keep the screen on when a view is active then it's better not to use the lock at all. The wake lock needs an extra permission. You can do it by adding this to your onCreate override:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
This is the same effect as using android:keepScreenOn="true", which you already seem to be doing. I can't however tell why that isn't working from your snippets. Make sure you are inflating the right layout.
For your data
The device will likely be switching off 3G data when the screen is not active (and no lock is present). Again, don't release your lock if you need it (Though don't keep it forever either, that's just going to suck up phone battery).
How to keep an Activity running/active when the screen shuts off?
You will need to use a PARTIAL_WAKE_LOCK to ensure that your activity is kept active. android.permission.WAKE_LOCK must be requested in your manifest. However, battery will drain faster, so do remember to release the wakelock as soon as possible.
Alternately, use a Service instead
In the onCreate of your Activity, put the following lines:
Context mContext = getApplicationContext();
PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
final PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PARTIAL_WAKE_LOCK,"motionDetection:keepAwake");
wakeLock.acquire();
//Place this where you no longer need to have the processor running
wakeLock.release();
After you press the power button, the activity should still run if that's where you closed it.
If you were like me, and you were collecting accelerometer data, be sure to remove the default sensorManager.unregisterListener(this); from the onPause part of the app.
There is also a good way.
I found this some months ago and it save a little bit the battery life ;)
http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/
Be sure you don't have ' android:noHistory="true" ' in your manifest file for any of the activities. It kills the activity when the app goes off the screen or screen shuts off.
If you want your app stay active even if the screen is off I don't think you need to do anything extra: My application doesn't have any extra code for it and when I turn the screen off and on it is still there. But! Android OS probably kills it after a while when the screen is off, so you should probably use WAKE_LOCK in your manifest file. Or you can add ' android:keepScreenOn="true" ' to the manifest file to keep the screen ON all the time when your app is running.
I have a CPU intensive long-running operation (a few hours) that I am using AsyncTask to perform. As it continues, it updates a progressbar on the screen to show what percentage of the task is done.
I discovered that when my screen goes to sleep (time-out) the task seems to stop. Not sure whether this is happing because the AsyncTask stops or it gets stuck at trying to update the screen (latter I am thinking).
Other than never letting the screen sleep, how else can I prevent my AsyncTask to stop executing? And if that is the only way, then how do I make sure that the screen doesn't sleep?
EDIT: I must add that I know this sounds like a non-user-friendly app as commented by someone below. This does a very specialized task (processes thousands of image files to compare processing on different systems) and is to be used by a few users internally, not for public release.
That's expected behavior. The idea is that the phone's battery is not supposed to drain because of bad apps. If the screen is off, the user generally expects the phone to sleep.
If you need your app to run, you can use a WakeLock to keep the phone running (with the screen off): Documentation here and here.
Note that a wake lock requires the WAKE_LOCK permission, and again, you need to make it clear to the user that your app will drink the phone's milkshake while it's off.
Not sure if anyone will read this as the OP is several years old but I am in the same boat in that I need to use a wakelock for an app for internal use, and leaving the screen on was not ok (I just needed the cpu on so I could run some metrics queries) I simply used a partial wakelock; ie:
public class my_frag extends Fragment {
WakeLock wl;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setRetainInstance(true);
PowerManager pm = (PowerManager) this.getActivity().getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
//I happen to have it in a button click event based on an async task
//Side note: I should probably be using a Loader for my Async task but this works fine
connectButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (metrics_task != null)
{
Status s = metrics_task.getStatus();
if (s.name().equals("RUNNING")){
if (metrics_task.running){
metrics_task.cancel(true);
connectButton.setText("Start");
metrics_task.running = false;
wl.release(); <--releases it on async stop
}
else{
metrics_task = new start_metrics(ae);
metrics_task.execute();
wl.acquire(); <--starts it on async start
}
}
else{
metrics_task = new start_metrics(ae);
metrics_task.execute();
}
}
else{
metrics_task = new start_metrics(ae);
metrics_task.execute();
}
}
});
This worked great with no issues
My 2 cents on this old post, in case it might help someone. If all you want is to prevent your screen from going to sleep, there's a simple solution that does not require a permission from the user - and it's just 2 lines of code:
// prevent the screen from sleeping
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// do your stuff
// don't forget to re-enable the screen time-out so it won't stay awake from now on
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
An important note: it can only be called within an Activity - not from other app components. more details can be found here.
I want to take pictures from the Android device's camera periodically over a matter of hours, to create a time lapse video effect.
I set an Alarm Manager with an AlarmManager.RTC_WAKEUP flag set to start up a service every few minutes.
The service holds a partial wakelock, does some work, and then calls a Broadcast Receiver through the Alarm Manager which starts up an Activity.
The activity is created (or is resumed), turns on it's own wakelock, and sets up the camera preview surface. Once the surface is setup the SurfaceHolder listener's surfaceChanged() method is called, which finally takes a picture.
If the device is awake, everything works perfectly as expected. But if the device is asleep, once the Activity's onResume() method is finished the Activity is instantly paused. The camera's preview surface never finishes initializing, and no picture will ever be taken.
So the questions I have are:
Is there any way to wake up the phone programmatically? I even try using:
PowerManager powerManager =
(PowerManager)this.getSystemService(Context.POWER_SERVICE);
powerManager.userActivity(SystemClock.currentThreadTimeMillis(),false);
But that doesn't wake up the phone if it is asleep.
Is there any way to take a picture without using a preview surface view?
Is there a way to take a picture that doesn't rely on asynchronous callbacks? Can I put all the code in the Activities onResume() method to take a picture?
Is there any way to keep the Activity's onResume() method running long enough so that the camera's preview has enough time to initialize and call all the listeners?
I am using the wakelocks correctly, and I have all the permission's set properly in the manifest file. My activity isn't kept awake long enough for the asynchronous listeners to properly work.
And to compound the issue, I'm trying to keep everything Android 1.6 compatible, because that is the only test device I have access to.
This is frustrating stuff!
I have finally gotten somewhere now.
I have to create a wakelock using these two flags
PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ACQUIRE_CAUSES_WAKEUP
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ACQUIRE_CAUSES_WAKEUP, "bbbb");
wl.acquire();
Then the device wakes up, and starts at the keyguard screen.
But the only way I can get past the keyguard screen and take a picture is to use these flags on the Activity's window:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
But this is only available with Android 2.0, and doesn't work in 1.6.
You can also disable the Keyguard screen with
KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
km.newKeyguardLock(TAG).disableKeyguard();
provided you have the DISABLE_KEYGUARD permission.
That's available since API Level 1.
Are you doing something like this in your onResume method
.... onResume() {
....
WakeLock myWakeLock = .....;
...
}
If so, as soon as the method exits, the WakeLock is released, and the device is free to do whatever it feels like doing ( which is likely to go back to sleep )
and you will need to store the WakeLock in the class somewhere, not as a function local.