Regarding question (1): How to invoke NDEF_DISCOVERED
intent filter
Your activity ".activity.TagActivity_" filters has two different NDEF_DISCOVERED
. The first one matches if the intent contains a URI of the form "vnd.android.nfc://ext/abc:d". The second one matches if the intent contains a data type of "text/plain".
Consequently, you need to either add a matching URI or a matching MIME type to the intent that you use to start that activity.
MIME type "text/plain":
final Intent intent = new Intent(NfcAdapter.ACTION_NDEF_DISCOVERED);
intent.setType("text/plain");
startActivity(intent);
URI "vnd.android.nfc://ext/abc:d":
final Intent intent = new Intent(NfcAdapter.ACTION_NDEF_DISCOVERED);
intent.setData(Uri.parse("vnd.android.nfc://ext/abc:d"));
startActivity(intent);
Any of the two will start your activity.
NOTE that you specified android:permission="android.permission.NFC"
for your receiving activity. You normally would not do that. Specifying this permission means that your sending application needs to have that permission.
Regarding question (2): How to pass a mock tag object?
It's possible to create a mock tag object instance using reflection (note that this is not part of the public Android SDK, so it might fail for future Android versions).
Get the createMockTag()
method though reflection:
Class tagClass = Tag.class;
Method createMockTagMethod = tagClass.getMethod("createMockTag", byte[].class, int[].class, Bundle[].class);
Define some constants for preparing a valid mock NDEF tag instance:
final int TECH_NFC_A = 1;
final String EXTRA_NFC_A_SAK = "sak"; // short (SAK byte value)
final String EXTRA_NFC_A_ATQA = "atqa"; // byte[2] (ATQA value)
final int TECH_NDEF = 6;
final String EXTRA_NDEF_MSG = "ndefmsg"; // NdefMessage (Parcelable)
final String EXTRA_NDEF_MAXLENGTH = "ndefmaxlength"; // int (result for getMaxSize())
final String EXTRA_NDEF_CARDSTATE = "ndefcardstate"; // int (1: read-only, 2: read/write, 3: unknown)
final String EXTRA_NDEF_TYPE = "ndeftype"; // int (1: T1T, 2: T2T, 3: T3T, 4: T4T, 101: MF Classic, 102: ICODE)
Create an NDEF message:
NdefMessage ndefMessage = new NdefMessage(NdefRecord.createMime("text/plain"), "Text".getBytes("US-ASCII"));
Create the tech-extras bundle for a Type 2 tag with that NDEF message:
Bundle nfcaBundle = new Bundle();
nfcaBundle.putByteArray(EXTRA_NFC_A_ATQA, new byte[]{ (byte)0x44, (byte)0x00 }); //ATQA for Type 2 tag
nfcaBundle.putShort(EXTRA_NFC_A_SAK , (short)0x00); //SAK for Type 2 tag
Bundle ndefBundle = new Bundle();
ndefBundle.putInt(EXTRA_NDEF_MAXLENGTH, 48); // maximum message length: 48 bytes
ndefBundle.putInt(EXTRA_NDEF_CARDSTATE, 1); // read-only
ndefBundle.putInt(EXTRA_NDEF_TYPE, 2); // Type 2 tag
ndefBundle.putParcelable(EXTRA_NDEF_MSG, ndefMessage); // add an NDEF message
Prepare an anti-collision identifier/UID for your tag (see Tag.getId()
method). E.g. a 7-byte-UID for a Type 2 tag:
byte[] tagId = new byte[] { (byte)0x3F, (byte)0x12, (byte)0x34, (byte)0x56, (byte)0x78, (byte)0x90, (byte)0xAB };
Then you can create a mock tag instance by invoking the createMockTag()
method
Tag mockTag = (Tag)createMockTagMethod.invoke(null,
tagId, // tag UID/anti-collision identifier (see Tag.getId() method)
new int[] { TECH_NFC_A, TECH_NDEF }, // tech-list
new Bundle[] { nfcaBundle, ndefBundle }); // array of tech-extra bundles, each entry maps to an entry in the tech-list
Once you created that mock tag object, you can send it as part of the NDEF_DISCOVERED
intent:
Intent ndefIntent = new Intent(NfcAdapter.ACTION_NDEF_DISCOVERED);
ndefIntent.setType("text/plain");
ndefIntent.putExtra(NfcAdapter.EXTRA_ID, tagId);
ndefIntent.putExtra(NfcAdapter.EXTRA_TAG, mockTag);
ndefIntent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, new NdefMessage[]{ ndefMessage });
Optionally, you can explicitly define your target activity as the receiving component:
ndefIntent.setComponent(...); // or equivalent
You can then send this intent to your activity:
startActivity(ndefIntent);
The receiver can then use the moch tag object to retrieve instances of the technology classes (e.g. Ndef.get(tag)
) but any method that requires IO operations will fail.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…