Conrad Chan
- Forum posts: 2
Jul 9, 2012, 4:53:53 AM via Website
Jul 9, 2012 4:53:53 AM via Website
Hi, everyone. I am a beginner of android application development. I am developing my first android app which will auto launch after sensing a NFC tag and read the data from the tag. I have read examples from the android development page and other sites like stackoverflow, so I discover I have to make use of the foreground-dispatch method to overcome the mission. Here are the codes I wrote, however, some problems exist cause it cannot launch after the mobile device senses the tag, could anyone please help me to take a look and give some advices to me. Thank you!
I have divided my program into two java files, here is the main activity file:
public class NFC extends Activity {
NFCForeGround nfcForeGround = null;
NdefMessage[] messages = null;
@Override
public void onCreate(Bundle savedInstanceState) {
//Create the activity
super.onCreate(savedInstanceState);
//Form the layout
setContentView(R.layout.activity_nfc);
//Change the background color of layout
View mlayout = findViewById(R.id.laidout);
mlayout.setBackgroundColor(Color.GREEN);
//Give value to the variable
nfcForeGround = new NFCForeGround(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_nfc, menu);
return true;
}
@Override
public void onPause(){
//Pause the activity
super.onPause();
//Disable NFC Foreground dispatch
nfcForeGround.disable();
}
@Override
public void onResume(){
//Resume the activity
super.onResume();
//Enable the Foreground dispatch
nfcForeGround.enable();
}
@Override
public void onNewIntent(Intent intent){
//Set the intent
setIntent(intent);
//Get the action
String action = intent.getAction();
//Check if the action equals to Discover a NFC tag
if(nfcForeGround.getNfcAdapter().ACTION_NDEF_DISCOVERED.equals(action)||
nfcForeGround.getNfcAdapter().ACTION_TECH_DISCOVERED.equals(action)){
//Fetch the message
Parcelable[] rawMessage =
intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
//Check if rawMessage is null
if(rawMessage!=null){
//Check the rawMessage into NdefMessage format
messages = new NdefMessage[rawMessage.length];
for(int i=0; i<rawMessage.length; i++)
messages[i] = (NdefMessage) rawMessage[i];
}else{
//Message is not in Parcelable format
byte[] empty = new byte[] {};
//Fetch message and switch the format
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
NdefMessage message = new NdefMessage(new NdefRecord[]{
record
});
messages = new NdefMessage[]{
message
};
}
}else{
finish();
}
}
}
And below is the class of the NFC object:
public class NFCForeGround {
private NfcAdapter nfcadapter;
//Variables needed for using the enableForegroundDispatch function
private PendingIntent intent;
private Activity act;
private IntentFilter FilterArray[];
private String TechLists[][];
public NFCForeGround(Activity activity){
super();
//Set the variable act to activity
this.act = activity;
//Give value to variable nfcadapter
nfcadapter = NfcAdapter.getDefaultAdapter(activity.getApplicationContext());
//Give value to variable intent
intent = PendingIntent.getActivity(act, 0, new Intent(act,
act.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
//Give value to variable ndef
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
//Filter for the intent NfcAdapter.ACTION_NDEF_DISCOVERED with mime type "type/plain"
ndef.addDataType("text/plain");
} catch (MalformedMimeTypeException e) {
}
//Give value to FilterArray
FilterArray = new IntentFilter[]{ndef};
//Give value to TechLists
TechLists = new String[][]{new String[]{NfcA.class.getName()}};
}
public void enable(){
//Enable the Dispatch
nfcadapter.enableForegroundDispatch(act, intent, FilterArray, TechLists);
}
public void disable(){
//Disable the Dispatch
nfcadapter.disableForegroundDispatch(act);
}
public NfcAdapter getNfcAdapter() {
//Return the NFC Adapter variable
return nfcadapter;
}
}
And below is the AndroidManifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.nfc"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="15" />
<uses-feature android:name="android.hardware.nfc" android:required="true"/>
<uses-permission android:name="android.permission.NFC"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".NFC"
android:label="@string/title_activity_nfc" >
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.LAUNCHER" />
<data android:mimeType="mime/type"/>
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
</activity>
</application>
</manifest>
At last is the nfc_tech_filter file:
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.Ndef</tech>
<tech>android.nfc.tech.MifareUltralight</tech>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.IsoDep</tech>
<tech>android.nfc.tech.NdefFormatable</tech>
</tech-list>
</resources>
As you can see, I have added an intent-filter into the manifest file, also add a test list file to handle the tag, but I am not sure why it cannot work.
I have divided my program into two java files, here is the main activity file:
public class NFC extends Activity {
NFCForeGround nfcForeGround = null;
NdefMessage[] messages = null;
@Override
public void onCreate(Bundle savedInstanceState) {
//Create the activity
super.onCreate(savedInstanceState);
//Form the layout
setContentView(R.layout.activity_nfc);
//Change the background color of layout
View mlayout = findViewById(R.id.laidout);
mlayout.setBackgroundColor(Color.GREEN);
//Give value to the variable
nfcForeGround = new NFCForeGround(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_nfc, menu);
return true;
}
@Override
public void onPause(){
//Pause the activity
super.onPause();
//Disable NFC Foreground dispatch
nfcForeGround.disable();
}
@Override
public void onResume(){
//Resume the activity
super.onResume();
//Enable the Foreground dispatch
nfcForeGround.enable();
}
@Override
public void onNewIntent(Intent intent){
//Set the intent
setIntent(intent);
//Get the action
String action = intent.getAction();
//Check if the action equals to Discover a NFC tag
if(nfcForeGround.getNfcAdapter().ACTION_NDEF_DISCOVERED.equals(action)||
nfcForeGround.getNfcAdapter().ACTION_TECH_DISCOVERED.equals(action)){
//Fetch the message
Parcelable[] rawMessage =
intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
//Check if rawMessage is null
if(rawMessage!=null){
//Check the rawMessage into NdefMessage format
messages = new NdefMessage[rawMessage.length];
for(int i=0; i<rawMessage.length; i++)
messages[i] = (NdefMessage) rawMessage[i];
}else{
//Message is not in Parcelable format
byte[] empty = new byte[] {};
//Fetch message and switch the format
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
NdefMessage message = new NdefMessage(new NdefRecord[]{
record
});
messages = new NdefMessage[]{
message
};
}
}else{
finish();
}
}
}
And below is the class of the NFC object:
public class NFCForeGround {
private NfcAdapter nfcadapter;
//Variables needed for using the enableForegroundDispatch function
private PendingIntent intent;
private Activity act;
private IntentFilter FilterArray[];
private String TechLists[][];
public NFCForeGround(Activity activity){
super();
//Set the variable act to activity
this.act = activity;
//Give value to variable nfcadapter
nfcadapter = NfcAdapter.getDefaultAdapter(activity.getApplicationContext());
//Give value to variable intent
intent = PendingIntent.getActivity(act, 0, new Intent(act,
act.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
//Give value to variable ndef
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
//Filter for the intent NfcAdapter.ACTION_NDEF_DISCOVERED with mime type "type/plain"
ndef.addDataType("text/plain");
} catch (MalformedMimeTypeException e) {
}
//Give value to FilterArray
FilterArray = new IntentFilter[]{ndef};
//Give value to TechLists
TechLists = new String[][]{new String[]{NfcA.class.getName()}};
}
public void enable(){
//Enable the Dispatch
nfcadapter.enableForegroundDispatch(act, intent, FilterArray, TechLists);
}
public void disable(){
//Disable the Dispatch
nfcadapter.disableForegroundDispatch(act);
}
public NfcAdapter getNfcAdapter() {
//Return the NFC Adapter variable
return nfcadapter;
}
}
And below is the AndroidManifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.nfc"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="15" />
<uses-feature android:name="android.hardware.nfc" android:required="true"/>
<uses-permission android:name="android.permission.NFC"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".NFC"
android:label="@string/title_activity_nfc" >
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.LAUNCHER" />
<data android:mimeType="mime/type"/>
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
</activity>
</application>
</manifest>
At last is the nfc_tech_filter file:
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.Ndef</tech>
<tech>android.nfc.tech.MifareUltralight</tech>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.IsoDep</tech>
<tech>android.nfc.tech.NdefFormatable</tech>
</tech-list>
</resources>
As you can see, I have added an intent-filter into the manifest file, also add a test list file to handle the tag, but I am not sure why it cannot work.
Recommended editorial content
With your consent, external content is loaded here.
By clicking on the button above, you agree that external content may be displayed to you. Personal data may be transmitted to third-party providers in the process. You can find more information about this in our Privacy Policy.