I am recording sensor data such as Accelerometer, Orientation, Gyroscope. This data writes to a file onSensorChanged update every so often.
My problem is when I put the phone into standby that the sensor data stops writing to file. So I done some research and decided to set it up using PowerManager and using the wake lock
PARTIAL_WAKE_LOCK: I just can't get it working.
SCREEN_DIM_WAKE_LOCK: My code will work grand.
From what I read up on there seems to be a problem with using PARTIAL_WAKE_LOCK.
I can't seem to find a definite answer on whether or not there is a problem with it still or there isn't. I even tried some of the hack approaches people have suggested such as using an itent to capture when screen is off and then unregistering the sensors and registering them again. But this solution didn't work. From what I can gather it seems inconsistant if it will work or not and seems phone dependant. I have tried my code on both a HTC Wildfire running Android2.2 and Nexus S running Android2.3.
My application is an app that is basically ran in the background with a long running service. So having PARTIAL_WAKE_LOCK is important with battery life.
This is only defined to work as of Android 2.3. Prior to that the platform would explicitly turn off all sensors when the screen turns off in order to reduce battery use.
This is a pretty old question, I'll still answer it as pretty much all the devices today are beyond 2.3
Create a background service and use the Partial Lock Wake in the following manner:
First take care of the permissions (in the manifest file):
<uses-permission android:name="android.permission.WAKE_LOCK" />
Then, most preferably use this in the Application file, or wherever:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyWakelockTag");
if(/*condition*/) {
wakeLock.acquire(); //keep CPU awake
} else {
wakeLock.release(); //disable keep CPU awake
}
Although it is a pretty cool feature, it drains your battery life, hence use it responsibly.
Related
My audio streaming app is working correctly with only WifiLock.
But some devices report that when they turn off the screen, connection is cut and audio streaming is topped. (They say this does not happen on 3G)
So, I thought maybe I can also use a Partial WakeLock. I am not sure if this fixes the issue but I think it is an option. At the same time, adding a WakeLock while a basic WifiLock is working may deplete the battery faster and may not fix the issue.
What do you think about adding a WakeLock too for this kind of issue and app?
private static WifiLock wifiLock = ((WifiManager) appInstance().getSystemService(Context.WIFI_SERVICE))
.createWifiLock((android.os.Build.VERSION.SDK_INT>=12?WifiManager.WIFI_MODE_FULL_HIGH_PERF:WifiManager.WIFI_MODE_FULL), "myappwifilock");
The newly added line:
private static WakeLock wakeLock= ((PowerManager) appInstance().getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "myappwakelock");
(ofcourse I acquire and release these locks on the creation of the service and on the destruction of it.)
Use them both. The behavior I am sure varies from phone to phone. You may wish to search for the devices the reports are about + "wifi"or "wifi driver". Are you sure your audio streaming app is working correctly with only WifiLock ? This sounds very strange - the CPU will go to sleep and the service will stop - see Service, WakeLock. Something else is keeping the phone awake. So you need a wake lock
If you only use wake lock on the other hand the wifi will turn off maybe - I am not sure for you are using it - but better safe than sorry. If it does turn off waking the phone up won't wake it up - for this I am sure. Using the wifi lock has no impact on the battery - using the wifi radio has, and this you are doing anyway.
So both - and be sure your service acquires them - have a look at WakefulIntentService
My app simply need to detect any motion of the device while screen is off.
I know that accelerometer is used for this task but it don't work while screen is off in all devices. this is a list of devices http://www.saltwebsites.com/2012/android-accelerometers-screen-off
so is there a way of taking accelerometer sensor data while screen is off that works on all devices?
or is there a way to detect motion using another sensors?
Partial Wake Lock is all you need to access accelerometer readings while the screen is off.
You can use it like this:
private PowerManager.WakeLock mWakeLock;
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
mWakeLock.acquire();
And after you're done, just release the lock:
mWakeLock.release();
If you obtain accelerometer data in a Service, you could simply acquire lock in it's onCreate() and release in onDestroy().
Yes you can use accelerometer in the background or when screen is off
but you need to hold a WakeLock [Link] to prevent the device from sleeping.
If you need to detect if the device is still or if it started moving again you might be interested in Recognizing the User's Current Activity from Google Services.
After a quick research I found that most of android devices does not send the accelarometer events when the screen is off. To know more about this bug please take a look on here. Also here too.
When the screen is off the CPU goes to sleep and you cannot capture events without taking a partial wakelock. I suggest you to take a partial wakelock when you call the onPause and release it onResume. Be careful with wakelocks they make your phone drain a really big amount of energy, you should manage them carefully.
PS: You have to acquire the wakelock in the onPause method because if you try to call it somewhere else you might not be able to gain it because the CPU may be already shutted down.
Envrionment: Eclipse
Language: Java (Android)
I have a bit of a problem, which I didn't realise until I tested my application out on a device. I always thought that services would continuously be running in the background, even when the phone's sleeping. I found out that this is not the case, so, my question is that does the service start up again once you wake your device up? And if not, how would I cause the service to start-up again.
Would I be able to wake the phone every 5 minutes or so, just to run my service, which will last 30 seconds to 1 minute. And then make the phone sleep again?
Thanks in advance.
EDIT: I am very new to Android programming and would really appreciate if someone would tell me how to use WakefulIntentService.
I have a service that is searching for the user's GPS Location every so often, and when the phone goes to sleep, I want my service to still look for their location. How would I go about using the WakefulIntentService for this? And would I be able to use it in this scenario.
Thanks.
You need to hold the processor lock to keep your service running
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TAG");
wl.acquire();
// When you are done
wl.release();
And if your service is using Wi-Fi, you need another lock as well
WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifiLock= wm.createWifiLock(WifiManager.WIFI_MODE_FULL, "TAG");
wifiLock.acquire();
// When you are done
wifiLock.release();
Remember to add android.permission.WAKE_LOCK in your manifest
I have a service that is searching for the user's GPS Location every so often, and when the phone goes to sleep, I want my service to still look for their location. How would I go about using the WakefulIntentService for this? And would I be able to use it in this scenario.
WakefulIntentService is inappropriate here, as it is designed only to keep the device awake for a short period of time to do some work. It is not designed to keep the device awake for an indeterminate time, such as the time it takes to get a GPS fix.
I have a LocationPoller project that handles your scenario a bit better.
I am very new to Android programming
What you are trying to do is not a suitable project for somebody with your Android experience level, IMHO.
I don't know what your service is doing exactly, but if it's down/uploading data to a server you might want to consider using a Sync Adapter.
Unless you need exact timing this is less of a burden on your system than AlarmManager.
I you are doing something else, you might want to look into the JobScheduler API.
Anyway if you really want to stick to AlarmManager just know that Inexact Repeating is already a lot better than Exact Repeating.
I used AlarmManager, I looked at WakefulIntentService and that gave me an idea on what to do.
Thanks again for the help everyone.
I want my app to keep the CPU running but turn the screen off to minimise power wastage.
Previous posts on this subject suggest the following approach:
mPm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = mPm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Constants.WAKE_LOCK_TAG);
mWakeLock.acquire(); //keep CPU running, turn screen off
The manifest contains:
<uses-permission android:name="android.permission.WAKE_LOCK" />
In my innocence I expected that on acquiring the lock the screen would go off immediately but nothing happened.
The earlier posts I have read never seem to overcome this problem, did anyone succeed? Is there anything else I must do?
It would be more efficient in another way to use this within the onCreate method of the activity:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
That is a better way to use wake-locks in a efficient manner.
The wake lock does not turn off the screen. Normally, when the screen goes off, your application pauses because the CPU is put to sleep. If you have PARTIAL_WAKE_LOCK, your app will continue to run and the CPU will be active even when the screen goes off (due to auto or manual sleeping). Only use this if you really need to continue processing data after the screen is off. You mention you are concerned about minimizing power usage, acquiring a wake lock of any kind can cause waster power. It is wise to follow this warning from the PowerManager docs
Device battery life will be significantly affected by the use of this
API. Do not acquire PowerManager.WakeLocks unless you really need
them, use the minimum levels possible, and be sure to release them as
soon as possible.
So it is good idea to evaluate why you think you need a wake lock for your task. If you think it is too save power, it isn't.
I am bit confused after going through the questions & answers in Stackoverflow about WakefulIntentService. I just would like to get some knowledge on this topics to make sure my understanding is correct, please feel free to correct me, if I am wrong.
I built a small application, where I am using a background Service that keeps playing music whenever the user shakes the mobile. I tested after the device is locked and screen is turned off and it works as expected.
What I am hearing from this forum, the service might turn off as soon the device goes to asleep. Is that true? In my case, it works always, Am I missing something?
What is the need of WakeFulIntentService? When do we need to use WakefulIntentService?
I tried running a timer in a Service, though the device is locked and screen is turned off and my timer is running pretty much I can say for sure. Because I used to get notification whenever my timer trips.
What I am hearing from this forum, the service might turn off as soon the device goes to asleep. Is that true?
Yes.
In my case, it works always
Then something else on your device is keeping the device from falling asleep. Perhaps use adb shell dumpsys power to see what WakeLocks are outstanding.
What is the need of WakeFulIntent Service? When do we need to use WakefulIntentService?
The device may fall asleep if the user is inactive and nothing is keeping the device awake. A WakeLock is used to ensure the device stays awake. For transactional-type work (e.g., downloading a file), WakefulIntentService combines an IntentService and a WakeLock to make keeping the device awake as long as necessary (and only as long as necessary) relatively easy.
WakefulIntentService is not suitable for use with services that need to run indefinitely, such as a music player. For those, manage your own WakeLock.
I used the code below in an app.
Make sure your service is sticky:
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
//this service will run until we stop it
return START_STICKY;
}
I you want your phone to be awake constantly u can use this code below:
private WakeLock wl;
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "whatever");
wl.acquire();
Don't forget the permissions in your manifest.
<uses-permission android:name="android.permission.WAKE_LOCK" />