2014-06-10 2 views
-1

NFC 카드에서 읽을 수 있고 NDEF 메시지를 읽을 수있는 간단한 Android 앱을 개발했습니다. 이제android에서 NFC 카드를 순차적으로 스캔

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가이 문제를 처리하고 NDF 메시지를 의도적으로 EXTRA_NDEF_MESSAGES으로 전달합니다. 그래서 당신은 즉시 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 
     ... 
    } 
} 
관련 문제