Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

The context is: Framework 4.5, Xamarin.Android v5.0

I want to use the NFC technology to implement shortcuts for my application users. I want the users to scan an NFC tag so they just have to put a value to a predefined scheme.

I have put some arguments in my NFC message and I do that when I write the message on my NFC tag:

    var tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
    var ndef = Ndef.Get(tag);
            NdefRecord external = NdefRecord.CreateExternal(applicationPackageName(), "letypetype", Encoding.ASCII.GetBytes("param"));
            NdefRecord appRecord = NdefRecord.CreateApplicationRecord(applicationPackageName());
            NdefMessage ndefMessage = new NdefMessage(external, appRecord);
    if (ndef != null)
        ndef.Connect();
        ndef.WriteNdefMessage(ndefMessage);

Then, I want to use it on my application, so I have put it in AndroidManifest.xml this:

<uses-feature android:name="android.hardware.nfc" android:required="true" />

And on my main activity I have the following intent filter:

     [IntentFilter(new[] { NfcAdapter.ActionNdefDiscovered },
      Categories = new[] { Intent.CategoryDefault },
      DataScheme = "vnd.android.nfc", DataPathPrefix = "letypetype",
     DataHost = "ext")]
        public class Activity1 : Activity
       { ...

And I try to handle my parameter in this activity with the override method OnResume:

    protected override void OnResume()
        base.OnResume();
        if (NfcAdapter.ActionNdefDiscovered.Equals(this.Intent.Action))
            IParcelable[] rawMsgs = this.Intent.GetParcelableArrayExtra(NfcAdapter.ExtraNdefMessages);
            if (rawMsgs != null)
                NdefMessage[] msgs = new NdefMessage[rawMsgs.Length];
                for (int i = 0; i < rawMsgs.Length; i++)
                    msgs[i] = (NdefMessage)rawMsgs[i];

But there is no way to get it back. So I'm pretty sure I do something wrong but I don't know what.

Sorry, I was off on friday. So yes I've tried your code, and I also add this line into my AndroidManifest.xml : <uses-permission android:name="android.permission.NFC" /> And yes, the tag launches the application, and after I try to access to extra information on my tag. But there is still no extra tag to access... So maybe the problem comes from the creation of my message... I don't know... – Le0n Nov 3, 2015 at 11:08 Did you solve the problem? Mark answer which hepled you or post your own answer for help people who have the same problem. – Majkl Dec 22, 2015 at 5:20

The problem that you are facing is a result of your wrong intent filter for the external record. What currently happens in your case is that the intent filter

[IntentFilter(new[] { NfcAdapter.ActionNdefDiscovered },
      Categories = new[] { Intent.CategoryDefault },
      DataScheme = "vnd.android.nfc",
      DataPathPrefix = "letypetype",
      DataHost = "ext")]

does not match the external record that you created using

NdefRecord external = NdefRecord.CreateExternal(
            applicationPackageName(),
            "letypetype",
            Encoding.ASCII.GetBytes("param"));

Instead, your activity is launched due to the Android Application Record (AAR). As theres was no matching NFC intent filter Android does not know that your activity supports NFC and, consequently, does not pass the tag (and its NDEF messages) to your activity.

In order to receive the NDEF messages/tag handle in your activity, you would therefore need to update the intent filter to match the external record. If the package name of the app is "com.example", then your intent filter would need to look like:

[IntentFilter(new[] { NfcAdapter.ActionNdefDiscovered },
      Categories = new[] { Intent.CategoryDefault },
      DataScheme = "vnd.android.nfc",
      DataPathPrefix = "/com.example:letypetype",
      DataHost = "ext")]

Note that the domain field and a leading slash need to be included into the DataPathPrefix attribute.

Also note that (while this usually works) a Java/Android package name is not a valid domain name according to the NFC Forum's specification of the external type. Instead, you should use a real domain name (e.g. "example.com").

And finally: don't forget to request the NFC permission in the manifest:

<uses-permission android:name="android.permission.NFC" />

If I well understand the question (if not correct me please), the problem is reading the data from the tag? Try the first simple reading through EnableForegroundDispatch and OnNewIntent and then customize for your needs.

private NfcAdapter mNfcAdapter;

In Activity OnCreate

  mNfcAdapter = NfcAdapter.GetDefaultAdapter(this);

In Activity OnResume

if (mNfcAdapter != null)
      var tagDetected = new IntentFilter(NfcAdapter.ActionTagDiscovered);//or try other Action type
      var filters = new[] { tagDetected };
      var intent = new Intent(this, GetType()).AddFlags(ActivityFlags.SingleTop);
      var pendingIntent = PendingIntent.GetActivity(this, 0, intent, 0);
      mNfcAdapter.EnableForegroundDispatch(this, pendingIntent, filters, null);

And overriede

    protected override void OnNewIntent(Intent intent)
  object obj = intent.GetParcelableExtra(NfcAdapter.ExtraTag);
  if (obj != null && obj is Tag)
    Tag t = (Tag)obj;
    byte[] id = t.GetId();
    string[] techList = t.GetTechList();
    int con = t.DescribeContents();
    string objName = t.ToString();

do not forget for in OnPause

if (mNfcAdapter != null) mNfcAdapter.DisableForegroundDispatch(this);

and OnDestroy

if (mNfcAdapter != null)
      mNfcAdapter.Dispose();
      mNfcAdapter = null;
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.