Android Alarmmanager 通知在长时间空闲后不出现

Android Alarmmanager Notifications Not Appearing After Long Idle Periods

几周来我一直在努力解决这个问题。基本问题是,在设备长时间(8 小时)闲置后,计划的通知将不会激活。在测试中,我一直在使用两台设备,一台 LG Optimus Elite 和一台三星 Galaxy Note S4。在 Optimus Elite 上,通知会在设备被唤醒时发生,但在 Note 上,通知会完全消失并且永远不会显示。整个系统在设备处于唤醒状态或短时间不活动后工作。

public class AlarmReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    try {
        WakeLocker.acquire(context);
        Bundle bundle = intent.getExtras();
        Intent i = new Intent(context, AlarmService.class);
        i.putExtra("name", bundle.getString("name"));
        i.putExtra("alarm", bundle.getString("alarm"));
        context.startService(i);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

**public class AlarmService extends Service {

LocalBroadcastManager broadcaster;
static final public String REFRESH_INTENT = "rf";

@Override
public IBinder onBind(Intent arg0)
{
    // TODO Auto-generated method stub
    return null;
}

public void handleIntent(Intent intent){
    broadcaster = LocalBroadcastManager.getInstance(this);
    Bundle bundle = intent.getExtras();
    String message = bundle.getString("alarm");
    if(message.equals("dosesTakenResetAlarm")){
        dailyReset(getApplicationContext());
    }
    else if(message.equals("scheduledReminder")){
        scheduledReminder(bundle.getInt("code", 0), bundle.getString("name"), getApplicationContext());
    }
    WakeLocker.release();
}

public void onStart(Intent intent, int startId){
    handleIntent(intent);
}

public int onStartCommand(Intent intent, int flags, int startId){
    handleIntent(intent);
    return START_NOT_STICKY;
}

@Override
public void onDestroy()
{
    // TODO Auto-generated method stub
    super.onDestroy();
    WakeLocker.release();
}

private void dailyReset(Context context){
    FileWriter fw = new FileWriter(context);
    AlarmCreator ac = new AlarmCreator();
    fw.fp.onloadString(fw.readFromFile());
    int medNum = 0;
    while(fw.fp.hasNext()){
        SaveData mv = fw.readEntry(medNum);
        fw.fp.onloadMedString(mv.data);
        String name = fw.fp.nextMedVariable();
        String doses = fw.fp.nextMedVariable();
        String frequency = fw.fp.nextMedVariable();
        String frequencyS = fw.fp.nextMedVariable();
        String reminders = fw.fp.nextMedVariable();
        String dosesT = fw.fp.nextMedVariable();
        frequencyS = ""+(Integer.parseInt(frequencyS)-1);
        if(Integer.parseInt(frequencyS) < 0){
            frequencyS = ""+(Integer.parseInt(frequency)-1);
        }
        fw.replaceEntry(fw.fp.buildMedSaveString(name, doses, frequency, frequencyS, reminders, "0"), mv.position1, mv.position2);
        if(frequencyS.equals("0")){
            fw.fp.onloadReminderString(reminders);
            int reminderNum = 0;
            while(fw.fp.hasNextReminder()){
                ReminderData temp = fw.fp.nextReminder();
                if(temp.half.equals("1")){
                    temp.hour = ""+(Integer.parseInt(temp.hour)+12);
                }
                ac.setAlarm(Integer.parseInt(temp.hour), Integer.parseInt(temp.minute), 0, ac.buildAlarmCode(medNum, reminderNum), name);
                reminderNum++;
            }
        }
        medNum++;
        fw.fp.nextMedication();
    }

    Intent intent = new Intent(REFRESH_INTENT);
    broadcaster.sendBroadcast(intent);
}

private void scheduledReminder(int code, String n, Context context){
    Intent intent = new Intent(context, Main.class);
    PendingIntent pIntent = PendingIntent.getActivity(context, 101, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(context)
                    .setSmallIcon(R.drawable.deleted)
                    .setContentTitle("Pillbud Reminder")
                    .setContentText("Take a dosage of "+n+".");
    mBuilder.setDefaults(Notification.DEFAULT_ALL);
    mBuilder.setContentIntent(pIntent);
    mBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
    NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    mNotifyMgr.notify(code, mBuilder.build());
}

}**

此外,如果有人对如何诱导这种睡眠状态有任何建议,那将对测试非常有帮助。

您需要获取唤醒锁。看看 WakefulBroadcastReceiver, or CommonsWare Guy's WakefulIntentService

关于让设备休眠,如果你有root,那么adb shell进去,获取root然后输入:

  echo standby > /sys/power/state

有更多关于电源状态的信息here

如果您没有 root,那么在 PowerManagergoToSleep 上调用应该可以。您需要授予调用应用 DEVICE_POWER 权限