Android - 如何从深度休眠中唤醒手机拍照?

9
我希望能够定期从Android设备的相机中拍摄照片,以创建时间流逝视频效果。
我设置了一个Alarm Manager,并将AlarmManager.RTC_WAKEUP标志设置为每隔几分钟启动一次服务。
该服务持有部分唤醒锁,执行一些工作,然后通过Alarm Manager调用广播接收器,启动一个Activity。
该活动被创建(或已恢复),打开自己的唤醒锁,并设置相机预览表面。一旦表面设置完成,SurfaceHolder监听器的surfaceChanged()方法被调用,最终拍摄照片。
如果设备处于唤醒状态,则一切都按预期正常工作。但是,如果设备处于睡眠状态,则一旦Activity的onResume()方法完成,Activity即会立即暂停。相机的预览表面永远无法完成初始化,也不会拍照。
所以我有以下问题:
  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);
    

但是如果手机处于睡眠状态,则不能唤醒它。

  1. 有没有不使用预览视图的方式拍照?

  2. 有没有一种不依赖异步回调的方法来拍照?我能把所有的代码放在Activity的onResume()方法中拍照吗?

  3. 有没有一种方法可以保持Activity的onResume()方法运行足够长的时间,以使相机的预览有足够的时间来初始化并调用所有的监听器?

我正确地使用了wakelocks,并且在清单文件中设置了所有的权限。但我的Activity没有保持足够长的时间,以便异步监听器正常工作。

更糟糕的是,我试图让所有的东西都与Android 1.6兼容,因为那是我唯一能访问的测试设备。

这真是令人沮丧的事情!


你为什么不在你的服务中完成所有这些操作? - Mr_and_Mrs_D
这个问题已经有一段时间了,所以我不是100%确定。我认为服务在手机处于深度睡眠状态时不会运行,这就是为什么我必须使用Alarm Manager先唤醒手机的原因。 - Paul Klemstine
如果您成功运行服务(有一种方法)-是否需要在Activity中执行所有操作?因为如果不需要,我认为我已经得到了答案。 - Mr_and_Mrs_D
3个回答

8

我现在终于有了一些进展。

我需要使用这两个标志创建一个wakelock。

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();

设备唤醒后,从锁屏界面开始。

但我能够越过锁屏界面并拍照的唯一方法是在Activity窗口上使用这些标志:

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
    | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

但这仅适用于Android 2.0,不适用于1.6。

不要忘记这个权限 <uses-permission android:name="android.permission.WAKE_LOCK"/>。 - max

2
您可以使用以下方式禁用Keyguard屏幕:
KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
km.newKeyguardLock(TAG).disableKeyguard();

只要您拥有DISABLE_KEYGUARD权限,就可以实现。

自API Level 1开始提供该功能。


0
你的onResume方法里面有类似这样的操作吗?
.... onResume() {
    ....
    WakeLock myWakeLock = .....;
    ...
}

如果是这样,一旦方法退出,WakeLock 就会被释放,设备就可以自由地做任何它想做的事情(很可能是回到睡眠状态),你需要在类中某个地方存储 WakeLock,而不是作为函数局部变量。

我在onResume()方法中使用类变量来控制wakelock:PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ActivityWakeLock"); wl.acquire(); - Paul Klemstine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接