gpt4 book ai didi

android - 前台 Activity 中的 NfcAdapter.enableReaderMode 是否应该覆盖 Intent 标签调度系统?

转载 作者:行者123 更新时间:2023-12-04 23:45:25 37 4
gpt4 key购买 nike

在 Android 10 中,我注意到我从操作系统收到一条 Toast 消息,说明“此 NFC 标签不支持应用程序”或“此 NFC 标签不支持应用程序”(取决于设备):

enter image description here

奇怪的是,我在 enableReaderMode 时看到了 Toast。在前台 Activity 中处于 Activity 状态。在所有以前的 Android 版本中,enableReaderMode将覆盖 Android Intent 标签调度系统。这是 Android 10 中的错误吗?

我知道enableForegroundDispatch也存在,即使在 Android 10 中,该 API 似乎也确实覆盖了 Intent 标签调度系统。但我想继续控制仅由 enableReaderMode 提供的 NFC 发现声音。 .

我也知道我可以在 list 中声明一个 Intent 过滤器来摆脱 Toast,同时继续使用 enableReaderMode ,但这也有意想不到的副作用(例如,我的应用程序可能会在从我不想要的设备主屏幕读取 NFC 标签时启动)。

最佳答案

是的,这似乎是一个错误,因为 Android 操作系统会在以下条件下触发一个新的 tagDiscovery 事件:

  • 使用 enableReaderMode 代替 enableForegroundDispatch
  • 读卡或写卡
  • 虽然卡仍处于近距离调用 disableReaderMode。

  • 由于这会触发操作系统级别的事件,因此它可以暂停重点 Activity ,可能会显示 toast 屏幕或显示相关的应用程序选择框。
    要解决该问题,
    解决方法 1:
  • 尝试循环连接卡,直到触发 IOException。 (这意味着卡不再靠近)
  • 然后调用 disableReaderMode

  • 缺点:您可能需要向用户显示一条消息,以从设备附近移除标签/卡。
    解决方法 2:
  • 使用旧版 enableForegroundDispatch/disableForegroundDispatch 和 readerMode

  • 缺点:不会显示弹出窗口,但仍会触发标签发现声音。
    两种解决方案都不需要定义 Intent 过滤器。
    下面是实现这两种解决方法的示例代码。
    import android.app.PendingIntent;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.nfc.NfcAdapter;
    import android.nfc.Tag;
    import android.nfc.tech.IsoDep;
    import android.os.Bundle;
    import android.widget.Toast;

    import java.io.IOException;

    import androidx.appcompat.app.AppCompatActivity;

    public class MainActivity extends AppCompatActivity
    {
    private NfcAdapter nfcAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);

    //Assuming nfc adapter is present and active, such checks are ignored for code clarity,
    //production code must check for hardware nfc adapter existence
    nfcAdapter = NfcAdapter.getDefaultAdapter(this); //Get the default NFC adapter from OS

    //Additional initialization code
    }

    private void onTagDiscovered(Tag tag)
    {
    try
    {
    if (tag == null)
    return;

    //Assumption: We're using an NFC card that supports IsoDep
    IsoDep iso = IsoDep.get(tag);

    if (iso == null)
    return;

    iso.setTimeout(1000);
    iso.connect();

    //doCardReadWrite(iso);

    iso.close();

    //Workaround 1
    //Wait until the card has been removed from the range of NFC
    //Then finish the activity
    while(true)
    {
    try
    {
    iso.connect();
    Thread.sleep(100);
    iso.close();
    }
    catch (IOException | InterruptedException e)
    {
    //On this example, once we're done with the activity, we want to close it
    //then onPause event will call disableReaderMode, at that moment we don't want a card to be in proximity
    onCardRemoved();
    break;
    }
    }
    //End of Workaround 1
    }
    catch (IOException e)
    {
    Toast.makeText(this, "Tag disconnected. Reason: " + e.getMessage(), Toast.LENGTH_SHORT).show();
    }
    }

    private void onCardRemoved()
    {
    this.finish();
    }

    @Override
    protected void onResume()
    {
    super.onResume();

    //Workaround 2
    //Legacy nfc reader activation method, just enabled it but we won't use it
    //(to fully support [e.g. OS version < v4.4.4] you must override onNewIntent(Intent intent) method as well)

    //create intent/tag filters to be used with enableForegroundDispatch
    PendingIntent pendingIntent = PendingIntent.getActivity(
    this,
    0,
    new Intent(this, this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
    0
    );

    IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
    tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
    IntentFilter[] writeTagFilters = new IntentFilter[]{tagDetected};

    nfcAdapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null);
    //End of Workaround 2

    //ReaderMode activation
    Bundle options = new Bundle();
    options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 1000);//Presence check interval
    final int READER_FLAGS = NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK | NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS;
    nfcAdapter.enableReaderMode(this, new NfcAdapter.ReaderCallback()
    {
    @Override
    public void onTagDiscovered(Tag tag)
    {
    MainActivity.this.onTagDiscovered(tag);
    }
    }, READER_FLAGS, options);
    }

    @Override
    protected void onPause()
    {
    nfcAdapter.disableReaderMode(this);

    //Workaround 2
    nfcAdapter.disableForegroundDispatch(this);

    super.onPause();
    }
    }

    关于android - 前台 Activity 中的 NfcAdapter.enableReaderMode 是否应该覆盖 Intent 标签调度系统?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60868912/

    37 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com