NFC标签检测不会调用onNewIntent,而是从主活动启动

我是NFC新手。 我试图连接到NFC,并将设备上的文本数据共享到其他设备。

我在两个设备上安装我的应用程序,并在一个设备上打开我的应用程序,并开始将设备点击到另一个设备,以便通过Beam传输数据。

在另一台设备上,由于Beam交互,我的应用程序打开。 但是,该活动是使用默认主要意图操作而不是TAG_DISCOVERED(或类似的NFC意图)启动的。 每次它做同样的事情。

另外,它不调用onNewIntent()方法。 我试图从onCreate onNewIntent调用,但意图的行动仍然主要在这种情况下。 我期望收到一个用于Beam交互的NFC意图。 那么你能告诉我我哪里错了吗?

在此代码中,我不共享数据。 我只需要标签。

performance:

 <activity android:name="com.framentos.hellonfc.MainActivity" android:clearTaskOnLaunch="true" android:label="@string/app_name" android:launchMode="singleTop" android:screenOrientation="portrait" > <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" /> </activity> 

Java代码:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ctx = this; // startHandler(); _handler = new Handler(); Button btnWrite = (Button) findViewById(R.id.button); message = (TextView) findViewById(R.id.nfcwriteTag); btnWrite.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); adapter = NfcAdapter.getDefaultAdapter(this); if (adapter == null) { message.setText("NFC is not supported on this device."); } if (adapter.isEnabled()) { message.setText("NFC is Enabled on this device."); } else { message.setText("Please enable NFC to communicate."); } pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); IntentFilter tagDetected = new IntentFilter( NfcAdapter.ACTION_NDEF_DISCOVERED); tagDetected.addCategory(Intent.CATEGORY_DEFAULT); IntentFilter tagTech = new IntentFilter( NfcAdapter.ACTION_TECH_DISCOVERED); tagTech.addCategory(Intent.CATEGORY_DEFAULT); IntentFilter tagDetect = new IntentFilter( NfcAdapter.ACTION_TAG_DISCOVERED); tagDetect.addCategory(Intent.CATEGORY_DEFAULT); writeTagFilters = new IntentFilter[] { tagDetected, tagTech ,tagDetect}; // handleIntent(getIntent()); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.i(getPackageName(), "on New Intent is called...!"); handleIntent(getIntent()); } public void onPause() { super.onPause(); WriteModeOff(); } @Override public void onResume() { super.onResume(); WriteModeOn(); } private void WriteModeOn() { writeMode = true; adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null); } private void WriteModeOff() { writeMode = false; adapter.disableForegroundDispatch(this); } 

Solutions Collecting From Web of "NFC标签检测不会调用onNewIntent,而是从主活动启动"

从您在问题中发布的代码中,我假设您没有注册您的应用程序来发送特定的NDEF消息。 在这种情况下,如果您的应用程序在一台设备上打开,则Android会自动使用应用程序的Play Store链接和Android应用程序logging(AAR)向其他设备发送包含URIlogging的NDEF消息。

所以你的第二个设备将收到以下NDEF消息:

 +---------------------------------------------------------------------------------------+ | WKT:URI | http://play.google.com/store/apps/details?id=your.package.name&feature=beam | +---------------------------------------------------------------------------------------+ | EXT:android:com:pkg | your.package.name | +---------------------------------------------------------------------------------------+ 

如果您的应用尚未在第二个设备上打开,现在发生的情况是Android应用logging(第二条logging)将强制您的应用启动。 但是,查看清单时,没有与此NDEF邮件的第一条logging(Play商店URL)相匹配的意向filter。 因此,Android认为你不会期望NDEF消息,并使用标准的android.intent.action.MAIN (带有类别android.intent.category.LAUNCHER )来启动你的应用程序(或者说你的应用程序的第一个活动,意图filter的行动MAIN与类别LAUNCHER )。

为了在您的应用程序中接收NFC意图以及整个NDEF消息,您需要定义一个适当的意图filter,以匹配上述NDEF消息中的第一条logging:

 <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="http" android:host="play.google.com" android:pathPrefix="/store/apps/details?id=your.package.name" /> </intent-filter> 

现在,Android会识别您的应用/活动已准备好接收NFC意图,并将NDEF_DISCOVERED意图传递给您的活动。 请注意,如果您的应用程序尚未运行,您仍然不会通过onNewIntent()接收该意图。 相反,您可以通过活动的getIntent()方法获得开始活动的意图。 例如在onCreate / onStart / onResume ,你可以使用

 Intent intent = getIntent(); if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) { NdefMessage ndefMessage = null; Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); if ((rawMessages != null) && (rawMessages.length > 0)) { ndefMessage = (NdefMessage)rawMessages[0]; } // TODO: do something with the received NDEF message } 

获取意图和NDEF消息。

关于你已经在你的清单中的意图filter:

  1. NDEF_DISCOVERED

     <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> 

    没有<data ... />标记的NDEF_DISCOVERED intentfilter绝不会在许多NFC设备上触发。 您应该始终定义您希望在启动NDEFlogging中出现的具体数据。

  2. TECH_DISCOVERED

     <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" /> 

    如果您不希望在检测到某个NFC标签技术时启动应用程序(您可以在nfc_tech_filter.xml文件中定义特定的技术),那么您应该只使用这个意图filter。对于您的Beam场景,您不会使用这种意图filter。Btw。 <category ...>标签不用于这个意图filter。

  3. TAG_DISCOVERED

     <intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> 

    这个意图filter通常不应该在清单中使用。 如果没有其他应用程序可能处理检测到的NFC标签,则意味着作为回退触发。 使用这可能会导致不良的用户体验(例如,您的应用程序启动的标签不能或实际上不想处理)。 它主要用于向后兼容API级别9(?)。

如果您的活动已经开始,为了捕捉NFC意图,您可以像这样注册前台调度(在onResume方法中):

 PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null); 

这样,当您的活动处于活动的onNewIntent方法的前台时,您将收到发生的任何NFC发现事件。 他们将通过ACTION_TAG_DISCOVERED意图发送。