jjzjj

android - Android的NFC前台派发系统有bug吗?

coder 2023-12-22 原文

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

我的具体情况:Activity A是MainActivity,使用前台dispatch。一切正常。但是,在我从浏览器启动的 Activity B 中(VIEW 操作),前台调度在某些情况下不再起作用。

工作流程:

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

  • 我启动 MainActivity 并再次关闭它。之后我切换
    到浏览器,启动 Activity 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);
    }
}

这些方法在每个 Activity 的相应方法中被调用。感谢您的帮助!

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

  • 从非 Activity 上下文调用的 startActivity;强制 Intent.FLAG_ACTIVITY_NEW_TASK 用于:Intent

我在 Stackoverflow 上发现了其他问题,那里的人们对 NotificationManager 有同样的问题,但所有提示都没有帮助我。将标志 singleTask 添加到我的 Activity B 对我有用,但老实说我不明白,因为上下文始终是一个 Activity 。

我从 MainActivity 中删除了所有代码,但第一个场景仍然无法正常工作。我从 list 中删除了 MainActivity,之后一切都很好。也许这是一个问题,一个应用程序实例正在运行并且 Activity B 是从浏览器启动的?我不知道。

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

最佳答案

您传递给 enableForegroundDispatchIntentFilter[] 是空的。因此,由于 list 文件中的 IntentFilter,您的 NFC Intent 可能会到达您的 Activity 。这解释了您观察到的行为,因为 NFC Intent 在以这种方式交付时总是会创建一个新实例。

在您的代码中添加类似这样的内容以启用前台调度:

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);

并将其作为参数传递给 enableForegroundDispatch

更新: 我最近了解了更多关于这个具体问题的信息。这是由 Android 确定应在哪个任务中启动新 Activity 的方式引起的。我不知道或不明白它是如何工作的具体细节,但效果是这样的:

  1. 当 Activity B 从浏览器启动时,它在浏览器的任务中创建
  2. 当NFC intent到达时,系统决定在Activity A的任务中创建一个新的Activity B

因为2.,SINGLE_TOP没有被忽略:A的任务顶部只有一个Activity B的实例。当 Activity A 关闭时,它的任务已经消失,因此 Activity B 将始终在浏览器的任务中创建,正如您所观察到的。

在这种情况下,您可能会觉得这是一个 Android 错误(我认为是这样),但是这种如何在其中创建任务的 Activity 的行为对于 Android 来说是如此基础,以至于许多应用程序都依赖它。因此,这种情况不太可能改变。

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

关于android - Android的NFC前台派发系统有bug吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10278881/

有关android - Android的NFC前台派发系统有bug吗?的更多相关文章

  1. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  2. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  3. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  4. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  5. ruby - 在没有基准或时间的情况下用 Ruby 测量用户时间或系统时间 - 2

    因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实

  6. ruby - 以毫秒为单位获取当前系统时间 - 2

    在Ruby中,以毫秒为单位获取自纪元(1970)以来的当前系统时间的正确方法是什么?我试过了Time.now.to_i,好像不是我想要的结果。我需要结果显示毫秒并且使用long类型,而不是float或double。 最佳答案 (Time.now.to_f*1000).to_iTime.now.to_f显示包含十进制数字的时间。要获得毫秒数,只需将时间乘以1000。 关于ruby-以毫秒为单位获取当前系统时间,我们在StackOverflow上找到一个类似的问题:

  7. ruby-on-rails - 如何构建复杂的 Rails 系统 - 2

    关闭。这个问题需要更多focused.它目前不接受答案。想改进这个问题吗?更新问题,使其只关注一个问题editingthispost.关闭8年前。Improvethisquestion我们有以下(以及更多)系统,我们将数据从一个应用推送/拉取到另一个:托管CRM(InsideSales.com)Asterisk电话系统(内部)横幅广告系统(openx,我们托管)潜在客户生成系统(自行开发)电子商务商店(spree,我们托管)工作板(本土)一些工作网站抓取+入站工作提要电子邮件传送系统(如Mailchimp,自主开发)事件管理系统(如eventbrite,自主开发)仪表板系统(大量图表和

  8. ruby-on-rails - Rails 3,在RAILS_ROOT上方显示来自本地文件系统的jpg图片 - 2

    我正在尝试找出一种方法来显示来自不在RAILS_ROOT下(在RedHat或Ubuntu环境中)的已安装文件系统的图像。我不想使用符号链接(symboliclink),因为这个应用程序实际上是通过Tomcat部署的,而当我关闭Tomcat时,Tomcat会尝试跟随符号链接(symboliclink)并删除挂载中的所有图像。由于这些文件的数量和大小,将图像放在public/images下也不是一种选择。我查看了send_file,但它只会显示一张图片。我需要在一个格式良好的页面中显示6个请求的图像。由于膨胀,我宁愿不使用Base64编码,但我不知道如何将图像数据与呈现的页面一起传递下去。

  9. ruby - 我可以从 Ruby 中的系统调用中获得连续输出吗? - 2

    当您在Ruby脚本中使用系统调用时,您可以像这样获得该命令的输出:output=`ls`putsoutput这就是thisquestion是关于。但是有没有办法显示系统调用的连续输出?例如,如果您运行此安全复制命令,以通过SSH从服务器获取文件:scpuser@someserver:remoteFile/some/local/folder/...它显示随着下载进度的连续输出。但是这个:output=`scpuser@someserver:remoteFile/some/local/folder/`putsoutput...不捕获该输出。如何从我的Ruby脚本中显示正在进行的下载进度?

  10. u盘安装系统(win10为例) - 2

    下载微PE工具箱进入官网下载微PE工具箱-下载 安装好后,打开微PE工具箱客户端,选择安装PE到U盘 PE壁纸可选择自己喜欢的壁纸,勾选上包含DOS工具箱,个性化盘符图标 下载原版系统进入网站下载镜像NEXT,ITELLYOU如果没有账号,注册一下就好进入选择开始使用选择win10 这里我们选择消费者版,用迅雷把BT种子下载下来 下面的两个盘符,是PE工具箱安装进U盘后,分成的盘符,注意EFI的盘符,这里面不能删东西,也不能添东西,另一个盘符可以当做正常的U盘空间使用,我们现在需要把下载下来的景象文件复制到正常的U盘空间中去 这个时候我们的系统U盘就只做好了 安装系统我们将U盘插入电脑,开机,

随机推荐