Android - How can I wake up the phone from a hard

2019-01-17 09:11发布

问题:

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:

  1. 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.

  1. Is there any way to take a picture without using a preview surface view?

  2. 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?

  3. 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!

回答1:

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.



回答2:

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.



回答3:

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.