Reputation: 7030
I'm trying to launch a specific activity when my phone scans an NFC Tag. This is what my manifest looks like:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lgandroid.ddcnfc"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.NFC"/>
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="16" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.lgandroid.ddcnfc.BluePrintActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<data android:mimeType="application/com.lgandroid.ddcnfc"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
android:name="com.lgandroid.ddcnfc.LoginActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.lgandroid.ddcnfc.MainActivity"
android:label="@string/app_name" >
</activity>
<activity
android:name="com.lgandroid.ddcnfc.PointDiagnosisActivity"
android:label="@string/app_name" >
</activity>
<activity
android:name="com.lgandroid.ddcnfc.PointControlActivity"
android:label="@string/app_name" >
</activity>
<activity
android:name="com.lgandroid.ddcnfc.SystemDiagnosisActivity"
android:label="@string/app_name" >
</activity>
<activity android:name="com.lgandroid.ddcnfc.SettingsActivity" android:label="@string/app_name"></activity>
</application>
Whenever I scan my tag, my main activity launches but I'd like my BluePrintActivity to launch. I'm not sure why this is the case. Here is my code for writing to tag:
private boolean writeTag(Tag tag) {
NdefRecord appRecord = NdefRecord.createApplicationRecord("com.lgandroid.ddcnfc");
NdefMessage message = new NdefMessage(new NdefRecord[] { appRecord });
try {
// see if tag is already NDEF formatted
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect();
if (!ndef.isWritable()) {
nfcTextView.setText("Read-only tag.");
return false;
}
// work out how much space we need for the data
int size = message.toByteArray().length;
if (ndef.getMaxSize() < size) {
nfcTextView.setText("Tag doesn't have enough free space.");
return false;
}
ndef.writeNdefMessage(message);
nfcTextView.setText("Tag written successfully.");
return true;
} else {
// attempt to format tag
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
try {
format.connect();
format.format(message);
nfcTextView.setText("Tag written successfully!\nClose this app and scan tag.");
return true;
} catch (IOException e) {
nfcTextView.setText("Unable to format tag to NDEF.");
return false;
}
} else {
nfcTextView.setText("Tag doesn't appear to support NDEF format.");
return false;
}
}
} catch (Exception e) {
nfcTextView.setText("Failed to write tag");
}
return false;
}
Edit: The answer I accepted above hinted me towards the right direction but since I was writing to a tag, the code in the accepted answer is not exactly the correct solution. If you are writing to a tag, this is what you need to do:
NdefRecord appRecord = new NdefRecord(
NdefRecord.TNF_MIME_MEDIA ,
"application/com.lgandroid.ddcnfc".getBytes(Charset.forName("US-ASCII")),
new byte[0], new byte[0]);
NdefMessage message = new NdefMessage(new NdefRecord[] { appRecord });
If you want to store a payload, just replace the last parameter "new byte[0]" to an appropriate data.
Upvotes: 13
Views: 8542
Reputation: 1843
As long as you only have an AAR stored on the tag, your application will be launched with its default activity (or the current activity stack, whatever it is). Therefore, the AAR should be the last record stored on a tag, only used to identify the app.
If you have an additional NDEF record that is matched by one of your Activities, there is a chance that the according Activity will be opened to handle the tag. However, my experiments and another question here indicate that this mechanism does not work as advertised.
An alternative solution might be to store a URL as one of the messages on the tag, opening a web page on a server you control (or going directly to Google Play).
Upvotes: 0
Reputation: 461
The reason your app starts is because you write an Android Application Record to the tag. This causes the application that has a matching package name to start up instead of the filtered activity.
Because you are filtering for a mime type you want to create a Mime Record with type 'application/com.lgandroid.ddcnfc' so instead of
NdefRecord appRecord = NdefRecord.createApplicationRecord("com.lgandroid.ddcnfc");
You should use:
NdefRecord appRecord = NdefRecord.createMimeRecord("application/com.lgandroid.ddcnfc", byteArray);
Upvotes: 10