PowerManager and PARTIAL_WAKE_LOCK - android

My app works fine when the device is plugged in the power supply whereas it fails (time to time) when the device is unplugged. I think that the piece of code responsible of this issue is as follows:
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "foo");
wl.acquire();
foo();
wl.release();
foo() is a function that invokes a Camera.takePicture() that, as you know, results in a parallel task that takes a couple of seconds to complete. Thus, wl.release() is actually called when the picture has not yet taken. The above code is executed by an alarm which wakeup the device from its standby mode. My question is, is there the risk that the device returns in its standby mode before the picture has been taken due to the fact that wl.release might be called before the picture is taken? Does wl.release() release instantaneously the PARTIAL_WAKE_LOCK or the device remains in its run mode for a while?
Many thanks in advance for any comment.

My question is, is there the risk that the device returns in its standby mode before the picture has been taken due to the fact that wl.release might be called before the picture is taken?
Yes.
Does wl.release() release instantaneously the PARTIAL_WAKE_LOCK
Yes.
or the device remains in its run mode for a while?
That depends on what else might be holding a WakeLock.

Related

AlarmManager doesn't wake up device

I set the alarm like this:
registerReceiver(wakeUpReceiver, new IntentFilter("com.example.yay"));
pi = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent("com.example.yay"), 0);
am = (AlarmManager)(getSystemService(Context.ALARM_SERVICE));
if (android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT) {
am.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+30*1000, pi);
} else {
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+30*1000, pi);
}
And it works if the device is awake, but if I turn off the screen, it doesn't turn on the screen (but wakeUpReceiver's onReceive() gets called)
What do I need to put in the manifest? AlarmManager docs don't seem to mention anything relevant to permissions or intent filter or anything like that. Maybe I'm just misunderstanding the docs as usual?
And yes, I've read all the other similar questions, but they're not helping.
You can use Wakelock to achieve this:
Different Levels Wake Locks:
FULL_WAKE_LOCK - Keep the screen at full brightness, keyboard
back-light illuminated, and the CPU running. SCREEN_BRIGHT_WAKE_LOCK -
Keeps the screen at full brightness and the CPU running.
SCREEN_DIM_WAKE_LOCK - Keeps the screen ON but lets it dim and the CPU
running. PARTIAL_WAKE_LOCK - Keeps the CPU running
Android permission for Wakelock:
Since wake locks has huge impact on battery life your application needs to request WAKE_LOCK permission in order to create them.
Create Wake Locks
To create a wake lock call newWakeLock on the Power manger as follows:
PowerManager.WakeLock wakeLock ;
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock( PowerManager.SCREEN_DIM_WAKE_LOCK, "My wakelook");
Release Wake lock
wakeLock.release();
Its very important to release wakelock or else it will drain the battery.
As answered above use wakelock create WakeLock in onReceive().
Or I suggest you to use WakefulBroadcastReceiver.
This will make sure that ur phone is awake during service.
WakefulBroadcastReceiver is the best option for the 2nd thing, about wakelocks - u can check on google some examples that show how to use alarm manager with wakelocks.
Ofc, ur service can done it's work, but sometimes sleep can occour, so I suggest you to implement it even if ur tests don't show the problem, better too keep it safe.
Are you sure onReceive() being called? Create some logs and do some tests. For now there can be 2 problems: or sleep is not calling onReceive() (here check the power managment options on your phone, I had problem with "Stamina" on my phone, which was blocking my alarms) or your phone is falling asleep before u do your work (then wakelocks/WakefulBroadcastReceiver).
Also AlarmManager will not "light up" ur screen, only CPU.
To turn on the screen use getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
or android:keepScreenOn="true" in layout.
The method suggested by another user SCREEN_DIM_WAKE_LOCK was deprecated in API level 17, keep it in mind!
For more:
https://developer.android.com/training/scheduling/wakelock.html

Is it possible to detect motion when screen is off?

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.

PowerManager newWakeLock.acquire() not working as expected

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.

Android Native timer for bringing back the device to wake up mode?

I want to launch a timer which will get fired when the timer gets expired when the device is in low power (sleep) mode.
Device only gets waked up (normal mode) either on hard ware event (pressing of power button) or any network activity (call or data packet receiving).
Is there any way to bring the device back to the normal mode with timers in the native layer of android?
I googled so much but not able to find a way. Tried using timer_create() as well. But its not getting fired when the device is in low power (sleep) mode.
Please let me know if anyone had already done on this part.
Actually precision required for me is in milliseconds and the AlarmManager with RTC_WAKEUP is in the application layer which is expiring after consider delay and also this is in the Java layer. (If I implement Jni it will make some overhead to the application as there are multiple timers which need to be run in sleep mode).
To bring back the device up i think you can explore on these lines
1. PowerMangerService
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
wl.acquire();
//..screen will stay on during this section..
wl.release();
2. android.provider.Settings.System.SCREEN_OFF_TIMEOUT value in the settings for screen time out.
3. Intent.ACTION_SCREEN_ON and Intent.ACTION_SCREEN_OFF intents by PowerManagerService

PARTIAL_WAKE_LOCK when recording sensor data

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.

Categories

Resources