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.
–
–
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.