当设备休眠几个小时时警报不会响起(在 Marshmallow 上)

Alarm not going off when device is sleeping for a few hours (on Marshmallow)

我创建了一个简单的闹钟,效果很好,并在用户选择的特定时间显示通知作为简单提醒(如果设备未唤醒,它会播放通知声音)。

但是当我将它用作早上起床的闹钟时,它无法播放通知声音。

很难测试,因为设备必须锁定几个小时。我认为这与打瞌睡有关,但我不确定。此外,如果设备整夜充电,它会正常播放闹钟。

早上手动唤醒设备后,收到通知...

闹钟设置代码:

        // Create an intent that will be wrapped in PendingIntent
        Intent intent = new Intent(getApplicationContext(), AlarmReceiver.class);
        intent.putExtra("id",id);

        // Create the pending intent and wrap our intent
        PendingIntent pendingIntent =
                PendingIntent.getBroadcast(getApplicationContext(),(int)id, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        //get the alarm manager
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        if (android.os.Build.VERSION.SDK_INT >= 19)
        {
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, date.getTime(), pendingIntent);
        }
        else if (android.os.Build.VERSION.SDK_INT >= 23)
        {
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, date.getTime() , pendingIntent);
        }
        else alarmManager.set(AlarmManager.RTC_WAKEUP, date.getTime() , pendingIntent);


        //go back to the main activity
        onBackPressed();

我的报警器:

public class AlarmReceiver extends WakefulBroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
    Log.e("ALARMRECEIVER","ONRECEIVE");

    //Create a notification
    long notificationId = intent.getLongExtra("id", -1);

    if(notificationId == -1)
    {
        Log.e("AlarmReceiver","id went missing");
    }
    else
    {
        NotificationRepository repository = NotificationRepository.getInstance(context);
        Notification notification = repository.getNotification(notificationId);


        if(notification != null)
        {
            String[] icons = context.getResources().getStringArray(R.array.icons);
            int iconId = context.getResources().getIdentifier(context.getPackageName()
                    + ":drawable/" + icons[notification.getIconIndex()], null, null);

            //create the android notification
            NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
                    .setSmallIcon(iconId)
                    .setContentTitle(notification.getTitle())
                    .setContentText(notification.getSubtitle())
                    .setColor(ContextCompat.getColor(context, R.color.colorPrimary));

            if(notification.isPlaySound())
            {
                mBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
                Log.e("ALARMRECEIVER", "SOUND");
            }
            else Log.e("ALARMRECEIVER","NO SOUND");

            if (notification.isVibrate())
            {
                mBuilder.setVibrate(new long[]{1000, 1000});
            }

            NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            // mId allows you to update the notification later on.
            mNotificationManager.notify((int) notificationId, mBuilder.build());
            //Delete the notification from the database
            repository.removeNotification(notificationId);

            Intent i = new Intent("dvanack.gmail.com.NOTIFY");
            context.sendBroadcast(i);
            AlarmReceiver.completeWakefulIntent(intent);
            Log.w("ONRECEIVE","ENDED");
        }

    }

}

我认为您在使用 Marshmallow 及更高版本时遇到了这个问题。

下面的代码似乎有问题:

 if (android.os.Build.VERSION.SDK_INT >= 19)
    {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, date.getTime(), pendingIntent);
    }
    else if (android.os.Build.VERSION.SDK_INT >= 23)
    {
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, date.getTime() , pendingIntent);
    }

此处..."else if" 无法访问,因为如果 android 版本是 marshmallow,它将再次进入第一个 if 条件,因为版本 >=19。希望这能解决问题。

所以条件应该是:

if (android.os.Build.VERSION.SDK_INT >= 23)
{
    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, date.getTime() , pendingIntent);
}
else if (android.os.Build.VERSION.SDK_INT >= 19)
{
     alarmManager.setExact(AlarmManager.RTC_WAKEUP, date.getTime(), pendingIntent);
}