Android - Wake lock not acquiring properly, app needs to keep running in standby
Asked Answered
K

3

6

In my app, in the onCreate() method of the main activity I am creating a wake lock so that the CPU will keep running if the phone goes on standb/screen turns off.

Also in the onCreate method I have an intent to create a service that uses the accelerometer. This service needs to be continuously running while the app is open and monitoring accelerometer values (I know this isn't good for battery but I need it to do that). Here is my code at the moment and the service starts fine.

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);  

        PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Howaya");
        wl.acquire();

        if (appStart == true)  
        { 
            Intent AccelService = new Intent(this, Accelerometer.class);
            AccelService.putExtra("unreg", false);
            startService(AccelService);
        }
        appStart = false;
  }

I have the following permission set in my manifest -

<uses-permission android:name="android.permission.WAKE_LOCK" />

I have tried this with different locks - dim screen and full brightness to no avail too. My output on logcat is here -

F/PowerManager(15628): android.util.Log$TerribleFailure: WakeLock finalized while still held: Howaya
F/PowerManager(15628):  at android.util.Log.wtf(Log.java:260)
F/PowerManager(15628):  at android.util.Log.wtf(Log.java:239)
F/PowerManager(15628):  at android.os.PowerManager$WakeLock.finalize(PowerManager.java:329)
F/PowerManager(15628):  at dalvik.system.NativeStart.run(Native Method)

I have seen people saying that partial wakelocks don't work like they should do, such as this link Google standby error page but this was released and closed last year so I don't know is that the case, can anyone help here please? I have a HTC Desire as regards that last point too, Thanks.

Kindling answered 19/2, 2011 at 17:10 Comment(0)
B
2

In my app, in the onCreate() method of the main activity I am creating a wake lock so that the CPU will keep running if the phone goes on standb/screen turns off.

Please use android:keepScreenOn on one of the widgets in your layout instead. That is far, far safer for activities than manually dealing with a WakeLock. Plus, you don't need the WAKE_LOCK permission then, IIRC.

My output on logcat is here

That error is because you never release the WakeLock. Please do not leak WakeLocks.

Now, you managed to write all of this prose and include all of these listings, and you forgot one little thing: actually telling us what your question is. This is a rather important item for a question-and-answer site like StackOverflow. And, no, "can anyone help here please?" does not count as a question when you never define what "help" it is you are looking to receive.

Behnken answered 19/2, 2011 at 17:33 Comment(5)
Ok sorry if I was unclear and thank you for the reply. My question was how can I get a wakelock running on my phone so that my app runs while the screen is still off, as the code I am using above isn't working. I would prefer not to have the screen on so that it won't waste as much battery and not have to use the widget in case I decided to put it on the market (then other users would have to use the widget)Kindling
@bobby123: An activity cannot have a logical need for a partial WakeLock. A service might have a need for a partial WakeLock, but not an activity, whose only purpose for existing is to display stuff on the screen. So, either get your WakeLock out of the activity and into the service (adjusting your business logic to match), or use android:keepScreenOn. Acquire your WakeLock in onCreate() of your service and release it in onDestroy(). Use startForeground() so your service isn't nuked and give the user an easy way to get to an activity to stop the service.Behnken
That's what I wanted to know, thanks. I'll move the wake lock to the service as that's what I really need it for. I have a menu button for the user to end the service at any time. One last question please, do you know should the method onSensorChanged() for the accelerometer still work while under a partial wake lock or is this still an issue with Google?Kindling
@bobby123: "do you know should the method onSensorChanged() for the accelerometer still work while under a partial wake lock or is this still an issue with Google" -- I am unaware that sensor behavior under WakeLocks is documented, which means it may vary by device. However, I haven't paid a lot of attention to this particular issue, since it's not in my area of interest, so I am far from expert on that topic, sorry.Behnken
From everything I've read I think it may be device specific alright, thought I'd ask anyways. Ok I'll your advice and thanks again.Kindling
M
10

Problem occurs because your WakeLock object is a local scoped variable inside OnCreate method. After method being executed - WakeLock object is no more referenced - thus eligible for garbage collection. If Dalvik GC occurs - object is ready for finalize - and finalizer internal code warns You, that WakeLock is still held - and active - but will be GC'ed. You have to obtain new WakeLock object and assign it to a field of class type WakeLock in Your activity derived class. Read about Object Oriented programming and Garbage Collector - You will understand the issue.

Martini answered 29/3, 2011 at 20:3 Comment(0)
B
2

In my app, in the onCreate() method of the main activity I am creating a wake lock so that the CPU will keep running if the phone goes on standb/screen turns off.

Please use android:keepScreenOn on one of the widgets in your layout instead. That is far, far safer for activities than manually dealing with a WakeLock. Plus, you don't need the WAKE_LOCK permission then, IIRC.

My output on logcat is here

That error is because you never release the WakeLock. Please do not leak WakeLocks.

Now, you managed to write all of this prose and include all of these listings, and you forgot one little thing: actually telling us what your question is. This is a rather important item for a question-and-answer site like StackOverflow. And, no, "can anyone help here please?" does not count as a question when you never define what "help" it is you are looking to receive.

Behnken answered 19/2, 2011 at 17:33 Comment(5)
Ok sorry if I was unclear and thank you for the reply. My question was how can I get a wakelock running on my phone so that my app runs while the screen is still off, as the code I am using above isn't working. I would prefer not to have the screen on so that it won't waste as much battery and not have to use the widget in case I decided to put it on the market (then other users would have to use the widget)Kindling
@bobby123: An activity cannot have a logical need for a partial WakeLock. A service might have a need for a partial WakeLock, but not an activity, whose only purpose for existing is to display stuff on the screen. So, either get your WakeLock out of the activity and into the service (adjusting your business logic to match), or use android:keepScreenOn. Acquire your WakeLock in onCreate() of your service and release it in onDestroy(). Use startForeground() so your service isn't nuked and give the user an easy way to get to an activity to stop the service.Behnken
That's what I wanted to know, thanks. I'll move the wake lock to the service as that's what I really need it for. I have a menu button for the user to end the service at any time. One last question please, do you know should the method onSensorChanged() for the accelerometer still work while under a partial wake lock or is this still an issue with Google?Kindling
@bobby123: "do you know should the method onSensorChanged() for the accelerometer still work while under a partial wake lock or is this still an issue with Google" -- I am unaware that sensor behavior under WakeLocks is documented, which means it may vary by device. However, I haven't paid a lot of attention to this particular issue, since it's not in my area of interest, so I am far from expert on that topic, sorry.Behnken
From everything I've read I think it may be device specific alright, thought I'd ask anyways. Ok I'll your advice and thanks again.Kindling
P
0

As @Michal P said, you acquire a wakelock in onCreate method, but you never release it.

When GC scan this zero referenced object, call default finalize method, but actually it is active.

  @Override
    protected void finalize() throws Throwable {
        synchronized (mToken) {
            if (mHeld) {
                Log.wtf(TAG, "WakeLock finalized while still held: " + mTag);
                Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0);
                try {
                    mService.releaseWakeLock(mToken, 0);
                } catch (RemoteException e) {
                }
            }
        }
    }
Pennate answered 6/4, 2017 at 7:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.