NFC 类的 onNewIntent 始终在第 3 次扫描后运行
NFC class' onNewIntent always runs after 3rd scan
我有一个 Activity 从 NFC 标签捕获数据。为了读取标签的内容,我必须扫描标签 3 次。
我希望在第一次扫描时提取标签的内容。
在第一次扫描时,activity 似乎进入了以下生命周期方法:
onCreate -> onResume -> enableForegroundMode()
第二次扫描:
onPause -> disableForegroundMode() -> onCreate -> onResume -> enableForegroundMode()
然后在最后的第 3 次扫描中:
onPause -> disableForegroundMode() -> onNewIntent
谁能告诉我为什么会这样,为什么我必须总是扫描 3 次?
下面是我的 class 和堆栈跟踪
提前致谢
public class NfcActivity extends Activity {
private static final String TAG = NfcActivity.class.getName();
protected NfcAdapter nfcAdapter;
protected PendingIntent nfcPendingIntent;
Handler handler;
Runnable runnable;
Parcelable[] messages;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nfcactivitylayout);
Log.e(TAG, "oncreate");
// initialize NFC
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
}
public void enableForegroundMode() {
Log.e(TAG, "enableForegroundMode");
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); // filter for all
IntentFilter[] writeTagFilters = new IntentFilter[] {tagDetected};
nfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, writeTagFilters, null);
}
public void disableForegroundMode() {
Log.e(TAG, "disableForegroundMode");
nfcAdapter.disableForegroundDispatch(this);
}
@Override
public void onNewIntent(Intent intent) {
Log.e(TAG, "onNewIntent");
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
//TextView textView = (TextView) findViewById(R.id.title);
//textView.setText("Hello NFC!");
messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
setContentView(R.layout.successfulnfc);
Log.e(TAG, "Found " + messages.length + " NDEF messages"); // is almost always just one
vibrate(); // signal found messages :-)
initHandler();
handler.postDelayed(runnable, 2000);
}
} else {
// ignore
}
}
@Override
protected void onResume() {
Log.e(TAG, "onResume");
super.onResume();
enableForegroundMode();
}
@Override
protected void onPause() {
Log.e(TAG, "onPause");
super.onPause();
disableForegroundMode();
if(handler != null){
handler.removeCallbacks(runnable);
}
}
private void vibrate() {
Log.e(TAG, "vibrate");
Vibrator vibe = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE) ;
vibe.vibrate(500);
}
}
.
01-05 12:56:48.849: E/com.carefreegroup.rr3.NfcActivity(12362): oncreate
01-05 12:56:48.859: E/com.carefreegroup.rr3.NfcActivity(12362): onResume
01-05 12:56:48.859: E/com.carefreegroup.rr3.NfcActivity(12362): enableForegroundMode
01-05 12:56:50.099: E/wpa_supplicant(1113): send_and_recv error 0 - cmd 32
01-05 12:56:50.099: E/wpa_supplicant(1113): send_and_recv error 0 - cmd 50
01-05 12:56:50.099: E/wpa_supplicant(1113): send_and_recv error 0 - cmd 32
01-05 12:56:50.099: E/wpa_supplicant(1113): send_and_recv error 0 - cmd 50
01-05 12:56:50.699: E/MP-Decision(1724): Update arg 1
01-05 12:56:52.679: E/MP-Decision(1724): Update arg 2
01-05 12:56:52.699: E/com.carefreegroup.rr3.NfcActivity(12362): onPause
01-05 12:56:52.699: E/com.carefreegroup.rr3.NfcActivity(12362): disableForegroundMode
01-05 12:56:52.719: E/com.carefreegroup.rr3.NfcActivity(12362): oncreate
01-05 12:56:52.719: E/com.carefreegroup.rr3.NfcActivity(12362): onResume
01-05 12:56:52.719: E/com.carefreegroup.rr3.NfcActivity(12362): enableForegroundMode
01-05 12:56:53.689: E/MP-Decision(1724): Update arg 1
01-05 12:56:55.009: E/MP-Decision(1724): Update arg 2
01-05 12:56:55.009: E/com.carefreegroup.rr3.NfcActivity(12362): onPause
01-05 12:56:55.009: E/com.carefreegroup.rr3.NfcActivity(12362): disableForegroundMode
01-05 12:56:55.019: E/com.carefreegroup.rr3.NfcActivity(12362): onNewIntent
01-05 12:56:55.059: E/com.carefreegroup.rr3.NfcActivity(12362): Found 1 NDEF messages
01-05 12:56:55.059: E/com.carefreegroup.rr3.NfcActivity(12362): vibrate
01-05 12:56:55.059: E/com.carefreegroup.rr3.NfcActivity(12362): onResume
01-05 12:56:55.059: E/com.carefreegroup.rr3.NfcActivity(12362): enableForegroundMode
01-05 12:56:56.009: E/MP-Decision(1724): Update arg 1
01-05 12:56:57.059: E/com.carefreegroup.rr3.NfcActivity(12362): about to process tag
01-05 12:56:57.089: E/com.carefreegroup.rr3.NfcActivity(12362): Found 1 records in message 0
01-05 12:56:57.089: E/com.carefreegroup.rr3.NfcActivity(12362): Record #0 is of class TextRecord
01-05 12:56:57.099: E/com.carefreegroup.rr3.NfcActivity(12362): payload = 1,10,1074,Kelly Waugh
01-05 12:56:57.109: E/MP-Decision(1724): Update arg 2
01-05 12:56:57.129: E/com.carefreegroup.rr3.NfcActivity(12362): onPause
01-05 12:56:57.129: E/com.carefreegroup.rr3.NfcActivity(12362): disableForegroundMode
.
<activity
android:name=".NfcActivity"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
[编辑 1]
Intent i;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nfcactivitylayout);
Log.e(TAG, "oncreate");
// initialize NFC
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
i = getIntent();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(i.getAction())) {
//TextView textView = (TextView) findViewById(R.id.title);
//textView.setText("Hello NFC!");
messages = i.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
setContentView(R.layout.successfulnfc);
Log.e(TAG, "Found " + messages.length + " NDEF messages"); // is almost always just one
vibrate(); // signal found messages :-)
initHandler();
handler.postDelayed(runnable, 2000);
}
} else {
// ignore
}
}
[编辑 3]
public class NfcActivity extends Activity {
private static final String TAG = NfcActivity.class.getName();
protected NfcAdapter nfcAdapter;
protected PendingIntent nfcPendingIntent;
Handler handler;
Runnable runnable;
Parcelable[] messages;
Intent i;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nfcactivitylayout);
Log.e(TAG, "oncreate");
// initialize NFC
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
i = getIntent();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(i.getAction())) {
//TextView textView = (TextView) findViewById(R.id.title);
//textView.setText("Hello NFC!");
messages = i.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
setContentView(R.layout.successfulnfc);
Log.e(TAG, "Found " + messages.length + " NDEF messages"); // is almost always just one
vibrate(); // signal found messages :-)
initHandler();
handler.postDelayed(runnable, 2000);
}
} else {
// ignore
}
}
public void enableForegroundMode() {
Log.e(TAG, "enableForegroundMode");
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); // filter for all
IntentFilter[] writeTagFilters = new IntentFilter[] {tagDetected};
nfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, writeTagFilters, null);
}
public void disableForegroundMode() {
Log.e(TAG, "disableForegroundMode");
nfcAdapter.disableForegroundDispatch(this);
}
@Override
public void onNewIntent(Intent intent) {
Log.e(TAG, "onNewIntent");
Intent processPayloadIntent = new Intent(NfcActivity.this, NfcscannerActivity.class);
processPayloadIntent.setAction("QRCODE_ACTION");
processPayloadIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(processPayloadIntent);
}
@Override
protected void onResume() {
Log.e(TAG, "onResume");
super.onResume();
enableForegroundMode();
}
@Override
protected void onPause() {
Log.e(TAG, "onPause");
super.onPause();
disableForegroundMode();
if(handler != null){
handler.removeCallbacks(runnable);
}
}
private void vibrate() {
Log.e(TAG, "vibrate");
Vibrator vibe = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE) ;
vibe.vibrate(500);
}
public void initHandler(){
handler = new Handler();
runnable = new Runnable() {
public void run() {
processTag();
}
private void processTag() {
Log.e(TAG, "about to process tag");
// parse to records
for (int i = 0; i < messages.length; i++) {
try {
List<Record> records = new Message((NdefMessage)messages[i]);
Log.e(TAG, "Found " + records.size() + " records in message " + i);
for(int k = 0; k < records.size(); k++) {
Log.e(TAG, " Record #" + k + " is of class " + records.get(k).getClass().getSimpleName());
Record record = records.get(k);
NdefRecord ndefRecord = record.getNdefRecord();
byte[] arr = ndefRecord.getPayload();
String payload = new String(arr);
payload = payload.substring(3, payload.length());
Log.e(TAG, "payload = " + payload);
Intent processPayloadIntent = new Intent(NfcActivity.this, NfcscannerActivity.class);
processPayloadIntent.putExtra("payload", payload);
processPayloadIntent.setAction("NFC");
processPayloadIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(processPayloadIntent);
}
} catch (Exception e) {
Log.e(TAG, "Problem parsing message", e);
}
}
}
};
}
}
首先,onCreate()
是获取 NFC Intent
的一种完全有效的方式。如果 Android 将 Intent
传送到您的 activity 的一个已经存在的实例,您将只会得到 onNewIntent()
。您需要处理 NDEF_DISCOVERED
Intent
进入 onCreate()
以及 进入 onNewIntent()
的情况。您可以在我相信您拥有的 this one, which is covered in a book 等示例应用程序中看到这一点。 :-)
您可能希望考虑做的另一件事是在 activity 的清单条目上使用 android:launchMode="singleTask"
,以确保 activity 只有一个副本正在使用。这也显示在同一示例应用程序中。
我有一个 Activity 从 NFC 标签捕获数据。为了读取标签的内容,我必须扫描标签 3 次。
我希望在第一次扫描时提取标签的内容。
在第一次扫描时,activity 似乎进入了以下生命周期方法:
onCreate -> onResume -> enableForegroundMode()
第二次扫描:
onPause -> disableForegroundMode() -> onCreate -> onResume -> enableForegroundMode()
然后在最后的第 3 次扫描中:
onPause -> disableForegroundMode() -> onNewIntent
谁能告诉我为什么会这样,为什么我必须总是扫描 3 次?
下面是我的 class 和堆栈跟踪
提前致谢
public class NfcActivity extends Activity {
private static final String TAG = NfcActivity.class.getName();
protected NfcAdapter nfcAdapter;
protected PendingIntent nfcPendingIntent;
Handler handler;
Runnable runnable;
Parcelable[] messages;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nfcactivitylayout);
Log.e(TAG, "oncreate");
// initialize NFC
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
}
public void enableForegroundMode() {
Log.e(TAG, "enableForegroundMode");
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); // filter for all
IntentFilter[] writeTagFilters = new IntentFilter[] {tagDetected};
nfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, writeTagFilters, null);
}
public void disableForegroundMode() {
Log.e(TAG, "disableForegroundMode");
nfcAdapter.disableForegroundDispatch(this);
}
@Override
public void onNewIntent(Intent intent) {
Log.e(TAG, "onNewIntent");
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
//TextView textView = (TextView) findViewById(R.id.title);
//textView.setText("Hello NFC!");
messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
setContentView(R.layout.successfulnfc);
Log.e(TAG, "Found " + messages.length + " NDEF messages"); // is almost always just one
vibrate(); // signal found messages :-)
initHandler();
handler.postDelayed(runnable, 2000);
}
} else {
// ignore
}
}
@Override
protected void onResume() {
Log.e(TAG, "onResume");
super.onResume();
enableForegroundMode();
}
@Override
protected void onPause() {
Log.e(TAG, "onPause");
super.onPause();
disableForegroundMode();
if(handler != null){
handler.removeCallbacks(runnable);
}
}
private void vibrate() {
Log.e(TAG, "vibrate");
Vibrator vibe = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE) ;
vibe.vibrate(500);
}
}
.
01-05 12:56:48.849: E/com.carefreegroup.rr3.NfcActivity(12362): oncreate
01-05 12:56:48.859: E/com.carefreegroup.rr3.NfcActivity(12362): onResume
01-05 12:56:48.859: E/com.carefreegroup.rr3.NfcActivity(12362): enableForegroundMode
01-05 12:56:50.099: E/wpa_supplicant(1113): send_and_recv error 0 - cmd 32
01-05 12:56:50.099: E/wpa_supplicant(1113): send_and_recv error 0 - cmd 50
01-05 12:56:50.099: E/wpa_supplicant(1113): send_and_recv error 0 - cmd 32
01-05 12:56:50.099: E/wpa_supplicant(1113): send_and_recv error 0 - cmd 50
01-05 12:56:50.699: E/MP-Decision(1724): Update arg 1
01-05 12:56:52.679: E/MP-Decision(1724): Update arg 2
01-05 12:56:52.699: E/com.carefreegroup.rr3.NfcActivity(12362): onPause
01-05 12:56:52.699: E/com.carefreegroup.rr3.NfcActivity(12362): disableForegroundMode
01-05 12:56:52.719: E/com.carefreegroup.rr3.NfcActivity(12362): oncreate
01-05 12:56:52.719: E/com.carefreegroup.rr3.NfcActivity(12362): onResume
01-05 12:56:52.719: E/com.carefreegroup.rr3.NfcActivity(12362): enableForegroundMode
01-05 12:56:53.689: E/MP-Decision(1724): Update arg 1
01-05 12:56:55.009: E/MP-Decision(1724): Update arg 2
01-05 12:56:55.009: E/com.carefreegroup.rr3.NfcActivity(12362): onPause
01-05 12:56:55.009: E/com.carefreegroup.rr3.NfcActivity(12362): disableForegroundMode
01-05 12:56:55.019: E/com.carefreegroup.rr3.NfcActivity(12362): onNewIntent
01-05 12:56:55.059: E/com.carefreegroup.rr3.NfcActivity(12362): Found 1 NDEF messages
01-05 12:56:55.059: E/com.carefreegroup.rr3.NfcActivity(12362): vibrate
01-05 12:56:55.059: E/com.carefreegroup.rr3.NfcActivity(12362): onResume
01-05 12:56:55.059: E/com.carefreegroup.rr3.NfcActivity(12362): enableForegroundMode
01-05 12:56:56.009: E/MP-Decision(1724): Update arg 1
01-05 12:56:57.059: E/com.carefreegroup.rr3.NfcActivity(12362): about to process tag
01-05 12:56:57.089: E/com.carefreegroup.rr3.NfcActivity(12362): Found 1 records in message 0
01-05 12:56:57.089: E/com.carefreegroup.rr3.NfcActivity(12362): Record #0 is of class TextRecord
01-05 12:56:57.099: E/com.carefreegroup.rr3.NfcActivity(12362): payload = 1,10,1074,Kelly Waugh
01-05 12:56:57.109: E/MP-Decision(1724): Update arg 2
01-05 12:56:57.129: E/com.carefreegroup.rr3.NfcActivity(12362): onPause
01-05 12:56:57.129: E/com.carefreegroup.rr3.NfcActivity(12362): disableForegroundMode
.
<activity
android:name=".NfcActivity"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
[编辑 1]
Intent i;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nfcactivitylayout);
Log.e(TAG, "oncreate");
// initialize NFC
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
i = getIntent();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(i.getAction())) {
//TextView textView = (TextView) findViewById(R.id.title);
//textView.setText("Hello NFC!");
messages = i.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
setContentView(R.layout.successfulnfc);
Log.e(TAG, "Found " + messages.length + " NDEF messages"); // is almost always just one
vibrate(); // signal found messages :-)
initHandler();
handler.postDelayed(runnable, 2000);
}
} else {
// ignore
}
}
[编辑 3]
public class NfcActivity extends Activity {
private static final String TAG = NfcActivity.class.getName();
protected NfcAdapter nfcAdapter;
protected PendingIntent nfcPendingIntent;
Handler handler;
Runnable runnable;
Parcelable[] messages;
Intent i;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nfcactivitylayout);
Log.e(TAG, "oncreate");
// initialize NFC
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
i = getIntent();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(i.getAction())) {
//TextView textView = (TextView) findViewById(R.id.title);
//textView.setText("Hello NFC!");
messages = i.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
setContentView(R.layout.successfulnfc);
Log.e(TAG, "Found " + messages.length + " NDEF messages"); // is almost always just one
vibrate(); // signal found messages :-)
initHandler();
handler.postDelayed(runnable, 2000);
}
} else {
// ignore
}
}
public void enableForegroundMode() {
Log.e(TAG, "enableForegroundMode");
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); // filter for all
IntentFilter[] writeTagFilters = new IntentFilter[] {tagDetected};
nfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, writeTagFilters, null);
}
public void disableForegroundMode() {
Log.e(TAG, "disableForegroundMode");
nfcAdapter.disableForegroundDispatch(this);
}
@Override
public void onNewIntent(Intent intent) {
Log.e(TAG, "onNewIntent");
Intent processPayloadIntent = new Intent(NfcActivity.this, NfcscannerActivity.class);
processPayloadIntent.setAction("QRCODE_ACTION");
processPayloadIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(processPayloadIntent);
}
@Override
protected void onResume() {
Log.e(TAG, "onResume");
super.onResume();
enableForegroundMode();
}
@Override
protected void onPause() {
Log.e(TAG, "onPause");
super.onPause();
disableForegroundMode();
if(handler != null){
handler.removeCallbacks(runnable);
}
}
private void vibrate() {
Log.e(TAG, "vibrate");
Vibrator vibe = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE) ;
vibe.vibrate(500);
}
public void initHandler(){
handler = new Handler();
runnable = new Runnable() {
public void run() {
processTag();
}
private void processTag() {
Log.e(TAG, "about to process tag");
// parse to records
for (int i = 0; i < messages.length; i++) {
try {
List<Record> records = new Message((NdefMessage)messages[i]);
Log.e(TAG, "Found " + records.size() + " records in message " + i);
for(int k = 0; k < records.size(); k++) {
Log.e(TAG, " Record #" + k + " is of class " + records.get(k).getClass().getSimpleName());
Record record = records.get(k);
NdefRecord ndefRecord = record.getNdefRecord();
byte[] arr = ndefRecord.getPayload();
String payload = new String(arr);
payload = payload.substring(3, payload.length());
Log.e(TAG, "payload = " + payload);
Intent processPayloadIntent = new Intent(NfcActivity.this, NfcscannerActivity.class);
processPayloadIntent.putExtra("payload", payload);
processPayloadIntent.setAction("NFC");
processPayloadIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(processPayloadIntent);
}
} catch (Exception e) {
Log.e(TAG, "Problem parsing message", e);
}
}
}
};
}
}
首先,onCreate()
是获取 NFC Intent
的一种完全有效的方式。如果 Android 将 Intent
传送到您的 activity 的一个已经存在的实例,您将只会得到 onNewIntent()
。您需要处理 NDEF_DISCOVERED
Intent
进入 onCreate()
以及 进入 onNewIntent()
的情况。您可以在我相信您拥有的 this one, which is covered in a book 等示例应用程序中看到这一点。 :-)
您可能希望考虑做的另一件事是在 activity 的清单条目上使用 android:launchMode="singleTask"
,以确保 activity 只有一个副本正在使用。这也显示在同一示例应用程序中。