9

我想在几个小时内定期从 Android 设备的相机中拍照,以创建延时视频效果。

我设置了一个带有 AlarmManager.RTC_WAKEUP 标志的警报管理器,以每隔几分钟启动一次服务。

该服务持有一个部分唤醒锁,做一些工作,然后通过启动一个活动的警报管理器调用一个广播接收器。

活动被创建(或恢复),打开它自己的唤醒锁,并设置相机预览表面。一旦设置了表面,就会调用 SurfaceHolder 侦听器的 surfaceChanged() 方法,最终拍摄一张照片。

如果设备处于唤醒状态,则一切都按预期完美运行。但是如果设备处于睡眠状态,一旦 Activity 的 onResume() 方法完成,Activity 就会立即暂停。相机的预览表面永远不会完成初始化,也不会拍摄任何照片。

所以我的问题是:

  1. 有没有办法以编程方式唤醒手机?我什至尝试使用:

    PowerManager powerManager =
                (PowerManager)this.getSystemService(Context.POWER_SERVICE);
    powerManager.userActivity(SystemClock.currentThreadTimeMillis(),false);
    

但是,如果它睡着了,这不会唤醒手机。

  1. 有什么方法可以在不使用预览表面视图的情况下拍照?

  2. 有没有不依赖异步回调的拍照方式?可以把所有代码都放在Activities onResume()方法中拍照吗?

  3. 有没有办法让 Activity 的 onResume() 方法运行足够长的时间,以便相机的预览有足够的时间来初始化和调用所有侦听器?

我正确使用了唤醒锁,并且我在清单文件中正确设置了所有权限。我的活动没有保持足够长的时间让异步侦听器正常工作。

为了使问题更加复杂,我正在尝试保持所有 Android 1.6 兼容,因为这是我可以访问的唯一测试设备。

这是令人沮丧的事情!

4

3 回答 3

8

我现在终于到了某个地方。

我必须使用这两个标志创建一个唤醒锁

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

然后设备唤醒,并从键盘保护屏幕开始。

但是我可以通过键盘保护屏幕并拍照的唯一方法是在活动窗口上使用这些标志:

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

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

于 2011-03-07T19:23:37.407 回答
2

您还可以使用以下命令禁用 Keyguard 屏幕

KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
km.newKeyguardLock(TAG).disableKeyguard();

前提是您具有 DISABLE_KEYGUARD 权限。

这从 API 级别 1 开始可用。

于 2011-03-29T16:43:09.447 回答
0

你在你的 onResume 方法中做这样的事情吗

.... onResume() {
    ....
    WakeLock myWakeLock = .....;
    ...
}

如果是这样,只要方法退出,WakeLock 就会被释放,并且设备可以自由地做任何想做的事情(这可能会重新进入睡眠状态),您需要将 WakeLock 存储在类中的某个地方,不作为本地功能。

于 2011-03-07T03:05:44.800 回答