首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Kivy + Python中读取NFC标签?

如何在Kivy + Python中读取NFC标签?
EN

Stack Overflow用户
提问于 2016-06-22 03:34:04
回答 1查看 2.7K关注 0票数 3

我正在尝试读取NFC标签,如果标签只有文本,则读取正常。但是,如果标记包含URL或为空,则不起作用。我认为问题出在nfc_filter.xml文件上。

代码语言:javascript
复制
<intent-filter>
  <action android:name="android.nfc.action.TAG_DISCOVERED"/>
  <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
  <action android:name="android.nfc.action.TECH_DISCOVERED"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <data android:mimeType="*/*" />
</intent-filter>

Python代码:

代码语言:javascript
复制
def nfc_init(self):
    activity.bind(on_new_intent=self.on_new_intent)
    self.j_context = context = PythonActivity.mActivity
    self.nfc_adapter = NfcAdapter.getDefaultAdapter(context)
    self.nfc_pending_intent = PendingIntent.getActivity(context, 0, Intent(context, context.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0)
    return True

def on_new_intent(self, intent):
    print 'on_new_intent()', intent.getAction()
    # get TAG details
    tag = cast('android.nfc.Tag', intent.getParcelableExtra(NfcAdapter.EXTRA_TAG))
    details = self.get_ndef_details(tag)

def on_pause(self):
    print 'paused'
    return True

def on_resume(self):
    print 'resumed'

我想要的是,当我的应用程序处于活动状态时,当你读取NFC标签时,它总是会收到意图。现在我可以在日志中看到,如果标记包含文本以外的内容或为空,则不会从on_pause恢复。

有人能帮我一下吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-23 16:03:35

由于清单中的意图筛选器,你的应用程序当前会接收NFC事件:

代码语言:javascript
复制
<intent-filter>
  <action android:name="android.nfc.action.TAG_DISCOVERED"/>
  <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
  <action android:name="android.nfc.action.TECH_DISCOVERED"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <data android:mimeType="*/*" />
</intent-filter>

这个意图过滤器有几个问题:

  1. 此意图筛选器将匹配意图操作TAG_DISCOVEREDNDEF_DISCOVEREDTECH_DISCOVERED同时包含类别DEFAULT或BROWSABLE的意图,同时包含任何(?)MIME类型。

这样做的问题是,只有NDEF_DISCOVERED意图可以包含MIME类型。因此,TAG_DISCOVEREDTECH_DISCOVERED永远不会匹配。

  1. MIME类型*/* (即匹配任何MIME类型)不会(应该不会?)在清单意图过滤器中工作,因为只有子类型部分(即斜杠后面的部分)可以包含通配符(*)。请参阅android:mimeType.

  1. 可浏览类别是无用的,因为任何

意图都不会包含该类别。

包含

  1. NDEF_DISCOVERED的标记的URL意图不包含MIME类型。由于您将NDEF_DISCOVERED意图筛选器限制为包含MIME类型的意图,因此它将与包含URL的意图不匹配。

  1. TECH_DISCOVERED意图筛选器要求声明技术列表XML文件。

因此,您需要更改意图过滤器以匹配您的标记。如果你想匹配任何NDEF格式的标签,你可以简单的使用意图过滤器:

代码语言:javascript
复制
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

然而,这也带来了一些限制:任何注册了更具体NDEF_DISCOVERED意图的应用程序(例如,包含MIME类型过滤器或URL过滤器的应用程序)将优先于您的应用程序,您将不会收到该意图。此外,有报道称,不带<data ...>NDEF_DISCOVERED意图过滤器在某些设备上不起作用。

因此,为了匹配MIME类型和URL,您可能需要使用更具体的意图过滤器,例如,为了匹配所有text/image/application/ MIME类型、所有HTTP(S) URL和所有NFC论坛外部类型:

代码语言:javascript
复制
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="text/*" />
    <data android:mimeType="image/*" />
    <data android:mimeType="application/*" />
</intent-filter>
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="http" />
    <data android:scheme="https" />
    <data android:scheme="vnd.android.nfc" android:host="ext" android:pathPrefix="/" />
</intent-filter>

尽管如此,如果其他应用程序注册了更具体的意图过滤器,您的应用程序将不会收到任何符合这些“更具体”标准的意图(请参阅How NFC Tags are Dispatched to Applications)。

如果您的应用程序也应该收到有关非NDEF格式的标签的通知,您可以使用TECH_DISCOVERED意图过滤器(请注意,不需要为此特定意图过滤器指定任何类别)。在这种情况下,您还需要声明一个包含应该匹配的技术列表的XML资源文件(声明必须在<intent-filter ... />元素之外!):

代码语言:javascript
复制
<intent-filter>
    <action android:name="android.nfc.action.TECH_DISCOVERED" />
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
           android:resource="@xml/nfc_tech_filter" />

您还需要一个XML资源nfc_tech_filter.xml (放在res/xml/下)。为了匹配任何标记,您可以使用:

代码语言:javascript
复制
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcB</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcF</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcV</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcBarcode</tech>
    </tech-list>
</resources>

最后,不要在清单中使用 intent filter,除非您真的知道它的所有含义(特别是在用户体验和用户期望方面)。此意图过滤器仅是API level 9( Android 2.3.3之前)的兼容模式,其中NFC支持非常非常有限,并且是一种后备模式,可用于创建处理任何其他应用程序不支持的NFC标签的应用程序。

检测前台应用中的标签

既然你写了你希望你的应用程序总是收到这些意图,当它是活动的,并且你阅读NFC标签时,你可能想要考虑从清单中完全删除意图过滤器,而使用前台调度系统。在这种情况下,当读取NFC标签时,您的应用程序将不会启动,但它将接收所有 NFC发现事件,并且当它处于前台时,它将优先于all其他应用程序。

您可以通过简单地将此代码添加到您的应用程序中来做到这一点(虽然不太确定Python语法):

代码语言:javascript
复制
def on_pause(self):
    print 'paused'
    self.nfc_adapter.disableForegroundDispatch(PythonActivity.mActivity)
    return True

def on_resume(self):
    print 'resumed'
    self.nfc_adapter.enableForegroundDispatch(PythonActivity.mActivity, self.nfc_pending_intent, None, None)
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37953101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档