我开发了一个简单的Android应用程序,可以读取NFC卡上的NDEF消息。以下是该应用的代码 -
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);
}
}
}
}
}
现在我想要实现的是 - 一旦我读了一张卡并且它有一个特定的数据值,我希望我的应用程序应该等待几秒钟接受另一张卡作为输入,然后我想比较这两张卡中的数据。 我该如何实现这一目标?谢谢。
答案 0 :(得分: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);
}
}
}
}
}
}
}
其次,如果您想要在一定时间内扫描两个标签,您可以执行以下操作(我假设您只想执行该检查,如果您的标签包含文本记录而且您没有&# 39;请注意时间戳的潜在-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
...
}
}