TÌM HIỂU NFC TRÊN ANDROID: PHẦN 2
Bài đăng này đã không được cập nhật trong 9 năm
Tìm hiểu NFC trên Android: Phần 2
Tìm hiểu NFC trên Android: Phần 1
Trong bài trước chúng ta đã tìm hiểu tổng quan về công nghệ NFC trên Android, những ứng dụng thực tế của nó trong đời sống và demo sử dụng 2 thiết bị Android để truyền dữ liệu giữa 2 máy (Android to Android – P2P).
Trong phần này chúng ta tập trung vào việc làm thế nào để có thể đọc và ghi (read and write) dữ liệu trên 1 thẻ NFC (NFC Tag)!
Trên Android OS hỗ trợ các tiêu chuẩn của thẻ (NFC tag) và các lớp đại điện để làm việc với chúng trong bảng sau
Table 1. Các công nghệ thẻ được hỗ trợ
Các lớp | Mô tả |
---|---|
TagTechnology | Cài đặt interface này để có thể truy cập vào các công nghệ khác nhau và khả năng của chúng (nfc tag) |
NfcA | Cung cấp truy cập tới tiêu chuẩn NFC_A (ISO 14443-3A) và các hoạt động IO |
NfcB | Cung cấp truy cập tới tiêu chuẩn NFC-B (ISO 14443-3B) và các hoạt động IO |
NfcF | Cung cấp truy cập tới tiêu chuẩn NFC-F (JIS 6319-4) và các hoạt động IO |
NfcV | Cung cấp truy cập tới tiêu chuẩn NFC-V (ISO 15693) và các hoạt động IO |
IsoDep | Cung cấp truy cập tới tiêu chuẩn ISO-DEP (ISO 14443-4) và các hoạt động IO |
Ndef | Cung cấp truy cập tới các phương thức và dữ liệu NDEF trên thẻ NFC đã được định dạng (format) như NDEF |
NdefFormatable | Cũng cấp các phương thức để định dạng thẻ dưới dạng NDEF |
Trong khuôn khổ bài này chúng ta demo làm việc với thẻ được định dạng dưới dạng NDEF (tiêu chuẩn của NFC forum như trong bài trước đã nói).
Ứng dụng demo:
Tên: NfcWriteTag
Chức năng: Ghi dữ liệu tới thẻ NFC và đọc dữ liệu vừa ghi được
Yêu cầu:
-
Điện thoại Android:
-
Android API > 10 ( 2.3.3 – GINGERBREAD_MR1)
-
Hỗ trợ NFC (Enable NFC function )
NFC tags (được định dạng dưới dạng NDEF)
Như trong bài trước chúng ta cài đặt các thuộc tính trong AndroidManifest.xml để có thể nhận dạng được thẻ NFC khi chạm vào thiết bị Android.
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
Chú ý: Có các 3 loại IntentFilter sau khi làm việc với NFC
Trường | Mô tả |
---|---|
String ACTION_NDEF_DISCOVERED | Action của Intent để lọc các hành động khi 1 Tag với NDEF payload (nội dung đính kèm) được phát hiện |
String ACTION_TAG_DISCOVERED | Action của Intent để lọc các hành động khi 1 Tag được phát hiện |
String ACTION_TECH_DISCOVERED | Action của Intent để lọc các hành động khi 1 tag được phát hiện và các hoạt động đã được đăng ký cho các công nghệ cụ thể trên thẻ |
Tiếp theo, trong onCreate() của lớp WriteTagActivity.class chúng cài đặt các đối tượng để làm việc với NFC:
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if(mNfcAdapter == null) {
showToast("NFC not available on this device!");
return;
}
//Register a pending intent to callback to this activity when NFC tag discovered
pendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
//Filter NDEF Message
IntentFilter ndefDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
ndefDetected.addDataType("text/plain");
nfcIntentFilter = new IntentFilter[] { ndefDetected };
Trong hàm này NfcAdapter là 1 lớp đại diện cho NFC tại thiết bị giúp chúng ta tương tác với NFC.
Chúng ta đăng ký 1 callback cho lớp này sử dụng PendingIntent để nhận dữ liệu khi NFC được phát hiện.
Chúng ta cũng đăng ký 1 bộ lọc để lọc các hoạt động khi NDEF message được gửi tới sử dụng IntentFilter với action NfcAdapter.ACTION_NDEF_DISCOVERED để lọc các hành động khi 1 Tag được phát hiện có đính kèm (payload) các chuỗi (text/plain).
Tiếp theo, trong onResume() chúng ta triển khai các phương thức để phân tích gói tin nhận được khi NFC tag được phát hiện
@Override
protected void onResume() {
super.onResume();
//Discovery Tag and clear old intent
Intent intent = getIntent();
discoveryTag(intent);
enableNdefWriteMode();
}
discoveryTag() triển khai phân tích gói tin để nhận về payload
private void discoveryTag(Intent intent) {
//NFC tag discovered
if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
NdefMessage[] mess = getNdefMessages(intent);
String payload = new String(mess[0].getRecords()[0].getPayload());
//Turn Light ON
if(LIGHT_TAG.equals(payload)) {
imgLight.setImageResource(R.drawable.light_on);
}
showToast(payload);
setIntent(new Intent());
}
}
Cuối cùng, chúng ta muốn ghi dữ liệu trên thẻ NFC khi chúng được phát hiện, chúng ta triển khai trong hàm onNewIntent() (được gửi tới khi đăng ký sử IntentFilter với action FLAG_ACTIVITY_SINGLE_TOP)
@Override
protected void onNewIntent(Intent intent) {
Log.d("NFC_TAG", "onNewIntent > " + intent.getAction());
if (isWriteMode && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefMessage message = getTagAsNdef();
boolean success = writeTag(message, detectedTag);
if(success) {
showToast("Write NFC Success");
} else {
showToast("Write NFC Failed");
}
isWriteMode = false;
}
}
Chúng ta lấy về đối tượng Tag đại diện cho thẻ được phát hiện, sau đó tổng hợp 1 nội dung message (NDEF message) qua phương thức getTagAsNdef() để ghi dữ liệu vào thẻ.
GetTagAsNdef(): Tổng hợp NDEF message để ghi vào NFC tag
private NdefMessage getTagAsNdef() {
String uniqueId = LIGHT_TAG;//String value
byte[] payload = uniqueId.getBytes(Charset.forName("US-ASCII"));
NdefRecord rtdUriRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
NdefRecord.RTD_TEXT, new byte[0], payload);
return new NdefMessage(new NdefRecord[] { rtdUriRecord });
}
writeTag(): Ghi dữ liệu lên thẻ được phát hiện
public boolean writeTag(NdefMessage message, Tag tag) {
int size = message.toByteArray().length;
String mess = "";
try {
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect();
if (!ndef.isWritable()) {
showToast("Tag is read-only");
return false;
}
if (ndef.getMaxSize() < size) {
mess = "Tag capacity is " + ndef.getMaxSize() + " bytes, message is " + size
+ " bytes.";
showToast(mess);
return false;
}
//Write NDEF Message to TAG
ndef.writeNdefMessage(message);
return true;
} else {
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
try {
format.connect();
format.format(message);
mess = "Formatted tag and wrote message";
showToast(mess);
return false;
} catch (IOException e) {
mess = "Failed to format tag.";
showToast(mess);
return false;
}
} else {
mess = "Tag doesn't support NDEF.";
showToast(mess);
return false;
}
}
} catch (Exception e) {
mess = "Failed to write tag";
showToast(mess);
return false;
}
}
Full Source Code: NfcWriteTag
Một số hình ảnh:
Tham khảo:
All rights reserved