【问题标题】:Check if NFC tag is near检查NFC标签是否在附近
【发布时间】:2014-11-19 13:16:41
【问题描述】:

是否可以强制 android 检查 NFC 标签是否在附近?我只能在 android 检测到标签时读取标签,我想强制它检查标签是否在特定时刻附近

【问题讨论】:

  • 为了检查标签是否在附近,它必须检测到该标签...这不合逻辑。
  • 我需要检查手机背面是否贴有nfc标签,这是客户必备的

标签: android nfc


【解决方案1】:

您想要做的通常是不可能的。但是,如果您可以忍受肮脏的黑客攻击,则以下内容将起作用(由于未指定的行为):

首先禁用所有支持的标签类型的阅读器模式。这会使 NFC 子系统进入清洁状态,例如它确保 NFC 控制器与标签没有连接。

完成后再次恢复阅读器模式。如果此时存在标签,您将获得通常的发现操作作为意图。不过可能需要一两秒钟。

可以使用NfcAdapter.enableReaderModeNfcAdapter.disableReaderMode 控制阅读器模式

【讨论】:

  • 这个想法还可以,但它只适用于 API 19... 是否有可能适用于较旧的 android 版本?
  • @Mikel 如果你有系统权限,你可以像设置应用一样启用和禁用整个 NFC 子系统。
  • @Mikel 好吧,在这种情况下你不能实现这个功能。
【解决方案2】:

我想出了一些可行的方法(至少对我来说!)

首先,当您最初通过android.nfc.action.NDEF_DISCOVERED 检测到标签时,将标签作为您的类中的一个字段并启动一个计时器(这是在 C#/Xamarin 中,但同样适用于 Java):

_tag = Intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;

ReaderTimer = new Timer(2000);
ReaderTimer.Elapsed += TimerElapsed;
ReaderTimer.Start();

现在,它会每 2 秒触发一次。它将尝试重新连接到标签。如果不能,标签就消失了。:

    private void TimerElapsed(object sender, ElapsedEventArgs e)
    {
        if (_tag == null)
        {
            return;
        }

        Ndef ndef = Ndef.Get(_tag);

        if (ndef == null)
        {
            // NDEF is not supported by this Tag.
            return;
        }

        if (!ndef.IsConnected)
        {
            try
            {
                ndef.Close();
                ndef.Connect();
            }
            catch (Exception ex)
            {
                // could not reconnect
                // implies tag is not in proximity

                //do whatever needs to be done when NFC is disconnected

                ReaderTimer.Stop();
            }
        }
    }

我已经使用 API 14 对此进行了测试。

不幸的是当屏幕关闭时ndef.Connect()失败,所以被注册为断开连接。

【讨论】:

  • 对,存储标签句柄并稍后尝试连接应该可以。但是,这可能存在一些问题: (1) NFC 旨在用于短交互。因此,标签句柄可能不会永远有效(特别是当与标签的物理连接在两次连接重试之间暂时断开时)。 (2) 请注意,对于某些标签技术(或某些 Android 版本???)connect() 不一定会导致标签上的 I/O 操作,因此即使与标签的连接丢失也可能成功(您可以使用getNdefMessage()in 强制I/O)。
  • 谢谢迈克尔,我会考虑的。
【解决方案3】:

试试这个代码吧!它会不断检查NFC标签是否靠近手机。

@Override
protected void onNewIntent(Intent intent) {
    setIntent(intent);
    readFromIntent(intent);
    if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
        myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {

        @Override
        public void run() {
        checkNFCStatus();
        handler.postDelayed(this,1000);
        }

    }, 1000);

    }
}

public void checkNFCStatus(){
    try {
        if(myTag != null) {
            Ndef ndefTag = Ndef.get(myTag);
            ndefTag.connect();
            if (ndefTag.isConnected()) {
                Log.d("network", "NFC connected");
            } else {
                Log.d("network", "NFC disconnected");
            }
            ndefTag.close();
        }

    } catch (IOException e) {
        e.printStackTrace();
        Log.d("network", "NFC disconnected");
    }
}

//If the connection is not closed, an exception will be thrown

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多