2

我想让我的应用程序进入睡眠状态,然后在设定的时间唤醒它。我让它睡觉,但没有醒来。

这将设置唤醒锁:

private void setWakeLock(){
    System.out.println("wakelock");
    PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
    wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
            PowerManager.ACQUIRE_CAUSES_WAKEUP
            | PowerManager.ON_AFTER_RELEASE, "DoNotDimScreen");
    wl.acquire();
}

这会设置唤醒/睡眠时间的警报:

private void setWakeSleep(){
    java.util.Calendar c = java.util.Calendar.getInstance();
    c.set(java.util.Calendar.HOUR_OF_DAY, 17);
    c.set(java.util.Calendar.MINUTE, 53);
    c.set(java.util.Calendar.MILLISECOND, 0);
    Intent sleepIntent = new Intent("SLEEP_INTENT");
    PendingIntent sleepPendingIntent = PendingIntent.getBroadcast(this, 0, sleepIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), sleepPendingIntent);

    c.set(java.util.Calendar.HOUR_OF_DAY, 18);
    c.set(java.util.Calendar.MINUTE, 14);
    c.set(java.util.Calendar.MILLISECOND, 0);
    Intent wakeIntent = new Intent("WAKE_INTENT");
    PendingIntent wakePendingIntent = PendingIntent.getBroadcast(this, 0, wakeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager alarmManager2 = (AlarmManager) getSystemService(ALARM_SERVICE);
    alarmManager2.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), wakePendingIntent);
}

这是广播接收器:

private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Time updateHour = new Time();
        updateHour.set(System.currentTimeMillis());         
        if (intent.getAction().equals("SLEEP_INTENT")) {
            System.out.println("sleep");
            wl.release();
        }
        if (intent.getAction().equals("WAKE_INTENT")) {         
            wl.acquire();
            System.out.println("wake");
            //initialise();
        }
    }
};

非常感谢任何帮助!

4

2 回答 2

8

首先,您不想要唤醒锁;这些是为了防止设备进入睡眠状态,这是高度反社会的,除非你的应用真的需要它(它会耗尽电池)。

其次,如果您在 18:14 之后调用设置唤醒时间的代码将失败,因为您现在将定义过去的时间。让我们暂时忽略它。

接下来,您的意图操作应该类似于“org.user1797190.WAKE_INTENT”,而不仅仅是可能导致冲突的“WAKE_INTENT”。如果您希望公开此意图,请考虑在http://openintents.org进行注册。不过,这也不是你的问题。

您不需要alarmManager2——系统中只有一个警报管理器,所以只需重新使用第一个。

我从来没有听说过让应用程序本身进入“睡眠”状态。您的意思是您希望该应用程序消失,然后稍后再回来?

这就是我要做的。完全忘记“SLEEP_INTENT”。只需安排一个“WAKE_INTENT”,然后调用finish()。您的应用程序将简单地离开屏幕。

我会完全忘记广播接收器。相反,我会使用 getActivity() 而不是 getBroadcast() 来获取将重新启动活动的待处理意图。修改您的清单,以便您的 WAKE_INTENT 将进入活动。此外,您应该将“android:launchMode”属性设置为“singleTask”,这样就不会创建活动的多个实例。onNewIntent()如果您的活动在到达时已经在运行,您还需要实施以处理唤醒意图。

最后,如果您的活动是创建意图的同一应用程序的一部分,则根本不需要命名意图;您可以按类创建它们。不过,您需要另一种方法让接收者知道这是一个唤醒意图。

所以,把它们放在一起:

您的清单应包含:

<activity android:name=".TestActivity" android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

您的代码应包含:

/**
 * Arrange for the activity to return at a specific time.
 * Call finish() after calling this method().
 * This function can be called from anywhere that has a valid Context.
 */
public static void scheduleWakeup(Context ctx, long timeMillis) {
    if (DEBUG) Log.d(TAG, "Scheduling wakeup for " + timeMillis);
    Intent intent = new Intent(ctx, TestActivity.class);
    intent.putExtra("wakeup", true);
    PendingIntent pi = PendingIntent.getActivity(ctx, 0, intent,
                          PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager mgr = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
    mgr.cancel(pi);    // Cancel any previously-scheduled wakeups
    mgr.set(AlarmManager.RTC_WAKEUP, timeMillis, pi);
}

...

protected void onCreate(Bundle state) {
    Intent intent = getIntent();
    if (intent.getBooleanExtra("wakeup", false)) {
        // We were woken up by the alarm manager
    }
    ...
}

protected void onNewIntent(Intent intent) {
    if (intent.getBooleanExtra("wakeup", false)) {
        // We were woken up by the alarm manager, but were already running
    }
}

这与我在自己的应用程序中所做的非常接近,而且对我来说效果很好。

当然,您必须自己进行测试。Log.d() 是你的朋友。

于 2012-12-03T19:11:42.833 回答
0

如上。问题是我在调用活动中使用了广播接收器。

于 2012-12-03T19:52:09.377 回答