Simple Android NFC Program

gmaster picture gmaster · Jul 31, 2012 · Viewed 8.2k times · Source

I am working on a simple program for Android API 14 (4.0 - Ice Cream Sandwich) to test NFC (which I will then use in a bigger program). The program has two EditTexts, one labeled input and one labeled output. The goal is, when I tap two phones running the app together, for the text entered in the input box to appear in the output box of the other phone (this should work both ways). The code runs fine, but nothing happens when I tap the phones together. Code is below.

package com.sample.nfctest;

import java.sql.Date;

import android.app.Activity;
import android.content.Intent;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.EditText;
import android.widget.Toast;

public class NFCTestActivity extends Activity {

EditText input;
EditText output;
NfcAdapter mAdapter;
NdefMessage msgs[];
NdefRecord msg;
NfcAdapter nfcAdapter;
boolean somethingHappened = false;
double initialTime;
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    input = (EditText) findViewById(R.id.editText1);
    output = (EditText) findViewById(R.id.editText2);
    nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    if (nfcAdapter == null)
    {
        Toast.makeText(this, "No NFC.  Sucks to suck.", Toast.LENGTH_LONG).show();
        System.out.println("No NFC.  Sucks to suck.");
        return;
    }
    initialTime =  new Date(0).getTime();
    while(!somethingHappened)
    {
        if(30000 < new Date(0).getTime() - initialTime)
            somethingHappened = true;
        onResume();
    }
}
public void onResume() 
{
    super.onResume();
    msg = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, "text/plain".getBytes(), 
            new byte[0], input.getText().toString().getBytes());
    input.setText("");
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
        Intent intent = getIntent();
        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        if (rawMsgs != null) {
            somethingHappened = true;
            msgs = new NdefMessage[rawMsgs.length];
            for (int i = 0; i < rawMsgs.length; i++) {
                msgs[i] = (NdefMessage) rawMsgs[i];
                output.append(msgs[i].toString());
            }
        }           
    }
    //process the msgs array
    NdefRecord send[] = {msg};
    try{
        nfcAdapter.setNdefPushMessage(new NdefMessage(send), this);
        somethingHappened = true;
    }catch(Exception e){}
}
}

Here is the main.xml file.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<RelativeLayout
    android:id="@+id/relativeLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="15dp"
        android:text="@string/Inputs"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="300dp"
        android:layout_height="100dp"
        android:layout_below="@+id/textView1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="19dp" />


    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/editText1"
        android:layout_below="@+id/editText1"
        android:layout_marginTop="19dp"
        android:text="@string/Output"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/editText2"
        android:layout_width="300dp"
        android:layout_height="100dp"
        android:layout_alignLeft="@+id/textView2"
        android:layout_below="@+id/textView2"
        android:layout_marginTop="18dp" />

</RelativeLayout>

</LinearLayout>

And here is the manifest.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sample.nfctest"
android:versionCode="1"
android:versionName="1.0" >

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

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:name=".NFCTestActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>

<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme=""
    android:host="com.sample.nfctest"
    android:pathPrefix="" />
</intent-filter>

</manifest>

On a side note, is there a way to test an NFC application like this using the emulator? I'm borrowing someone's phone to test with (using a Nexus 7 and a Galaxy Nexus).

Thanks in advance.

Answer