Android的NFC前台调度系统是否有错误?

时间:2012-04-23 10:32:39

标签: android android-activity nfc foreground dispatch

我对前台调度行为有一个恼人的问题。有时它不会调用onNewIntent(),而是完全重新创建活动,这会破坏应用程序的工作流程。

我的具体情况:活动A是MainActivity,它使用前台调度。一切都按预期工作。但是,在我从浏览器启动的活动B(VIEW操作)中,前台调度在某些情况下不再起作用。

工作流程:

  • 我启动MainActivity,切换到浏览器(不关闭 MainActivity),启动活动B并连接我的NFC设备 - >它 创建一个新活动B.

  • 我启动MainActivity并再次关闭它。之后我切换了 到浏览器,启动活动B并连接我的NFC设备 - > 一切都适用于onNewIntent()

代码是正确的,例如如果我在第一个场景中连接NFC设备两次,它会在第二次工作,但不是第一次。在MainActivity和activity B中,我最终在activity的onPause()方法中调用disableForegroundDispatch()方法。

我的具体问题是否有解决方案?对我来说,这听起来像个错误。

修改:

public void resume(Activity targetActivity) {
    if (nfc != null && nfc.isEnabled()) {
        // nfc is the default NFC adapter and never null on my devices

        Intent intent = new Intent(targetActivity, targetActivity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(targetActivity, 0, intent, 0);
        nfc.enableForegroundDispatch(targetActivity, pendingIntent, null, new String[][] { new String[] { IsoDep.class.getName() } });
    }
}

public void pause(Activity targetActivity) {
    if (nfc != null && nfc.isEnabled()) {
        nfc.disableForegroundDispatch(targetActivity);
    }
}

在每个活动的相应方法中调用这些方法。谢谢你的帮助!

解决方案:经过长时间的研究,我终于找到了问题。 Logcat打印:

  • 从非活动上下文调用的startActivity;强制Intent.FLAG_ACTIVITY_NEW_TASK:意图

我在Stackoverflow上发现了其他问题,人们对NotificationManager有同样的问题,但所有提示都没有帮助我。将标志singleTask添加到我的活动B为我做了伎俩,但说实话我不理解它,因为上下文总是一个活动。

我从MainActivity中删除了所有代码,但第一个方案仍无效。我从清单中拿出了MainActivity,然后一切都很好。也许这是一个问题,一个app实例正在运行,活动B是从浏览器启动的?我不知道。

无论如何,感谢NFC人的帮助!

2 个答案:

答案 0 :(得分:2)

您传递给IntentFilter[]的{​​{1}}为空。因此,由于清单文件中的IntentFilter,您的NFC意图可能会到达您的Activity。这解释了您观察到的行为,因为NFC意图总是以这种方式创建新实例。

将类似内容添加到您的代码中以启用前台调度:

enableForegroundDispatch

并将其作为参数传递给IntentFilter[] iFilters = new IntentFilter[2]; iFilters[0] = new IntentFilter(); iFilters[0].addAction("android.nfc.action.TECH_DISCOVERED"); iFilters[1] = new IntentFilter(); iFilters[1].addAction("android.nfc.action.TAG_DISCOVERED"); iFilters[1].addCategory(Intent.CATEGORY_DEFAULT);

更新: 我最近了解了这个具体问题。这是由Android确定应在哪个任务中启动新活动的方式引起的。我不知道或不了解其工作原理的具体细节,但结果是:

  1. 当从浏览器启动活动B时,它将在浏览器的任务中创建
  2. 当NFC意图到来时,系统确定要在活动A的任务中创建新的活动B
  3. 由于2.,不会忽略SINGLE_TOP:A的任务顶部只有一个活动B实例。当活动A关闭时,它的任务已经消失,因此活动B将始终在浏览器的任务中创建,正如您所观察到的那样。

    在这种情况下,您可能会觉得这是一个Android错误(我想,我认为),但这种行为如何创建活动,其中任务对于Android来说非常重要,许多应用依赖它。所以这种情况不太可能发生变化。

    可能的解决方法:使用enableForegroundDispatch“singleTask”(或“singleInstance”)声明活动B.然后,在启动B时将创建新的(第3个)任务。

答案 1 :(得分:0)

我猜您的工作流程如下:主要 - >检测标签 - >读者活动 - >作家活动检测标签 - >写标签

当您的编写器活动(启用了前台的活动,我认为是出于编写目的)属于从先前的标记发现中调用的活动堆栈(例如,任务)时,似乎会出现此问题。

特别是,如果您的工作流程如下,则不会出现此问题: 主要作家活动检测标签 - >写标签

我的解决方法是在新任务中调用编写器活动。 在laucnhes writer的活动中,只需在启动writer的intent中添加新的任务标志。

startActivity(new Intent(this,MyTagWriterActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));

主要 - >检测标签 - >读者活动-NEW_TASK->作家活动检测标签 - >写标签

它确实搞乱了活动历史,但却使作家活动更具可预测性。