PowerManager.newWakeLock() 抛出非法参数异常。

3

我试图获取一个唤醒锁,但是当我调用PowerManager.newWakeLock()时,我收到了一个非法参数异常。

这里是我用来获取锁的代码:

private void setWakeLock(Context context)
{
    PowerManager pm = (PowerManager) context
    .getSystemService(Context.POWER_SERVICE);
    SoundAlarmActivity.WakeLock = pm.newWakeLock(
    PowerManager.ACQUIRE_CAUSES_WAKEUP
            | PowerManager.ON_AFTER_RELEASE, "Alarm");
    SoundAlarmActivity.WakeLock.acquire();
}

以下是logcat日志:

09-28 12:53:09.704: ERROR/AndroidRuntime(702): java.lang.IllegalArgumentException
09-28 12:53:09.704: ERROR/AndroidRuntime(702):     at android.os.PowerManager$WakeLock.<init>(PowerManager.java:223)
09-28 12:53:09.704: ERROR/AndroidRuntime(702):     at android.os.PowerManager.newWakeLock(PowerManager.java:365)
2个回答

15

试试这个:

private void setWakeLock(Context context)
{
    PowerManager pm = (PowerManager) context
    .getSystemService(Context.POWER_SERVICE);
    SoundAlarmActivity.WakeLock = pm.newWakeLock(
    PowerManager.FULL_WAKE_LOCK |
        PowerManager.ACQUIRE_CAUSES_WAKEUP
            | PowerManager.ON_AFTER_RELEASE, "BusSnoozeAlarm");
    SoundAlarmActivity.WakeLock.acquire();
}

PowerManager.ACQUIRE_CAUSES_WAKEUP与部分唤醒锁不兼容,因此您在定义所需唤醒锁的类型时,必须确保使用FULL_WAKE_LOCK。


非常感谢您,我尝试了很多方法,您的解决方案有效 ;) - IgorOliveira
完整的唤醒锁已经被弃用了吗?我怎样才能在没有它的情况下获得相同的行为呢? - Sandra
我介绍了ACQUIRE_CAUSES_WAKEUP并在创建wakelock时遇到了运行时异常,提示“必须指定有效的唤醒锁级别”。我添加了PARTIAL_WAKELOCK,尽管文档中说不应该这样做,但它被接受了。看起来它也似乎起作用了,虽然不能百分之百确认它是否真正起作用,因为很难强制出现需要使用wakelock的情况以证明它真正起作用了。所以,使用PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE - Stephen Hosking

8

您需要定义您想要的唤醒锁的“类型”。您提供的两个标志只是级别的补充:

[WakeLock level] Flag Value | CPU | Screen | Keyboard
-----------------------------------------------------
PARTIAL_WAKE_LOCK           | On* | Off    | Off
SCREEN_DIM_WAKE_LOCK        | On  | Dim    | Off
SCREEN_BRIGHT_WAKE_LOCK     | On  | Bright | Off
FULL_WAKE_LOCK              | On  | Bright | Bright

注意:从API级别17开始,除了PARTIAL_WAKE_LOCK之外,其他wakelock级别已被弃用,您应该使用LayoutParams.FLAG_KEEP_SCREEN_ON代替。

3
请注意,使用ACQUIRE_CAUSES_WAKEUP选项无法与PARTIAL_WAKE_LOCK一起使用。 - Donal Rafferty
3
让我来理一下。如果单独使用ACQUIRE_CAUSES_WAKEUP是不行的,因为你需要定义你想要的“唤醒锁”的类型。如果你不这样做,你会得到一个异常,提示“必须指定有效的唤醒锁级别”。所以你必须从WakeLock级别列表中选择一个。但是,SCREEN_DIM_WAKE_LOCK、SCREEN_BRIGHT_WAKE_LOCK和FULL_WAKE_LOCK已经过时了,你说,好吧,我还有一个剩余的。然后...你意识到,唯一没有过时的那个你也不能用了。那么有没有正确的方法来做这件事呢?FULL_WAKE_LOCK | ACQUIRE_CAUSES_WAKEUP可以很好地工作。 - Sandra
我介绍了ACQUIRE_CAUSES_WAKEUP,并在创建wakelock时遇到了运行时异常,提示“必须指定有效的唤醒锁级别”。我添加了PARTIAL_WAKELOCK,尽管文档中说不需要,但它被接受了。它似乎也起作用了。不能100%确定它是否正常工作并被接受,但看起来是这样。很难强制出现需要wakelock的情况,以证明它实际上正在工作。因此,请使用PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE - Stephen Hosking
1
经过几天的测试和复制需要WakeLock的条件,我相信我的解决方案是有效的。我之前只有一个PARTIAL_WAKELOCK,它在Android 9之前可以工作,但在Android 9上失败了。该应用程序正在尝试从服务启动活动,在这种情况下,手机可能已经休眠数小时。在Android 9中,活动就无法启动。将AQUIRE_CAUSES_WAKEUP和ON_AFTER_RELEASE添加到PARTIAL_WAKE_LOCK中使其再次工作。 - Stephen Hosking

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