Is there a way to create an ACTION_NDEF_DISCOVERED

2019-03-05 03:34发布

问题:

For an app i'm writing i am wondering if it is possible to create an ACTION_NDEF_DISCOVERED intent from code. Normally this intent is created by the system when reading an ndef formatted tag. It contains a parcableextra of the type Tag.

The creation of the intent is probably easy but can you also create a Tag from code or is that not supported by the class as i suppose.

The goal is to broadcast a virtual tag with an ndef record to the system that then can be handled by an app that calls on the ACTION_NDEF_DISCOVERED intent.

回答1:

You could get a mock tag object instance using reflection. Something like this should work:

NdefMessage ndefMsg = ...;

Class tagClass = Tag.class;
Method createMockTagMethod = tagClass.getMethod("createMockTag", byte[].class, int[].class, Bundle[].class);

final int TECH_NFC_A = 1;
final int TECH_NDEF = 6;

final String EXTRA_NDEF_MSG = "ndefmsg";
final String EXTRA_NDEF_MAXLENGTH = "ndefmaxlength";
final String EXTRA_NDEF_CARDSTATE = "ndefcardstate";
final String EXTRA_NDEF_TYPE = "ndeftype";

Bundle ndefBundle = new Bundle();
ndefBundle.putInt(EXTRA_NDEF_MSG, 48); // result for getMaxSize()
ndefBundle.putInt(EXTRA_NDEF_CARDSTATE, 1); // 1: read-only, 2: read/write
ndefBundle.putInt(EXTRA_NDEF_TYPE, 2); // 1: T1T, 2: T2T, 3: T3T, 4: T4T, 101: MF Classic, 102: ICODE
ndefBundle.putParcelable(EXTRA_NDEF_MSG, ndefMsg);

Tag mockTag = (Tag)createMockTagMethod.invoke(null,
        new byte[] { (byte)0x12, (byte)0x34, (byte)0x56, (byte)0x78 },
        new int[] { TECH_NFC_A, TECH_NDEF },
        new Bundle[] { null, ndefBundle });

The problem with this is that you will not be able to connect to this tag. Consequently, all methods of the Ndef object (that you can get from that mock Tag instance) that require IO operations with a real tag or a real tag that is registered with the NFC service will fail. Specifically, only

  • getCachedNdefMessage(),
  • getMaxSize(),
  • getType(),
  • isWritable(), and
  • getTag()

will work.

So pretty much the same functionality would be available if you do not pass a Tag object as part of the NDEF_DISCOVERED intent and instead just use the EXTRA_NDEF_MESSAGES intent extra.