【问题标题】:Is it possible to read an NFC tag from a card without using an intent?是否可以在不使用意图的情况下从卡中读取 NFC 标签?
【发布时间】:2021-11-03 13:41:24
【问题描述】:

我正在使用 Kotlin 构建一个 Android 应用。我应该能够通过单击按钮来读取 NFC 标签。在我阅读的所有文档中,我看不到这样做的方法。

通常情况:在 Android 设备旁边设置 NFC 令牌(卡、芯片等)。设备会自动打开 NFC 应用程序。这时候就会发现intent,读卡。

但是我怎样才能在应用程序中,将令牌放在设备附近,然后单击“读取”按钮,然后才从令牌中读取信息?

【问题讨论】:

    标签: android kotlin nfc ndef


    【解决方案1】:

    答案是肯定的和否定的,您可以在不使用意图的情况下读取卡片,但这无助于您在单击按钮时阅读,但其他更改意味着您只能在单击按钮时读取标签。

    你没有展示你如何获得意图的现有代码或描述你正在阅读的数据类型,所以答案会有点模糊。

    需要澄清的一点是,标签检测始终由进入范围的标签启动,这始终是代码与标签交互的起点,但您可以将读取与标签检测分开。

    So“检测并存储”方法

    要做的第一件事是使用enableReaderMode 在标签在范围内时获取回调。

    例如

    public class NFCActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback{
    
    private NfcAdapter mNfcAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_nfc);
    
            mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
    
            // Rest of Activity setup
         }
    
    @Override
        protected void onResume() {
            super.onResume();
    
            if(mNfcAdapter!= null) {
                Bundle options = new Bundle();
                // Work around for some broken Nfc firmware implementations that poll the card too fast
                options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 250);
    
                // Enable ReaderMode for all types of card and disable platform sounds
                mNfcAdapter.enableReaderMode(this,
                        this,
                        NfcAdapter.FLAG_READER_NFC_A |
                                NfcAdapter.FLAG_READER_NFC_B |
                                NfcAdapter.FLAG_READER_NFC_F |
                                NfcAdapter.FLAG_READER_NFC_V |
                                NfcAdapter.FLAG_READER_NFC_BARCODE |
                                NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK |
                                NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS,
                        options);
            }
    
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            if(mNfcAdapter!= null)
                mNfcAdapter.disableReaderMode(this);
        }
    
    

    标签检测声音关闭,系统自动读取任何NDEF消息也关闭(因此用户不知道标签检测)

    然后在onTagDiscovered 回调方法中,您只需存储它提供给您的Tag 对象,以供您稍后按下按钮时使用。

    当您读取标签时,您使用存储的Tag 对象并将其转换为标签技术类型之一

    例如

    Ndef mNdef = Ndef.get(tag);
    
    // Check that it is an Ndef capable card
    if (mNdef!= null) {
     NdefMessage mNdefMessage = mNdef.getNdefMessage();
    }
    
    

    您还必须处理一些异常,因为没有保证当您按下按钮时标签仍在范围内。

    在您单击按钮之前,您不能真正延迟启用检测,因为如果您没有要求在检测到正在运行的应用程序时向其发送回调,那么系统很可能会使用该标签执行某些操作。

    【讨论】:

    • 非常感谢您的回答。您看起来像这里的 NFC 大师:所以我想请您跟进一下。你知道我如何从 MainActivity 读取 NFC 标签,同时在各种 Fragment 上吗?我想正确的方法是使用 LiveData,但是,如果我远离 MainActivity(已调用 onPause),则 nfcAdapter 已被禁用。我不知道该怎么做。
    • @James 当您在 Activity 中托管 Fragments 时,当您在 Fragments 之间交换时,Activity 不会暂停(每个 Fragment 都可以暂停和恢复,但 Activity 不会 - 我的一个应用程序启用了 enableReaderMode main Activity,然后在 ViewPager 中显示 3 个 Fragments,交换 Fragments 不会影响 NFC 处理)。在 Activity 中处理 NFC 检测后,您可以通过任何正常的 Fragment 通信方法将结果传达给 Fragment,例如接口、共享视图模型等
    • 非常感谢您的宝贵帮助。
    猜你喜欢
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多