2014-06-10 76 views
-1

我開發了一個簡單的android應用程序,可以讀取NFC卡上的NDEF消息。下面是應用程序的代碼 -掃描NFC卡片(連續)android

public class MainActivity extends Activity { 

    public static final String MIME_TEXT_PLAIN = "text/plain"; 
    public static final String TAG = "NfcDemo"; 

    private TextView mTextView; 
    private TextView mTextView2; 
    private NfcAdapter mNfcAdapter; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mTextView = (TextView) findViewById(R.id.textView_explanation); 

     mNfcAdapter = NfcAdapter.getDefaultAdapter(this); 

     if (mNfcAdapter == null) { 
       Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show(); 
      finish(); 
      return; 

     } 

     if (!mNfcAdapter.isEnabled()) { 
      mTextView.setText("NFC is disabled."); 
     } else { 
      mTextView.setText("Read Content : "); 
     } 

     handleIntent(getIntent()); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     setupForegroundDispatch(this, mNfcAdapter); 
    } 

    @Override 
    protected void onPause() { 

     stopForegroundDispatch(this, mNfcAdapter); 

     super.onPause(); 
    } 

    @Override 
    protected void onNewIntent(Intent intent) { 
      handleIntent(intent); 
    } 

    private void handleIntent(Intent intent) { 
     String action = intent.getAction(); 
     if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) { 

      String type = intent.getType(); 
      if (MIME_TEXT_PLAIN.equals(type)) { 

       Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 
       new NdefReaderTask().execute(tag); 

      } else { 
       Log.d(TAG, "Wrong mime type: " + type); 
      } 
     } else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) { 

      Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 
      String[] techList = tag.getTechList(); 
      String searchedTech = Ndef.class.getName(); 

      for (String tech : techList) { 
       if (searchedTech.equals(tech)) { 
        new NdefReaderTask().execute(tag); 
        break; 
       } 
      } 
     } 
    } 

    public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) { 
     final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass()); 
     intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 

     final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0); 

     IntentFilter[] filters = new IntentFilter[1]; 
     String[][] techList = new String[][]{}; 

     filters[0] = new IntentFilter(); 
     filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED); 
     filters[0].addCategory(Intent.CATEGORY_DEFAULT); 
     try { 
      filters[0].addDataType(MIME_TEXT_PLAIN); 
     } catch (MalformedMimeTypeException e) { 
      throw new RuntimeException("Check your mime type."); 
     } 

     adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList); 
    } 

    public static void stopForegroundDispatch(final Activity activity, NfcAdapter adapter) { 
     adapter.disableForegroundDispatch(activity); 
    } 

    private class NdefReaderTask extends AsyncTask<Tag, Void, String> { 

     @Override 
     protected String doInBackground(Tag... params) { 
      Tag tag = params[0]; 

      Ndef ndef = Ndef.get(tag); 
      if (ndef == null) { 
       // NDEF is not supported by this Tag. 
       return null; 
      } 

      NdefMessage ndefMessage = ndef.getCachedNdefMessage(); 

      NdefRecord[] records = ndefMessage.getRecords(); 
      for (NdefRecord ndefRecord : records) { 
       if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) { 
        try { 
         return readText(ndefRecord); 
        } catch (UnsupportedEncodingException e) { 
         Log.e(TAG, "Unsupported Encoding", e); 
        } 
       } 
      } 

      return null; 
     } 

     private String readText(NdefRecord record) throws UnsupportedEncodingException { 

      byte[] payload = record.getPayload(); 
      String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16"; 
      int languageCodeLength = payload[0] & 0063; 
      String languageCode = new String(payload, 1, languageCodeLength,"US-ASCII"); 
      return new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding); 
     } 

     @Override 
     protected void onPostExecute(String result) { 
      if (result != null) { 
       mTextView.setText("Read content: " + result); 
       } 

      } 
     } 
    } 


} 

現在我要實現的就是這一點 - 一旦我讀一張卡片,如果它有一個特定的數據值,我想我的應用程序應該等待幾秒鐘接受另一張卡片作爲輸入,然後我想比較這兩張卡片中的數據。 我該如何做到這一點?謝謝。

回答

1

首先,不需要通過Ndef對象實例檢索Android緩存的NDEF消息。 Android會爲您處理此問題,並將通過意向額外的EXTRA_NDEF_MESSAGES傳遞NDEF消息。所以,你可以立即在你handleIntent()方法來檢索NDEF消息:

private void handleIntent(Intent intent) { 
    String action = intent.getAction(); 
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action) || 
     NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) { 
     Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); 
     if ((rawMsgs != null) && (rawMsgs.length > 0)) { 
      NdefMessage ndefMsg = (NdefMessage)rawMsgs[0]; 
      if (ndefMsg != null) { 
       NdefRecord[] ndefRecs = ndefMsg.getRecords(); 
       if (ndefRecs != null) { 
        for (NdefRecord ndefRecord : records) { 
         if ((ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN) && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) { 
          processTextRecord(ndefRecord); 
         } 
        } 
       } 
      } 
     } 
    } 
} 

第二,如果你想,如果兩個標籤已經在一定時間內掃描,你可以做這樣的事情(我假設你只想要執行檢查,如果您的標籤包含文本記錄,並且您不介意潛在的時間戳-1轉角情況):

private long mLastTimestamp = -1; 
private final static long TIMEOUT = 5 * 1000 * 1000; // TIMEOUT between two taps in microseconds 
private void processTextRecord(NdefRecord ndefRecord) { 
    long currentTimestamp = System.nanoTime(); 
    if ((mLastTimestamp != -1) && ((currentTimestamp - mLastTimestamp) <= TIMEOUT)) { 
     // two taps of a tag (or two different tags) have occured within TIMEOUT nanoseconds 
     ... 
    } 
}