Android PendingIntent FLAG_NO_CREATE 不返回 null

Posted

技术标签:

【中文标题】Android PendingIntent FLAG_NO_CREATE 不返回 null【英文标题】:Android PendingIntent FLAG_NO_CREATE does not return null 【发布时间】:2014-04-09 18:16:36 【问题描述】:

我在使用 PendingIntents 时遇到了一些问题。每次打开我的应用程序时,它都会安排一些广播。 我的问题是无法识别已经存在的 PendingIntents。

我知道 PendingIntents 和 uninterlaying Intents 必须使用相同的参数创建。

她是我的代码...在我的 Launcher Activity 中作为 Asynctask 启动。

        long nextExecute = getNextExecute(t);

        if (nextExecute > System.currentTimeMillis()) 

            int tt = 12;

            intent = new Intent(context, BirthExecutor.class);
            intent.putExtra(Target.ROW_ID, tt);

            PendingIntent pending = PendingIntent.getBroadcast(context, 10, intent, PendingIntent.FLAG_NO_CREATE);

            if (pending != null) 

                manager.set(AlarmManager.RTC_WAKEUP, nextExecute, pending);

                BirthLog log = new BirthLog("Scheduled " + t.getFirstname() + " " + t.getLastname() + " on " + df.format(nextExecute));
                log_helper.insertLog(log);

             else 

                BirthLog log = new BirthLog(t.getFirstname() + " " + t.getLastname() + " already active!");
                log_helper.insertLog(log);

            

            intent = new Intent(LogAdapter.LOG_RECEIVE_ACTION);
            context.sendBroadcast(intent);

        

每次执行完全相同的代码,但为什么挂起的变量不为空?它一定要是 !!! 我对 requestId 进行了硬编码,putExtra 也是硬编码的。

编辑

我有另一个功能来更新这个时间表。 只有当我执行该函数时,PendingIntents 才不再被识别。我尝试使用相同的上下文对象作为静态引用,但也失败了。

public void updateTask(Target t) 

    if (t.getTime() == null || t.getRow() == null)
        return;

    Intent intent;
    SimpleDateFormat df = new SimpleDateFormat("HH:mm dd.MM.yyyy", Locale.US);

    long nextExecute = getNextExecute(t);

    if (nextExecute > System.currentTimeMillis()) 

        intent = new Intent(static_context, BirthExecutor.class);
        intent.putExtra(Target.ROW_ID, 12);

        PendingIntent pending = PendingIntent.getBroadcast(static_context, 10, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        if (pending != null) 

            manager.set(AlarmManager.RTC_WAKEUP, nextExecute, pending);

            BirthLog log = new BirthLog("Scheduled " + t.getFirstname() + " " + t.getLastname() + " on " + df.format(nextExecute));
            log_helper.insertLog(log);
            Log.d("birth", log.getComment());

         else 

            BirthLog log = new BirthLog(t.getFirstname() + " " + t.getLastname() + " ERROR. TIME: " + df.format(nextExecute));
            log_helper.insertLog(log);
            Log.d("birth", log.getComment());

        

        intent = new Intent(LogAdapter.LOG_RECEIVE_ACTION);
        static_context.sendBroadcast(intent);

    


编辑 2

好的,如果该挂起意图已被调度,则返回非空结果是有意义的。 我已经更改了我的代码。每次我旋转手机时,都会触发主要活动 onCreate 并执行调度 asynctask。但结果始终为空?!?!如果已经有预定的pendingintent,它应该是一个非空的结果,对吧?

@Override
protected Void doInBackground(Void... params) 

    Intent intent;
    SimpleDateFormat df = new SimpleDateFormat("HH:mm dd.MM.yyyy", Locale.US);

    for (Target t : target_helper.getAllTarget()) 

        long nextExecute = getNextExecute(t);

        if (nextExecute > System.currentTimeMillis()) 

            PendingIntent pending = getPendingIntent(context, t, false);

            if (pending != null) 

                BirthLog log = new BirthLog(t.getFirstname() + " " + t.getLastname() + " already active!");
                log_helper.insertLog(log);

             else 

                manager.set(AlarmManager.RTC_WAKEUP, nextExecute, pending);

                BirthLog log = new BirthLog("Scheduled " + t.getFirstname() + " " + t.getLastname() + " on " + df.format(nextExecute));
                log_helper.insertLog(log);

            

            intent = new Intent(LogAdapter.LOG_RECEIVE_ACTION);
            context.sendBroadcast(intent);

        

    

    return null;



private PendingIntent getPendingIntent(Context context, Target t, boolean update) 

    Intent intent = new Intent(context, BirthExecutor.class);
    intent.putExtra(Target.ROW_ID, t.getRow());

    if (update) 
        return PendingIntent.getBroadcast(context, t.getRow().intValue(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
     else 
        return PendingIntent.getBroadcast(context, t.getRow().intValue(), intent, PendingIntent.FLAG_NO_CREATE);
    


【问题讨论】:

【参考方案1】:

文档不正确。如果在调用PendingIntent.getBroadcast() 时使用PendingIntent.FLAG_NO_CREATE,它将返回null 如果没有找到匹配的PendingIntent。否则它将返回匹配的PendingIntent

文档说是相反的,但这是错误的:-(

【讨论】:

天哪,如果真的是那样 grrr ...我会看看...谢谢;) 其实,如果你想了几秒钟以上,很明显如果有匹配的null返回null,如果没有匹配则返回non-null。不是,因为通过设置 FLAG_NO_CREATE,您已经表明您不希望 android 创建新的 PendingIntent。它应该作为非空结果返回什么? 你解决了吗?我面临着完全相同的问题【参考方案2】:

系统完全按照文档中的说明进行操作:

int FLAG_NO_CREATE

Flag 表示如果描述的 PendingIntent 不存在,然后简单地返回 null 而不是创建 它。

话虽如此,如果我不想开始我的任务,如果它已经在运行,我会这样做:

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_NO_CREATE);
if (pendingIntent == null) 
    pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    // start it only it wasn't running already
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10 * 60 * 1000, pendingIntent);

【讨论】:

以上是关于Android PendingIntent FLAG_NO_CREATE 不返回 null的主要内容,如果未能解决你的问题,请参考以下文章

Android中pendingIntent的深入理解

Android中pendingIntent的深入理解

什么是 Android PendingIntent?

什么是 Android PendingIntent?

Android PendingIntent的使用

Android 位置:PendingIntent 与 LocationListener