无法在Android 5.0 Lollipop上取消/隐藏闹钟图标。

5
自从Android Lollipop 5.0(API21)发布以来,现在有一个官方API可以显示/隐藏闹钟图标。关于此问题,在stackoverflow上有更多信息,请点击这里
由于这个API的帮助,我现在可以在5.0+的Android设备上显示闹钟图标。不幸的是,如果闹钟被禁用,我无法解除/隐藏/取消该图标。
以下是我的操作步骤(结合了stackoverflow和Android自带闹钟的几个尝试):
public static void setNextAlert(final Context context) {

final Alarm alarm = calculateNextAlert(context);

AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(ALARM_ALERT_ACTION);

PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

int flags = alarm == null ? PendingIntent.FLAG_NO_CREATE : 0;
PendingIntent operation = PendingIntent.getBroadcast(context, 0 /* requestCode */,  intent, flags);


if (alarm != null) 
{
    if(UtilsAlarm.isLollipopOrLater())
    {
        PendingIntent viewIntent = PendingIntent.getActivity(context, alarm.id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager.AlarmClockInfo info = new AlarmManager.AlarmClockInfo(alarm.time, viewIntent);
        am.setAlarmClock(info, operation);
    }
    else
    {
        if(UtilsAlarm.isKitKatOrLater())
        {
            am.setExact(AlarmManager.RTC_WAKEUP, alarm.time, sender);
        }
        else
        {   
            am.set(AlarmManager.RTC_WAKEUP, alarm.time, sender);
        }
        
        setStatusBarIcon(context, true);
    }
    
    Calendar c = Calendar.getInstance();
    c.setTimeInMillis(alarm.time);
    String timeString = formatDayAndTime(context, c);
    saveNextAlarm(context, timeString);
} 
else 
{
    if(UtilsAlarm.isLollipopOrLater())
    {
        am.cancel(operation);
    }
    else
    {
        am.cancel(sender);
        setStatusBarIcon(context, false);
    }

    saveNextAlarm(context, "");
}

Intent i = new Intent(NEXT_ALARM_TIME_SET);
context.sendBroadcast(i); }

如果我们的设备版本低于Android 5.0(棒棒糖),则它仍然能很好地工作。但是,对于使用Android 5.0及以上版本的设备,当启用闹钟时会显示图标,但是如果您将其禁用(且未启用其他闹钟),则该闹钟被取消,但通知栏中的图标仍然存在(预期结果)。有人对此问题有什么想法吗?
谢谢您的帮助。

这看起来是正确的,听起来像是一个 bug。你在多个 5.x 设备上测试过吗?文档中说“系统可能选择向用户显示有关此警报的信息”,这表明对我来说它可能是硬件制造商的实现细节。 - Adam S
感谢Adam的评论。我按照他的建议尝试了并且向几个使用不同5.X设备的人询问,结果都一样:图标仍然显示。 - MatrixAndroidLife
你尝试过在创建和取消时使用相同的标志吗?目前你正在使用0标志进行创建,而使用FLAG_NO_CREATE进行取消。 - Adam S
是的,事实上我一开始也使用了相同的标志,然后改用了Lollipop Android股票闹钟中使用的方法在这里(第43行)。 - MatrixAndroidLife
2个回答

2
您的问题在于这行代码:int flags = alarm == null ? PendingIntent.FLAG_NO_CREATE : 0; 您告诉系统将null赋给PendingIntent operation,因为在上一次进入此方法时已经存在相应的意图(请参见FLAG_NO_CREATE文档)。
稍后当您调用am.cancel(operation);时,它根本没有任何效果,因为operation == null。您的闹钟仍然在系统中注册。当闹钟响起时没有任何反应的唯一原因是您在前一行取消了意图(而不是闹钟):PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);。因此,当您说“它当前从下一个即将到来的闹钟中被取消(预期结果)”时,您的断言是错误的。闹钟没有被取消;只是它的意图被取消了。
我建议您使用FLAG_UPDATE_CURRENT。

1
嗨!感谢您的回答 :) ... 我已经将每个PendingIntent.FLAG_CANCEL_CURRENT更改为PendingIntent.FLAG_UPDATE_CURRENT,现在似乎可以工作了! - MatrixAndroidLife

1

我已经解决了这个问题,将我的广播调用中的PendingIntent.FLAG_CANCEL_CURRENT更改为PendingIntent.FLAG_UPDATE_CURRENT


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