Tài liệu này mô tả các tác vụ NFC cơ bản mà bạn thực hiện trong Android. Hướng dẫn này giải thích cách gửi và nhận dữ liệu NFC dưới dạng thông báo NDEF và mô tả các API khung Android hỗ trợ các tính năng này. Để biết thêm các chủ đề nâng cao, bao gồm cả nội dung thảo luận về cách làm việc với dữ liệu không phải NDEF, hãy xem phần NFC nâng cao.
Có hai trường hợp sử dụng chính khi làm việc với dữ liệu NDEF và Android:
- Đọc dữ liệu NDEF từ thẻ NFC
- Chiếu thông báo NDEF từ thiết bị này sang thiết bị khác bằng Android BeamTM
Việc đọc dữ liệu NDEF từ thẻ NFC được xử lý bằng hệ thống gửi thẻ. Hệ thống này sẽ phân tích các thẻ NFC đã phát hiện, phân loại dữ liệu một cách phù hợp và khởi động một ứng dụng quan tâm đến dữ liệu đã phân loại. Một ứng dụng muốn xử lý thẻ NFC đã quét có thể khai báo bộ lọc ý định và yêu cầu xử lý dữ liệu.
Tính năng Android BeamTM cho phép một thiết bị đẩy thông báo NDEF sang một thiết bị khác bằng cách nhấn vật lý các thiết bị đó lại với nhau. Hoạt động tương tác này giúp gửi dữ liệu dễ dàng hơn so với các công nghệ không dây khác như Bluetooth, vì với NFC, bạn không cần phải tự khám phá hoặc ghép nối thiết bị theo cách thủ công. Kết nối tự động bắt đầu khi hai thiết bị trong phạm vi phủ sóng. Android Beam được cung cấp thông qua một bộ API NFC, vì vậy, mọi ứng dụng đều có thể truyền thông tin giữa các thiết bị. Ví dụ: các ứng dụng Danh bạ, Trình duyệt và YouTube sử dụng tính năng Truyền tia Android để chia sẻ danh bạ, trang web và video với các thiết bị khác.
Hệ thống điều phối thẻ
Các thiết bị chạy Android thường tìm thẻ NFC khi màn hình được mở khoá, trừ phi NFC bị tắt trong trình đơn Cài đặt của thiết bị. Khi một thiết bị chạy Android phát hiện thấy thẻ NFC, hành vi mong muốn là để hoạt động thích hợp nhất xử lý ý định mà không hỏi người dùng sẽ sử dụng ứng dụng nào. Vì các thiết bị quét thẻ NFC ở phạm vi rất ngắn, nên nhiều khả năng việc người dùng chọn một hoạt động theo cách thủ công sẽ buộc họ phải di chuyển thiết bị ra khỏi thẻ và ngắt kết nối. Bạn nên phát triển hoạt động của mình để chỉ xử lý các thẻ NFC mà hoạt động của bạn quan tâm nhằm ngăn Trình chọn hoạt động xuất hiện.
Để giúp bạn đạt được mục tiêu này, Android cung cấp một hệ thống phân phối thẻ đặc biệt giúp phân tích các thẻ NFC đã quét, phân tích cú pháp các thẻ đó và cố gắng xác định vị trí của các ứng dụng quan tâm đến dữ liệu đã quét. Trình quản lý thẻ của Google thực hiện việc này bằng cách:
- Phân tích cú pháp thẻ NFC và xác định loại MIME hoặc URI xác định tải trọng dữ liệu trong thẻ.
- Đóng gói loại MIME hoặc URI và tải trọng vào một ý định. Hai bước đầu tiên này được mô tả trong phần Cách thẻ NFC được ánh xạ với loại MIME và URI.
- Bắt đầu một hoạt động dựa trên ý định. Điều này được mô tả trong phần Cách thẻ NFC được điều phối đến các ứng dụng.
Cách thẻ NFC được ánh xạ với loại MIME và URI
Trước khi bắt đầu viết ứng dụng NFC, điều quan trọng là bạn phải hiểu nhiều loại thẻ NFC, cách hệ thống điều phối thẻ phân tích cú pháp thẻ NFC và công việc đặc biệt mà hệ thống điều phối thẻ thực hiện khi phát hiện thông báo NDEF. Thẻ NFC có rất nhiều công nghệ và cũng có thể ghi dữ liệu vào thẻ theo nhiều cách. Android hỗ trợ nhiều nhất cho tiêu chuẩn NDEF do Diễn đàn NFC xác định.
Dữ liệu NDEF được đóng gói trong một thông báo (NdefMessage
) chứa một hoặc nhiều bản ghi (NdefRecord
). Mỗi bản ghi NDEF phải được định dạng đúng theo thông số kỹ thuật của loại bản ghi mà bạn muốn tạo. Android cũng hỗ trợ các loại thẻ khác không chứa dữ liệu NDEF mà bạn có thể xử lý bằng cách sử dụng các lớp trong gói android.nfc.tech
. Để tìm hiểu thêm về các công nghệ này, hãy xem chủ đề NFC nâng cao. Khi xử lý các loại thẻ khác này, bạn cần viết ngăn xếp giao thức của riêng mình để giao tiếp với các thẻ. Vì vậy, bạn nên sử dụng NDEF khi có thể để dễ dàng phát triển và hỗ trợ tối đa cho thiết bị chạy Android.
Lưu ý: Để tải thông số kỹ thuật NDEF hoàn chỉnh xuống, hãy truy cập trang web Tài liệu về ứng dụng và thông số của diễn đàn NFC và xem bài viết Tạo các loại bản ghi NDEF phổ biến để xem ví dụ về cách tạo bản ghi NDEF.
Giờ đây, khi bạn đã có một số thông tin cơ bản về thẻ NFC, các phần sau đây sẽ mô tả chi tiết hơn về cách Android xử lý các thẻ có định dạng NDEF. Khi thiết bị chạy Android quét một thẻ NFC có chứa dữ liệu theo định dạng NDEF, thiết bị sẽ phân tích cú pháp thông báo và cố gắng tìm ra loại MIME của dữ liệu hoặc URI nhận dạng. Để thực hiện việc này, hệ thống sẽ đọc NdefRecord
đầu tiên bên trong NdefMessage
để xác định cách diễn giải toàn bộ thông báo NDEF (một thông báo NDEF có thể có nhiều bản ghi NDEF). Trong một thông báo NDEF được định dạng đúng cách, NdefRecord
đầu tiên
sẽ chứa các trường sau:
- TNF 3 bit (Định dạng tên loại)
- Cho biết cách diễn giải trường loại độ dài biến. Các giá trị hợp lệ được mô tả trong Bảng 1.
- Loại độ dài biến
- Mô tả loại bản ghi. Nếu sử dụng
TNF_WELL_KNOWN
, hãy dùng trường này để chỉ định Định nghĩa loại bản ghi (RTD). Các giá trị RTD hợp lệ được mô tả trong Bảng 2. - Mã độ dài biến
- Giá trị nhận dạng duy nhất của bản ghi. Trường này không được sử dụng thường xuyên, nhưng nếu cần xác định duy nhất một thẻ, bạn có thể tạo mã nhận dạng cho thẻ đó.
- Tải trọng có chiều dài thay đổi
- Tải trọng dữ liệu thực tế mà bạn muốn đọc hoặc ghi. Một thông báo NDEF có thể chứa nhiều bản ghi NDEF. Vì vậy, đừng giả định rằng toàn bộ tải trọng nằm trong bản ghi NDEF đầu tiên của thông báo NDEF.
Hệ thống điều phối thẻ sử dụng các trường loại và TNF để cố gắng liên kết một loại MIME hoặc URI với thông báo NDEF. Nếu thành công, mô-đun này sẽ đóng gói thông tin đó bên trong ý định ACTION_NDEF_DISCOVERED
cùng với tải trọng thực tế. Tuy nhiên, có những trường hợp hệ thống điều phối thẻ không thể xác định loại dữ liệu dựa trên bản ghi NDEF đầu tiên. Điều này xảy ra khi không thể ánh xạ dữ liệu NDEF tới một loại MIME hoặc URI, hoặc khi thẻ NFC không chứa dữ liệu NDEF để bắt đầu. Trong những trường hợp như vậy, đối tượng Tag
có thông tin về các công nghệ của thẻ và tải trọng sẽ được đóng gói bên trong ý định ACTION_TECH_DISCOVERED
.
Bảng 1 mô tả cách hệ thống điều phối thẻ ánh xạ các trường TNF và trường kiểu với các loại MIME hoặc URI. Hướng dẫn này cũng mô tả những TNF không thể ánh xạ tới một URI hoặc loại MIME.
Trong những trường hợp này, hệ thống điều phối thẻ sẽ quay lại dùng ACTION_TECH_DISCOVERED
.
Ví dụ: nếu hệ thống điều phối thẻ gặp một bản ghi thuộc loại TNF_ABSOLUTE_URI
, thì hệ thống sẽ ánh xạ trường loại độ dài biến số của bản ghi đó vào một URI. Hệ thống điều phối thẻ sẽ đóng gói URI đó trong trường dữ liệu của ý định ACTION_NDEF_DISCOVERED
cùng với các thông tin khác về thẻ, chẳng hạn như tải trọng. Mặt khác, nếu gặp bản ghi thuộc loại TNF_UNKNOWN
, thì mô-đun này sẽ tạo một ý định đóng gói công nghệ của thẻ.
Định dạng tên loại (TNF) | Liên kết |
---|---|
TNF_ABSOLUTE_URI |
URI dựa trên trường loại. |
TNF_EMPTY |
Quay lại ACTION_TECH_DISCOVERED . |
TNF_EXTERNAL_TYPE |
URI dựa trên URN trong trường loại. URN được mã hoá thành trường loại NDEF ở dạng rút gọn: <domain_name>:<service_name> .
Android ánh xạ mã này đến một URI có dạng: vnd.android.nfc://ext/<domain_name>:<service_name> . |
TNF_MIME_MEDIA |
Loại MIME dựa trên trường loại. |
TNF_UNCHANGED |
Không hợp lệ trong bản ghi đầu tiên, vì vậy hãy quay lại dùng ACTION_TECH_DISCOVERED . |
TNF_UNKNOWN |
Quay lại ACTION_TECH_DISCOVERED . |
TNF_WELL_KNOWN |
Loại MIME hoặc URI phụ thuộc vào Định nghĩa loại bản ghi (RTD) mà bạn đặt trong trường loại. Vui lòng xem Bảng 2 để biết thêm thông tin về các RTD hiện có và mối liên kết của các RTD đó. |
Định nghĩa loại bản ghi (RTD) | Liên kết |
---|---|
RTD_ALTERNATIVE_CARRIER |
Quay lại ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_CARRIER |
Quay lại ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_REQUEST |
Quay lại ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_SELECT |
Quay lại ACTION_TECH_DISCOVERED . |
RTD_SMART_POSTER |
URI dựa trên việc phân tích cú pháp tải trọng. |
RTD_TEXT |
Loại MIME của text/plain . |
RTD_URI |
URI dựa trên tải trọng. |
Cách thẻ NFC được gửi đến các ứng dụng
Khi tạo xong một ý định đóng gói thẻ NFC và thông tin nhận dạng thẻ, hệ thống điều phối thẻ sẽ gửi ý định đến một ứng dụng quan tâm để lọc ý định. Nếu nhiều ứng dụng có thể xử lý ý định, thì Trình chọn hoạt động sẽ hiển thị để người dùng có thể chọn Hoạt động. Hệ thống điều phối thẻ xác định 3 ý định, được liệt kê theo thứ tự ưu tiên cao nhất đến thấp nhất:
-
ACTION_NDEF_DISCOVERED
: Ý định này dùng để bắt đầu một Hoạt động khi một thẻ chứa tải trọng NDEF được quét và thuộc loại được nhận dạng. Đây là ý định có mức độ ưu tiên cao nhất và hệ thống điều phối thẻ sẽ cố gắng bắt đầu một Hoạt động bằng ý định này trước bất kỳ ý định nào khác, bất cứ khi nào có thể. ACTION_TECH_DISCOVERED
: Nếu không có hoạt động nào đăng ký để xử lý ý địnhACTION_NDEF_DISCOVERED
, thì hệ thống điều phối thẻ sẽ cố gắng khởi động ứng dụng bằng ý định này. Ý định này cũng được bắt đầu trực tiếp (không bắt đầuACTION_NDEF_DISCOVERED
trước) nếu thẻ được quét chứa dữ liệu NDEF không thể ánh xạ được tới loại MIME hay URI, hoặc nếu thẻ không chứa dữ liệu NDEF nhưng là công nghệ thẻ đã biết.ACTION_TAG_DISCOVERED
: Ý định này được bắt đầu nếu không có hoạt động nào xử lý ý địnhACTION_NDEF_DISCOVERED
hoặcACTION_TECH_DISCOVERED
.
Cách hoạt động cơ bản của hệ thống điều phối thẻ như sau:
- Hãy thử bắt đầu một Hoạt động bằng ý định do hệ thống điều phối thẻ tạo khi phân tích cú pháp thẻ NFC (
ACTION_NDEF_DISCOVERED
hoặcACTION_TECH_DISCOVERED
). - Nếu không có hoạt động nào lọc cho ý định đó, hãy thử bắt đầu một Hoạt động bằng ý định có mức độ ưu tiên thấp nhất tiếp theo (
ACTION_TECH_DISCOVERED
hoặcACTION_TAG_DISCOVERED
) cho đến khi ứng dụng lọc ý định hoặc cho đến khi hệ thống điều phối thẻ thử tất cả ý định có thể có. - Nếu không có ứng dụng nào lọc cho bất kỳ ý định nào, thì không cần làm gì cả.
Bất cứ khi nào có thể, hãy xử lý thông báo NDEF và ý định ACTION_NDEF_DISCOVERED
, vì ý định này là cụ thể nhất trong ba phương thức. Ý định này cho phép bạn khởi động ứng dụng tại thời điểm thích hợp hơn so với 2 ý định còn lại, mang lại trải nghiệm tốt hơn cho người dùng.
Yêu cầu quyền truy cập NFC trong tệp kê khai Android
Trước khi bạn có thể truy cập vào phần cứng NFC của thiết bị và xử lý đúng cách các ý định NFC, hãy khai báo các mục sau trong tệp AndroidManifest.xml
:
- Phần tử NFC
<uses-permission>
để truy cập vào phần cứng NFC:<uses-permission android:name="android.permission.NFC" />
- Phiên bản SDK tối thiểu mà ứng dụng của bạn có thể hỗ trợ. API cấp 9 chỉ hỗ trợ việc gửi thẻ có giới hạn qua
ACTION_TAG_DISCOVERED
và chỉ cấp quyền truy cập vào các thông báo NDEF thông qua phần bổ sungEXTRA_NDEF_MESSAGES
. Bạn không thể truy cập vào các thuộc tính thẻ hoặc thao tác I/O khác. API cấp 10 cung cấp tính năng hỗ trợ toàn diện cho trình đọc/người ghi cũng như tính năng đẩy NDEF trên nền trước. API cấp 14 cung cấp một cách dễ dàng hơn để đẩy thông báo NDEF đến các thiết bị khác bằng Android Beam và các phương thức bổ sung tiện lợi để tạo bản ghi NDEF.<uses-sdk android:minSdkVersion="10"/>
- Phần tử
uses-feature
để ứng dụng của bạn chỉ xuất hiện trong Google Play đối với các thiết bị có phần cứng NFC:<uses-feature android:name="android.hardware.nfc" android:required="true" />
Nếu ứng dụng dùng chức năng NFC nhưng chức năng đó không quan trọng với ứng dụng, thì bạn có thể bỏ qua phần tử
uses-feature
và kiểm tra xemgetDefaultAdapter()
có phải lànull
hay không trong thời gian chạy.
Lọc theo ý định NFC
Để khởi động ứng dụng khi thẻ NFC mà bạn muốn xử lý được quét được quét, ứng dụng của bạn có thể lọc cho một, hai hoặc cả ba ý định NFC trong tệp kê khai Android. Tuy nhiên, thường thì bạn sẽ muốn lọc ý định ACTION_NDEF_DISCOVERED
để kiểm soát chặt chẽ nhất thời điểm ứng dụng khởi động. Ý định ACTION_TECH_DISCOVERED
là phương án dự phòng cho ACTION_NDEF_DISCOVERED
khi không có ứng dụng nào lọc cho ACTION_NDEF_DISCOVERED
hoặc khi tải trọng không phải là NDEF. Bộ lọc cho ACTION_TAG_DISCOVERED
thường là quá chung chung của một danh mục nên không thể lọc được. Nhiều ứng dụng sẽ lọc tìm ACTION_NDEF_DISCOVERED
hoặc ACTION_TECH_DISCOVERED
trước ACTION_TAG_DISCOVERED
, vì vậy, ứng dụng của bạn có ít khả năng bắt đầu. ACTION_TAG_DISCOVERED
chỉ dành cho các ứng dụng như phương án cuối cùng cần lọc trong trường hợp không có ứng dụng nào khác được cài đặt để xử lý ý định ACTION_NDEF_DISCOVERED
hoặc ACTION_TECH_DISCOVERED
.
Vì cách triển khai thẻ NFC khác nhau và nhiều lần không thuộc quyền kiểm soát của bạn, nên điều này không phải lúc nào cũng có thể xảy ra. Đó là lý do bạn có thể dự phòng cho 2 ý định còn lại khi cần. Khi có quyền kiểm soát các loại thẻ và dữ liệu được ghi, bạn nên sử dụng NDEF để định dạng thẻ. Các phần sau đây mô tả cách lọc theo từng loại ý định.
ACTION_NDEF_discoveryED
Để lọc ý định ACTION_NDEF_DISCOVERED
, hãy khai báo bộ lọc ý định cùng với loại dữ liệu mà bạn muốn lọc. Ví dụ sau đây lọc các ý định ACTION_NDEF_DISCOVERED
có loại MIME là text/plain
:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain" /> </intent-filter>
Sau đây là ví dụ về các bộ lọc cho URI ở dạng https://developer.android.com/index.html
.
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="https" android:host="developer.android.com" android:pathPrefix="/index.html" /> </intent-filter>
ACTION_TECH_KHÁM PHÁ
Nếu hoạt động của bạn lọc ý định ACTION_TECH_DISCOVERED
, bạn phải tạo một tệp tài nguyên XML chỉ định các công nghệ mà hoạt động của bạn hỗ trợ trong một tập hợp tech-list
. Hoạt động của bạn được coi là khớp nếu tập hợp tech-list
là một tập hợp con của các công nghệ được thẻ hỗ trợ. Bạn có thể lấy hoạt động này bằng cách gọi getTechList()
.
Ví dụ: nếu thẻ được quét hỗ trợ Mifareclassic, NdefFormatable và NfcA, thì tập hợp tech-list
của bạn phải chỉ định cả ba, hai hoặc một trong các công nghệ (không chỉ định công nghệ nào khác) để hoạt động của bạn được so khớp.
Mẫu sau đây xác định tất cả công nghệ. Bạn phải xoá những mã không được thẻ NFC hỗ trợ. Lưu tệp này (bạn có thể đặt tên theo ý muốn) trong thư mục <project-root>/res/xml
.
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.IsoDep</tech> <tech>android.nfc.tech.NfcA</tech> <tech>android.nfc.tech.NfcB</tech> <tech>android.nfc.tech.NfcF</tech> <tech>android.nfc.tech.NfcV</tech> <tech>android.nfc.tech.Ndef</tech> <tech>android.nfc.tech.NdefFormatable</tech> <tech>android.nfc.tech.MifareClassic</tech> <tech>android.nfc.tech.MifareUltralight</tech> </tech-list> </resources>
Bạn cũng có thể chỉ định nhiều tập hợp tech-list
. Mỗi tập hợp tech-list
được xem xét độc lập và hoạt động của bạn sẽ được coi là khớp nếu bất kỳ tập hợp tech-list
nào là một tập hợp con của các công nghệ do getTechList()
trả về. Việc này cung cấp ngữ nghĩa AND
và OR
cho các công nghệ so khớp. Ví dụ sau đây khớp với các thẻ có thể hỗ trợ công nghệ NfcA và Ndef hoặc có thể hỗ trợ công nghệ NfcB và Ndef:
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.NfcA</tech> <tech>android.nfc.tech.Ndef</tech> </tech-list> <tech-list> <tech>android.nfc.tech.NfcB</tech> <tech>android.nfc.tech.Ndef</tech> </tech-list> </resources>
Trong tệp AndroidManifest.xml
, hãy chỉ định tệp tài nguyên mà bạn vừa tạo trong phần tử <meta-data>
bên trong phần tử <activity>
, như trong ví dụ sau:
<activity> ... <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED"/> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" /> ... </activity>
Để biết thêm thông tin về cách làm việc với các công nghệ thẻ và ý định ACTION_TECH_DISCOVERED
, hãy xem bài viết Làm việc với các công nghệ thẻ được hỗ trợ trong tài liệu NFC nâng cao.
ACTION_TAG_KHÁM PHÁ
Để lọc ACTION_TAG_DISCOVERED
, hãy sử dụng bộ lọc ý định sau:
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
Thu thập thông tin từ ý định
Nếu một hoạt động bắt đầu do ý định NFC, thì bạn có thể lấy thông tin về thẻ NFC đã quét qua ý định đó. Ý định có thể chứa các dữ liệu bổ sung sau tuỳ thuộc vào thẻ đã được quét:
EXTRA_TAG
(bắt buộc): Đối tượngTag
đại diện cho thẻ đã quét.EXTRA_NDEF_MESSAGES
(không bắt buộc): Một mảng các thông báo NDEF được phân tích cú pháp từ thẻ. Dữ liệu bổ sung này là bắt buộc đối với các ý địnhACTION_NDEF_DISCOVERED
.EXTRA_ID
(không bắt buộc): Mã cấp thấp của thẻ.
Để có được các dữ liệu bổ sung này, hãy kiểm tra xem hoạt động của bạn có được khởi chạy bằng một trong các ý định NFC hay không để đảm bảo rằng thẻ đã được quét, sau đó lấy các dữ liệu bổ sung từ ý định đó. Ví dụ sau đây sẽ kiểm tra ý định ACTION_NDEF_DISCOVERED
và lấy thông báo NDEF từ một ý định bổ sung.
Kotlin
override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) ... if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) { intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMessages -> val messages: List<NdefMessage> = rawMessages.map { it as NdefMessage } // Process the messages array. ... } } }
Java
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); ... if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) { Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); if (rawMessages != null) { NdefMessage[] messages = new NdefMessage[rawMessages.length]; for (int i = 0; i < rawMessages.length; i++) { messages[i] = (NdefMessage) rawMessages[i]; } // Process the messages array. ... } } }
Ngoài ra, bạn có thể lấy đối tượng Tag
qua ý định. Đối tượng này sẽ chứa tải trọng và cho phép bạn liệt kê các công nghệ của thẻ:
Kotlin
val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Tạo các loại bản ghi NDEF phổ biến
Phần này mô tả cách tạo các loại bản ghi NDEF phổ biến để trợ giúp bạn khi ghi vào thẻ NFC hoặc gửi dữ liệu bằng tính năng Truyền tia Android. Kể từ Android 4.0 (API cấp 14), phương thức
createUri()
sẽ có sẵn để giúp bạn tự động tạo
bản ghi URI. Kể từ Android 4.1 (API cấp 16), bạn có thể dùng createExternal()
và createMime()
để tạo bản ghi MIME và bản ghi NDEF loại bên ngoài. Hãy sử dụng các phương thức trợ giúp này bất cứ khi nào có thể để tránh sai sót khi tạo bản ghi NDEF theo cách thủ công.
Phần này cũng mô tả cách tạo bộ lọc ý định tương ứng cho bản ghi. Tất cả ví dụ về bản ghi NDEF phải có trong bản ghi NDEF đầu tiên của thông báo NDEF mà bạn đang ghi vào thẻ hoặc đang chiếu.
TNF_ABSOLUTE_URI
Lưu ý: Bạn nên sử dụng loại RTD_URI
thay vì TNF_ABSOLUTE_URI
, vì loại này hiệu quả hơn.
Bạn có thể tạo bản ghi NDEF TNF_ABSOLUTE_URI
theo cách sau:
Kotlin
val uriRecord = ByteArray(0).let { emptyByteArray -> NdefRecord( TNF_ABSOLUTE_URI, "https://developer.android.com/index.html".toByteArray(Charset.forName("US-ASCII")), emptyByteArray, emptyByteArray ) }
Java
NdefRecord uriRecord = new NdefRecord( NdefRecord.TNF_ABSOLUTE_URI , "https://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")), new byte[0], new byte[0]);
Bộ lọc ý định cho bản ghi NDEF trước sẽ có dạng như sau:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="https" android:host="developer.android.com" android:pathPrefix="/index.html" /> </intent-filter>
TNF_MIME_MEDIA
Bạn có thể tạo bản ghi NDEF TNF_MIME_MEDIA
theo các cách sau:
Sử dụng phương thức createMime()
:
Kotlin
val mimeRecord = NdefRecord.createMime( "application/vnd.com.example.android.beam", "Beam me up, Android".toByteArray(Charset.forName("US-ASCII")) )
Java
NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam", "Beam me up, Android".getBytes(Charset.forName("US-ASCII")));
Tạo NdefRecord
theo cách thủ công:
Kotlin
val mimeRecord = Charset.forName("US-ASCII").let { usAscii -> NdefRecord( NdefRecord.TNF_MIME_MEDIA, "application/vnd.com.example.android.beam".toByteArray(usAscii), ByteArray(0), "Beam me up, Android!".toByteArray(usAscii) ) }
Java
NdefRecord mimeRecord = new NdefRecord( NdefRecord.TNF_MIME_MEDIA , "application/vnd.com.example.android.beam".getBytes(Charset.forName("US-ASCII")), new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));
Bộ lọc ý định cho bản ghi NDEF trước sẽ có dạng như sau:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="application/vnd.com.example.android.beam" /> </intent-filter>
TNF_WELL_KNOWN với RTD_TEXT
Bạn có thể tạo bản ghi NDEF TNF_WELL_KNOWN
theo cách sau:
Kotlin
fun createTextRecord(payload: String, locale: Locale, encodeInUtf8: Boolean): NdefRecord { val langBytes = locale.language.toByteArray(Charset.forName("US-ASCII")) val utfEncoding = if (encodeInUtf8) Charset.forName("UTF-8") else Charset.forName("UTF-16") val textBytes = payload.toByteArray(utfEncoding) val utfBit: Int = if (encodeInUtf8) 0 else 1 shl 7 val status = (utfBit + langBytes.size).toChar() val data = ByteArray(1 + langBytes.size + textBytes.size) data[0] = status.toByte() System.arraycopy(langBytes, 0, data, 1, langBytes.size) System.arraycopy(textBytes, 0, data, 1 + langBytes.size, textBytes.size) return NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, ByteArray(0), data) }
Java
public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) { byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII")); Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16"); byte[] textBytes = payload.getBytes(utfEncoding); int utfBit = encodeInUtf8 ? 0 : (1 << 7); char status = (char) (utfBit + langBytes.length); byte[] data = new byte[1 + langBytes.length + textBytes.length]; data[0] = (byte) status; System.arraycopy(langBytes, 0, data, 1, langBytes.length); System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data); return record; }
Bộ lọc ý định cho bản ghi NDEF trước sẽ có dạng như sau:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter>
TNF_WELL_KNOWN với RTD_URI
Bạn có thể tạo bản ghi NDEF TNF_WELL_KNOWN
theo các cách sau:
Sử dụng phương thức createUri(String)
:
Kotlin
val rtdUriRecord1 = NdefRecord.createUri("https://example.com")
Java
NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");
Sử dụng phương thức createUri(Uri)
:
Kotlin
val rtdUriRecord2 = Uri.parse("https://example.com").let { uri -> NdefRecord.createUri(uri) }
Java
Uri uri = Uri.parse("https://example.com"); NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri);
Tạo NdefRecord
theo cách thủ công:
Kotlin
val uriField = "example.com".toByteArray(Charset.forName("US-ASCII")) val payload = ByteArray(uriField.size + 1) //add 1 for the URI Prefix payload [0] = 0x01 //prefixes https://www. to the URI System.arraycopy(uriField, 0, payload, 1, uriField.size) //appends URI to payload val rtdUriRecord = NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, ByteArray(0), payload)
Java
byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII")); byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix payload[0] = 0x01; //prefixes https://www. to the URI System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload NdefRecord rtdUriRecord = new NdefRecord( NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);
Bộ lọc ý định cho bản ghi NDEF trước sẽ có dạng như sau:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="https" android:host="example.com" android:pathPrefix="" /> </intent-filter>
TNF_EXTERNAL_TYPE
Bạn có thể tạo bản ghi NDEF TNF_EXTERNAL_TYPE
theo các cách sau:
Sử dụng phương thức createExternal()
:
Kotlin
var payload: ByteArray //assign to your data val domain = "com.example" //usually your app's package name val type = "externalType" val extRecord = NdefRecord.createExternal(domain, type, payload)
Java
byte[] payload; //assign to your data String domain = "com.example"; //usually your app's package name String type = "externalType"; NdefRecord extRecord = NdefRecord.createExternal(domain, type, payload);
Tạo NdefRecord
theo cách thủ công:
Kotlin
var payload: ByteArray ... val extRecord = NdefRecord( NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".toByteArray(Charset.forName("US-ASCII")), ByteArray(0), payload )
Java
byte[] payload; ... NdefRecord extRecord = new NdefRecord( NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".getBytes(Charset.forName("US-ASCII")), new byte[0], payload);
Bộ lọc ý định cho bản ghi NDEF trước sẽ có dạng như sau:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="vnd.android.nfc" android:host="ext" android:pathPrefix="/com.example:externalType"/> </intent-filter>
Sử dụng TNF_EXTERNAL_TYPE
để triển khai thẻ NFC tổng quát hơn nhằm hỗ trợ tốt hơn cho cả thiết bị chạy Android và không chạy Android.
Lưu ý: URN cho TNF_EXTERNAL_TYPE
có định dạng chính tắc: urn:nfc:ext:example.com:externalType
. Tuy nhiên, thông số kỹ thuật RTD của Diễn đàn NFC khai báo rằng phần urn:nfc:ext:
của URN phải được bỏ qua khỏi bản ghi NDEF. Vì vậy, bạn chỉ cần cung cấp miền (trong ví dụ này là example.com
) và nhập (trong ví dụ là externalType
) được phân tách bằng dấu hai chấm.
Khi gửi TNF_EXTERNAL_TYPE
, Android sẽ chuyển đổi urn:nfc:ext:example.com:externalType
URN thành URI vnd.android.nfc://ext/example.com:externalType
, đây là nội dung mà bộ lọc ý định trong ví dụ này khai báo.
Bản ghi ứng dụng Android
Ra mắt trong Android 4.0 (API cấp 14), Bản ghi ứng dụng Android (AAR) cung cấp độ chắc chắn mạnh mẽ hơn rằng ứng dụng của bạn được khởi động khi thẻ NFC được quét. AAR có tên gói của một ứng dụng được nhúng trong bản ghi NDEF. Bạn có thể thêm AAR vào bất kỳ bản ghi NDEF nào của thông báo NDEF, vì Android sẽ tìm kiếm toàn bộ thông báo NDEF cho các AAR. Nếu tìm thấy một AAR, thì nó sẽ khởi động ứng dụng dựa trên tên gói bên trong AAR. Nếu ứng dụng không có trên thiết bị, thì Google Play sẽ được khởi chạy để tải ứng dụng xuống.
AAR rất hữu ích nếu bạn muốn ngăn các ứng dụng khác lọc cho cùng một ý định và có thể xử lý các thẻ cụ thể mà bạn đã triển khai. Các AAR chỉ được hỗ trợ ở cấp ứng dụng do ràng buộc về tên gói, chứ không phải ở cấp Hoạt động như với tính năng lọc ý định. Nếu bạn muốn xử lý một ý định ở cấp Hoạt động, hãy sử dụng bộ lọc ý định.
Nếu một thẻ chứa AAR, thì hệ thống điều phối thẻ sẽ gửi đi theo cách sau:
- Thử bắt đầu một Hoạt động bằng cách sử dụng bộ lọc ý định như bình thường. Nếu Hoạt động khớp với ý định và cũng khớp với AAR, hãy bắt đầu Hoạt động.
- Nếu Hoạt động lọc ý định không khớp với AAR, nếu nhiều Hoạt động có thể xử lý ý định hoặc nếu không có Hoạt động nào xử lý ý định, hãy khởi động ứng dụng do AAR chỉ định.
- Nếu không có ứng dụng nào có thể bắt đầu bằng AAR, hãy truy cập Google Play để tải ứng dụng dựa trên AAR đó xuống.
Lưu ý: Bạn có thể ghi đè AAR và hệ thống điều phối ý định bằng hệ thống điều phối trên nền trước. Hệ thống này cho phép hoạt động ở nền trước được ưu tiên khi phát hiện thẻ NFC. Với phương thức này, hoạt động phải ở nền trước để ghi đè AAR và hệ thống điều phối ý định.
Nếu vẫn muốn lọc các thẻ đã quét không chứa AAR, thì bạn có thể khai báo các bộ lọc ý định như bình thường. Việc này sẽ hữu ích nếu ứng dụng của bạn quan tâm đến các thẻ khác không chứa AAR. Ví dụ: có thể bạn muốn đảm bảo rằng ứng dụng của bạn xử lý các thẻ độc quyền mà bạn triển khai cũng như các thẻ chung do bên thứ ba triển khai. Xin lưu ý rằng các tệp AAR dành riêng cho các thiết bị Android 4.0 trở lên, vì vậy, khi triển khai thẻ, rất có thể bạn muốn sử dụng kết hợp các loại/URI AAR và MIME để hỗ trợ nhiều loại thiết bị nhất. Ngoài ra, khi bạn triển khai thẻ NFC, hãy nghĩ về cách bạn muốn ghi thẻ NFC để có thể hỗ trợ hầu hết các thiết bị (thiết bị chạy Android và các thiết bị khác). Bạn có thể thực hiện việc này bằng cách xác định một loại MIME hoặc URI tương đối duy nhất để giúp ứng dụng dễ phân biệt hơn.
Android cung cấp một API đơn giản để tạo một AAR (đề xuất được tự động áp dụng) createApplicationRecord()
. Bạn chỉ cần nhúng AAR vào bất cứ đâu trong NdefMessage
. Bạn không muốn sử dụng bản ghi đầu tiên của NdefMessage
, trừ phi AAR là bản ghi duy nhất trong NdefMessage
. Điều này là do hệ thống Android kiểm tra bản ghi đầu tiên của NdefMessage
để xác định loại MIME hoặc URI của thẻ, được dùng để tạo ý định cho các ứng dụng lọc. Đoạn mã sau đây cho bạn biết cách tạo AAR:
Kotlin
val msg = NdefMessage( arrayOf( ..., NdefRecord.createApplicationRecord("com.example.android.beam") ) )
Java
NdefMessage msg = new NdefMessage( new NdefRecord[] { ..., NdefRecord.createApplicationRecord("com.example.android.beam")} ); )
Chiếu thông báo NDEF tới các thiết bị khác
Android Beam cho phép trao đổi dữ liệu ngang hàng đơn giản giữa hai thiết bị chạy Android. Ứng dụng muốn truyền dữ liệu tới một thiết bị khác phải ở nền trước và thiết bị nhận dữ liệu phải không bị khoá. Khi thiết bị phát tín hiệu tiếp xúc đủ gần với thiết bị thu, thiết bị phát tín hiệu sẽ hiển thị giao diện người dùng "Chạm để chiếu". Sau đó, người dùng có thể chọn có truyền thông báo tới thiết bị nhận hay không.
Lưu ý: Tính năng đẩy NDEF trên nền trước đã có ở API cấp 10, cung cấp chức năng tương tự như tính năng Truyền tia Android. Các API này kể từ đó đã ngừng hoạt động nhưng vẫn có sẵn để hỗ trợ các thiết bị cũ. Hãy xem enableForegroundNdefPush()
để biết thêm thông tin.
Bạn có thể bật Android Beam cho ứng dụng của mình bằng cách gọi một trong hai phương thức:
setNdefPushMessage()
: Chấp nhậnNdefMessage
để đặt làm thông báo cần truyền. Tự động phát thông báo khi 2 thiết bị ở đủ gần.setNdefPushMessageCallback()
: Chấp nhận lệnh gọi lại chứacreateNdefMessage()
. Lệnh này được gọi khi thiết bị nằm trong phạm vi để truyền dữ liệu đến. Lệnh gọi lại chỉ cho phép bạn tạo thông báo NDEF khi cần.
Một hoạt động chỉ có thể đẩy mỗi lần một thông báo NDEF, vì vậy, setNdefPushMessageCallback()
sẽ được ưu tiên hơn setNdefPushMessage()
nếu bạn đặt cả hai. Để sử dụng tính năng Truyền tia Android, bạn phải đáp ứng các nguyên tắc chung sau đây:
- Hoạt động đang chiếu dữ liệu phải ở nền trước. Cả hai thiết bị đều phải mở khoá màn hình.
- Bạn phải đóng gói dữ liệu mà bạn đang chiếu trong đối tượng
NdefMessage
. - Thiết bị NFC đang nhận dữ liệu được chiếu theo phải hỗ trợ giao thức đẩy NDEF
com.android.npp
hoặc SNEP (Giao thức trao đổi NDEF đơn giản) của Diễn đàn NFC. Giao thứccom.android.npp
là bắt buộc đối với các thiết bị ở API cấp 9 (Android 2.3) đến API cấp 13 (Android 3.2).com.android.npp
và SNEP đều là bắt buộc trên API cấp 14 (Android 4.0) trở lên.
Lưu ý: Nếu hoạt động của bạn bật tính năng Truyền tia Android và chạy ở nền trước, thì hệ thống điều phối ý định chuẩn sẽ bị tắt. Tuy nhiên, nếu hoạt động của bạn cũng bật tính năng gửi dữ liệu trên nền trước, thì hoạt động đó vẫn có thể quét những thẻ khớp với bộ lọc ý định đã đặt trong chế độ gửi trên nền trước.
Để bật tính năng Truyền tia Android:
- Tạo một
NdefMessage
chứa cácNdefRecord
mà bạn muốn đẩy sang thiết bị khác. - Gọi
setNdefPushMessage()
bằngNdefMessage
hoặc gọisetNdefPushMessageCallback
truyền vào đối tượngNfcAdapter.CreateNdefMessageCallback
trong phương thứconCreate()
của hoạt động. Các phương thức này đòi hỏi ít nhất một hoạt động mà bạn muốn bật bằng Android Beam, cùng với một danh sách không bắt buộc gồm các hoạt động khác cần kích hoạt.Nhìn chung, bạn thường sử dụng
setNdefPushMessage()
nếu Hoạt động của bạn chỉ cần đẩy cùng một thông báo NDEF vào mọi lúc, khi 2 thiết bị ở trong phạm vi giao tiếp. Bạn dùngsetNdefPushMessageCallback
khi ứng dụng quan tâm đến ngữ cảnh hiện tại của ứng dụng và muốn đẩy một thông báo NDEF tuỳ thuộc vào thao tác mà người dùng đang thực hiện trong ứng dụng.
Mẫu sau đây cho thấy cách một hoạt động đơn giản gọi NfcAdapter.CreateNdefMessageCallback
trong phương thức onCreate()
của một hoạt động (xem AndroidBeamdemo để biết mẫu đầy đủ). Ví dụ này cũng có các phương thức giúp bạn tạo bản ghi MIME:
Kotlin
package com.example.android.beam import android.app.Activity import android.content.Intent import android.nfc.NdefMessage import android.nfc.NdefRecord import android.nfc.NfcAdapter import android.nfc.NfcAdapter.CreateNdefMessageCallback import android.nfc.NfcEvent import android.os.Bundle import android.os.Parcelable import android.widget.TextView import android.widget.Toast import java.nio.charset.Charset class Beam : Activity(), NfcAdapter.CreateNdefMessageCallback { private var nfcAdapter: NfcAdapter? = null private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) textView = findViewById(R.id.textView) // Check for available NFC Adapter nfcAdapter = NfcAdapter.getDefaultAdapter(this) if (nfcAdapter == null) { Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show() finish() return } // Register callback nfcAdapter?.setNdefPushMessageCallback(this, this) } override fun createNdefMessage(event: NfcEvent): NdefMessage { val text = "Beam me up, Android!\n\n" + "Beam Time: " + System.currentTimeMillis() return NdefMessage( arrayOf( createMime("application/vnd.com.example.android.beam", text.toByteArray()) ) /** * The Android Application Record (AAR) is commented out. When a device * receives a push with an AAR in it, the application specified in the AAR * is guaranteed to run. The AAR overrides the tag dispatch system. * You can add it back in to guarantee that this * activity starts when receiving a beamed message. For now, this code * uses the tag dispatch system. *///,NdefRecord.createApplicationRecord("com.example.android.beam") ) } override fun onResume() { super.onResume() // Check to see that the Activity started due to an Android Beam if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) { processIntent(intent) } } override fun onNewIntent(intent: Intent) { // onResume gets called after this to handle the intent setIntent(intent) } /** * Parses the NDEF Message from the intent and prints to the TextView */ private fun processIntent(intent: Intent) { textView = findViewById(R.id.textView) // only one message sent during the beam intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMsgs -> (rawMsgs[0] as NdefMessage).apply { // record 0 contains the MIME type, record 1 is the AAR, if present textView.text = String(records[0].payload) } } } }
Java
package com.example.android.beam; import android.app.Activity; import android.content.Intent; import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.NfcAdapter.CreateNdefMessageCallback; import android.nfc.NfcEvent; import android.os.Bundle; import android.os.Parcelable; import android.widget.TextView; import android.widget.Toast; import java.nio.charset.Charset; public class Beam extends Activity implements CreateNdefMessageCallback { NfcAdapter nfcAdapter; TextView textView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView textView = (TextView) findViewById(R.id.textView); // Check for available NFC Adapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); if (nfcAdapter == null) { Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show(); finish(); return; } // Register callback nfcAdapter.setNdefPushMessageCallback(this, this); } @Override public NdefMessage createNdefMessage(NfcEvent event) { String text = ("Beam me up, Android!\n\n" + "Beam Time: " + System.currentTimeMillis()); NdefMessage msg = new NdefMessage( new NdefRecord[] { createMime( "application/vnd.com.example.android.beam", text.getBytes()) /** * The Android Application Record (AAR) is commented out. When a device * receives a push with an AAR in it, the application specified in the AAR * is guaranteed to run. The AAR overrides the tag dispatch system. * You can add it back in to guarantee that this * activity starts when receiving a beamed message. For now, this code * uses the tag dispatch system. */ //,NdefRecord.createApplicationRecord("com.example.android.beam") }); return msg; } @Override public void onResume() { super.onResume(); // Check to see that the Activity started due to an Android Beam if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { processIntent(getIntent()); } } @Override public void onNewIntent(Intent intent) { // onResume gets called after this to handle the intent setIntent(intent); } /** * Parses the NDEF Message from the intent and prints to the TextView */ void processIntent(Intent intent) { textView = (TextView) findViewById(R.id.textView); Parcelable[] rawMsgs = intent.getParcelableArrayExtra( NfcAdapter.EXTRA_NDEF_MESSAGES); // only one message sent during the beam NdefMessage msg = (NdefMessage) rawMsgs[0]; // record 0 contains the MIME type, record 1 is the AAR, if present textView.setText(new String(msg.getRecords()[0].getPayload())); } }
Xin lưu ý rằng mã này có nhận xét một AAR (đề xuất được tự động áp dụng) mà bạn có thể xoá. Nếu bạn bật AAR, thì ứng dụng được chỉ định trong AAR sẽ luôn nhận được thông báo Android Beam. Nếu không có ứng dụng thì Google Play sẽ bắt đầu tải ứng dụng xuống. Do đó, bộ lọc ý định sau đây là không cần thiết về mặt kỹ thuật đối với các thiết bị Android 4.0 trở lên nếu sử dụng AAR:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="application/vnd.com.example.android.beam"/> </intent-filter>
Với bộ lọc ý định này, ứng dụng com.example.android.beam
giờ đây có thể khởi động khi quét thẻ NFC hoặc nhận được Android Beam có AAR thuộc loại com.example.android.beam
hoặc khi thông báo có định dạng NDEF chứa bản ghi MIME thuộc loại application/vnd.com.example.android.beam
.
Mặc dù AAR đảm bảo một ứng dụng sẽ khởi động hoặc được tải xuống, nhưng bạn nên sử dụng các bộ lọc ý định vì các bộ lọc ý định này cho phép bạn bắt đầu một Hoạt động mà bạn chọn trong ứng dụng đó thay vì luôn bắt đầu Hoạt động chính trong gói do AAR chỉ định. AAR không có độ chi tiết cấp Hoạt động. Ngoài ra, vì một số thiết bị chạy Android không hỗ trợ AAR, bạn cũng nên nhúng thông tin nhận dạng vào bản ghi NDEF đầu tiên của thông báo NDEF và lọc cả thông báo đó để phòng trường hợp bị chặn. Xem phần Tạo các loại bản ghi NDEF phổ biến để biết thêm thông tin về cách tạo bản ghi.