Android:NDEF_DISCOVERED 的意图过滤器在 nfc window 而不是 运行 应用程序中打开应用程序
Android: Intent Filter for NDEF_DISCOVERED opens app in nfc window instead of running app
我实现了这个例子:https://developer.android.com/guide/topics/connectivity/nfc/nfc#p2p
package com.example.android.beam;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.TextView;
import android.widget.Toast;
import java.nio.charset.Charset;
public class Beam extends Activity implements CreateNdefMessageCallback {
NfcAdapter nfcAdapter;
TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView = (TextView) findViewById(R.id.textView);
// Check for available NFC Adapter
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
// Register callback
nfcAdapter.setNdefPushMessageCallback(this, this);
}
@Override
public NdefMessage createNdefMessage(NfcEvent event) {
String text = ("Beam me up, Android!\n\n" +
"Beam Time: " + System.currentTimeMillis());
NdefMessage msg = new NdefMessage(
new NdefRecord[] { createMime(
"application/vnd.com.example.android.beam", text.getBytes())
/**
* The Android Application Record (AAR) is commented out. When a device
* receives a push with an AAR in it, the application specified in the AAR
* is guaranteed to run. The AAR overrides the tag dispatch system.
* You can add it back in to guarantee that this
* activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system.
*/
//,NdefRecord.createApplicationRecord("com.example.android.beam")
});
return msg;
}
@Override
public void onResume() {
super.onResume();
// Check to see that the Activity started due to an Android Beam
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
processIntent(getIntent());
}
}
@Override
public void onNewIntent(Intent intent) {
// onResume gets called after this to handle the intent
setIntent(intent);
}
/**
* Parses the NDEF Message from the intent and prints to the TextView
*/
void processIntent(Intent intent) {
textView = (TextView) findViewById(R.id.textView);
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// only one message sent during the beam
NdefMessage msg = (NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
textView.setText(new String(msg.getRecords()[0].getPayload()));
}
}
在我的应用中并将此 intent-filter 添加到清单
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
当我现在在两个设备之一上发送时,意图执行 processIntent() 中的代码,但在名为 NFC 的程序内部,而不是在我的 运行 应用程序中。那么我怎样才能让 Intent 在 运行 应用程序中执行而不打开 NFC 应用程序呢?
您正在创建的 mime 类型为 application/vnd.com.example.android.beam
的消息与清单中的 mime 类型为 text/plain
之间存在不匹配的 mime 类型 您已要求系统启动您的应用程序,如果它看到了。
请注意,如果您确实匹配了 mime 类型,使用此代码可能会根据您应用程序的启动模式开始接收应用程序,但应用程序不会读取 NFC 消息。
这是因为 onNewIntent
仅在应用程序重新启动时调用,而您的应用程序并未重新启动。
通常的做法是清单过滤器以 Intent
启动您的应用程序,您需要在应用程序启动时处理它(通常在 onCreate
)。
onNewIntent
仅在您的应用程序已经 运行 并且已使用 enableForegroundDispatch
让系统向您的 运行 应用程序发送 NFC Intent
时使用,而不是尝试启动您的应用程序的新实例。
所以在您的代码中 onCreate
添加行
processIntent(getIntent());
我实现了这个例子:https://developer.android.com/guide/topics/connectivity/nfc/nfc#p2p
package com.example.android.beam;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.TextView;
import android.widget.Toast;
import java.nio.charset.Charset;
public class Beam extends Activity implements CreateNdefMessageCallback {
NfcAdapter nfcAdapter;
TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView = (TextView) findViewById(R.id.textView);
// Check for available NFC Adapter
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
// Register callback
nfcAdapter.setNdefPushMessageCallback(this, this);
}
@Override
public NdefMessage createNdefMessage(NfcEvent event) {
String text = ("Beam me up, Android!\n\n" +
"Beam Time: " + System.currentTimeMillis());
NdefMessage msg = new NdefMessage(
new NdefRecord[] { createMime(
"application/vnd.com.example.android.beam", text.getBytes())
/**
* The Android Application Record (AAR) is commented out. When a device
* receives a push with an AAR in it, the application specified in the AAR
* is guaranteed to run. The AAR overrides the tag dispatch system.
* You can add it back in to guarantee that this
* activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system.
*/
//,NdefRecord.createApplicationRecord("com.example.android.beam")
});
return msg;
}
@Override
public void onResume() {
super.onResume();
// Check to see that the Activity started due to an Android Beam
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
processIntent(getIntent());
}
}
@Override
public void onNewIntent(Intent intent) {
// onResume gets called after this to handle the intent
setIntent(intent);
}
/**
* Parses the NDEF Message from the intent and prints to the TextView
*/
void processIntent(Intent intent) {
textView = (TextView) findViewById(R.id.textView);
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// only one message sent during the beam
NdefMessage msg = (NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
textView.setText(new String(msg.getRecords()[0].getPayload()));
}
}
在我的应用中并将此 intent-filter 添加到清单
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
当我现在在两个设备之一上发送时,意图执行 processIntent() 中的代码,但在名为 NFC 的程序内部,而不是在我的 运行 应用程序中。那么我怎样才能让 Intent 在 运行 应用程序中执行而不打开 NFC 应用程序呢?
您正在创建的 mime 类型为 application/vnd.com.example.android.beam
的消息与清单中的 mime 类型为 text/plain
之间存在不匹配的 mime 类型 您已要求系统启动您的应用程序,如果它看到了。
请注意,如果您确实匹配了 mime 类型,使用此代码可能会根据您应用程序的启动模式开始接收应用程序,但应用程序不会读取 NFC 消息。
这是因为 onNewIntent
仅在应用程序重新启动时调用,而您的应用程序并未重新启动。
通常的做法是清单过滤器以 Intent
启动您的应用程序,您需要在应用程序启动时处理它(通常在 onCreate
)。
onNewIntent
仅在您的应用程序已经 运行 并且已使用 enableForegroundDispatch
让系统向您的 运行 应用程序发送 NFC Intent
时使用,而不是尝试启动您的应用程序的新实例。
所以在您的代码中 onCreate
添加行
processIntent(getIntent());