Android How to - Use Near Field Communication








The following code shows how to Use Near Field Communication.

Code revised from
Android Recipes:A Problem-Solution Approach
http://www.apress.com/9781430234135
ISBN13: 978-1-4302-3413-5

Example

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.examples.nfcbeam"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="16" />
    <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=".NfcActivity"
            android:label="NfcActivity" 
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="application/com.example.androidrecipes.beamtext" />
            </intent-filter>
        </activity>
        <activity
            android:name=".BeamActivity"
            android:label="BeamActivity" 
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <data android:mimeType="image/*" />
            </intent-filter>
        </activity>
    </application>

</manifest>

res\layout\main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Select Image"
        android:onClick="onSelectClick" />
    <TextView
        android:id="@+id/text_uri"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <ImageView
        android:id="@+id/image_preview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="center" />
</LinearLayout>

BeamActivity.java

/* www.j a v a2s .co m*/
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateBeamUrisCallback;
import android.nfc.NfcAdapter.OnNdefPushCompleteCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

public class BeamActivity extends Activity implements CreateBeamUrisCallback, OnNdefPushCompleteCallback {
    private static final String TAG = "NfcBeam";
    private static final int PICK_IMAGE = 100;
    
    private NfcAdapter mNfcAdapter;
    private Uri mSelectedImage;
    
    private TextView mUriName;
    private ImageView mPreviewImage;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mUriName = (TextView) findViewById(R.id.text_uri);
        mPreviewImage = (ImageView) findViewById(R.id.image_preview);
        
        // Check for available NFC Adapter
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if (mNfcAdapter == null) {
            mUriName.setText("NFC is not available on this device.");
        } else {
            // Register callback to set NDEF message
            mNfcAdapter.setBeamPushUrisCallback(this, this);
            // Register callback to listen for message-sent success
            mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
        }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == PICK_IMAGE && resultCode == RESULT_OK && data != null) {
            mUriName.setText( data.getData().toString() );
            mSelectedImage = data.getData();
        }
    }
    
    @Override
    public void onResume() {
        super.onResume();
        // Check to see that the Activity started due to an Android Beam
        if (Intent.ACTION_VIEW.equals(getIntent().getAction())) {
            processIntent(getIntent());
        }
    }

    @Override
    public void onNewIntent(Intent intent) {
        // onResume gets called after this to handle the intent
        setIntent(intent);
    }

    void processIntent(Intent intent) {
        Uri data = intent.getData();
        if(data != null) {
            mPreviewImage.setImageURI(data);
        } else {
            mUriName.setText("Received Invalid Image Uri");
        }
    }
    
    public void onSelectClick(View v) {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        startActivityForResult(intent, PICK_IMAGE);
    }

    @Override
    public Uri[] createBeamUris(NfcEvent event) {
        if (mSelectedImage == null) {
            return null;
        }
        return new Uri[] {mSelectedImage};
    }
    
    @Override
    public void onNdefPushComplete(NfcEvent event) {
        Log.i(TAG, "Push Complete!");
    }
}

NfcActivity.java

import java.util.Date;
//from  www  .  jav  a2 s  . com
import android.app.Activity;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcAdapter.OnNdefPushCompleteCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.format.DateFormat;
import android.util.Log;
import android.widget.TextView;

public class NfcActivity extends Activity implements
        CreateNdefMessageCallback, OnNdefPushCompleteCallback {
    private static final String TAG = "NfcBeam";
    private NfcAdapter mNfcAdapter;
    private TextView mDisplay;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mDisplay = new TextView(this);
        setContentView(mDisplay);
        
        // Check for available NFC Adapter
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if (mNfcAdapter == null) {
            mDisplay.setText("NFC is not available on this device.");
        } else {
            // Register callback to set NDEF message.  Setting this makes
            // NFC data push active while the Activity is in the foreground.
            mNfcAdapter.setNdefPushMessageCallback(this, this);
            // Register callback to listen for message-sent success
            mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
        }
    }
    
    @Override
    public void onResume() {
        super.onResume();
        // Check to see if a Beam launched this Activity
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
            processIntent(getIntent());
        }
    }

    @Override
    public void onNewIntent(Intent intent) {
        // onResume gets called after this to handle the intent
        setIntent(intent);
    }

    void processIntent(Intent intent) {
        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        // only one message sent during the beam
        NdefMessage msg = (NdefMessage) rawMsgs[0];
        // record 0 contains the MIME type, record 1 is the AAR, if present
        mDisplay.setText(new String(msg.getRecords()[0].getPayload()));
    }
    
    @Override
    public NdefMessage createNdefMessage(NfcEvent event) {
        String text = String.format("Sending A Message From Android Recipes at %s",
                DateFormat.getTimeFormat(this).format(new Date()));
        NdefMessage msg = new NdefMessage(NdefRecord.createMime(
                "application/com.example.androidrecipes.beamtext", text.getBytes())
         /**
          * The Android Application Record (AAR) is commented out. When a device
          * receives a push with an AAR in it, the application specified in the AAR
          * is guaranteed to run. The AAR overrides the tag dispatch system.
          * You can add it back in to guarantee that this
          * activity starts when receiving a beamed message. For now, this code
          * uses the tag dispatch system.
          */
          //,NdefRecord.createApplicationRecord("com.examples.nfcbeam")
        );
        return msg;
    }
    
    @Override
    public void onNdefPushComplete(NfcEvent event) {
        //This callback happens on a binder thread, don't update
        // the UI directly from this method.
        Log.i(TAG, "Message Sent!");
    }
}