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 只有一个副本正在使用。这也显示在同一示例应用程序中。