2014-06-10 73 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 
     ... 
    } 
}