我试图阅读NFC标签,如果标签只有文字,那么阅读效果会很好。但是,如果标记包含URL或为空,则它不起作用。我认为问题出在nfc_filter.xml文件中。
<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代码:
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恢复,以防标签包含除文本以外的内容或为空。
有人可以帮我这个吗?
答案 0 :(得分:3)
由于清单中的意图过滤器,您的应用当前会收到NFC事件:
<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>
此意图过滤器存在一些问题:
此意图过滤器将匹配具有意图操作TAG_DISCOVERED
,NDEF_DISCOVERED
或TECH_DISCOVERED
,和的意图,同时包含类别DEFAULT或BROWSABLE,和同时包含任何(?)MIME类型。
这个问题是只有NDEF_DISCOVERED
意图可能包含MIME类型。因此,TAG_DISCOVERED
和TECH_DISCOVERED
永远不会匹配。
MIME类型*/*
(即匹配任何MIME类型)赢了(不应该?)在清单意图过滤器中工作,因为只有子类型部分(即斜杠之后的部分)可能包含通配符(*)。请参阅android:mimeType。
BROWSABLE类别无用,因为任何NFC意图都不会包含该类别。
NDEF_DISCOVERED
意图不包含MIME类型。由于您将NDEF_DISCOVERED
意图过滤器限制为包含MIME类型的意图,因此它不会匹配包含URL的意图。
TECH_DISCOVERED
意图过滤器需要声明技术列表XML文件。
因此,您需要更改intent过滤器以匹配您的标记。如果要匹配任何NDEF格式的标记,只需使用intent过滤器:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
但是,这有一些限制:任何注册了更具体的NDEF_DISCOVERED
意图的应用(例如,包含MIME类型过滤器或网址过滤器的应用)将优先于您的应用,并且您赢得了#39 ;收到意图。此外,有报告称NDEF_DISCOVERED
意图过滤器<data ...>
在某些设备上无效。
因此,为了匹配MIME类型和网址,您可能需要使用更具体的意图过滤器,例如为了匹配所有text/
,image/
和application/
MIME类型,所有HTTP(S)网址以及所有NFC论坛外部类型:
<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>
尽管如此,如果某个其他应用注册了更具体的意图过滤器,那么您的应用就不会收到任何符合这些意图的意图&#34;更具体的&#34;标准(见How NFC Tags are Dispatched to Applications)。
如果您的应用也应该收到有关非NDEF格式的标签的通知,您可以使用TECH_DISCOVERED
意图过滤器(请注意,无需为此特定的意图过滤器指定任何类别)。在这种情况下,您还需要声明一个XML资源文件,其中包含应匹配的技术列表(声明必须在<intent-filter ... />
元素之外!):
<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/
下)。为了匹配任何标签,您可以使用:
<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>
最后,不使用清单中的TAG_DISCOVERED
intent过滤器,除非您真正了解其所有含义(尤其是用户体验和用户期望)。此意图过滤器仅仅是API级别9(在Android 2.3.3之前)的兼容模式,其中NFC支持非常非常有限,并且可以使用后备模式来创建处理任何不支持的NFC标签的应用程序。其他应用程序。
由于您写道,您希望您的应用始终接收这些意图&#34; 当它处于活动状态并且您阅读NFC标记&#34;时,您可能需要考虑删除意图从清单中完全过滤并使用前台调度系统。在这种情况下,当您读取NFC标签时,您的应用不会启动,但它会接收所有 NFC发现事件,并且优先于所有强大>其他应用程序,但它在前台。
你可以通过简单地将它添加到你的应用程序(虽然不太确定Python语法)来做到这一点:
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)