1
votes

I am new to NFC i want to NFC enabled android phone as NFC tag and read its data using NFC reader . It would be really great if you could suggest me the already build NFC apps for sending data or which NFC reader hardware should i go with.

2
So, Shubham, do You succeed in reaching Your aim? :) Because I have same problem, and it will be great , if You share Your experience. :)Victor
@Victor i used android phone instead of using NFC reader. there was some protocol issue it seems but between two android phones i was successful to send and receive data.shubham goel

2 Answers

2
votes

this is my NFC sending and Receiving code.

MainActivity sends files

public class MainActivity extends AppCompatActivity {

NfcAdapter nfcAdapter;
private PendingIntent mPendingIntent;
private IntentFilter[] mIntentFilters;
private String[][] mNFCTechLists;
private TextView mTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    nfcAdapter = NfcAdapter.getDefaultAdapter(this);

    mTextView = (TextView)findViewById(R.id.recive_text);
    PackageManager pm = this.getPackageManager();
    // Check whether NFC is available on device
    if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
        // NFC is not available on the device.
        Toast.makeText(this, "The device does not has NFC hardware.",
                Toast.LENGTH_SHORT).show();
    }
    // Check whether device is running Android 4.1 or higher
    else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
        // Android Beam feature is not supported.
        Toast.makeText(this, "Android Beam is not supported.",
                Toast.LENGTH_SHORT).show();
    }
    else {
        // NFC and Android Beam file transfer is supported.
        Toast.makeText(this, "Android Beam is supported on your device.",
                Toast.LENGTH_SHORT).show();
    }


    // create an intent with tag data and deliver to this activity
    mPendingIntent = PendingIntent.getActivity(this, 0,
            new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

    // set an intent filter for all MIME data
    IntentFilter ndefIntent = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
    try {
        ndefIntent.addDataType("*/*");
        mIntentFilters = new IntentFilter[] { ndefIntent };
    } catch (Exception e) {
        Log.e("TagDispatch", e.toString());
    }

    mNFCTechLists = new String[][] { new String[] { NfcF.class.getName() } };
}

public void sendFile(View view) {


    // Check whether NFC is enabled on device
    if(!nfcAdapter.isEnabled()){
        // NFC is disabled, show the settings UI
        // to enable NFC
        Toast.makeText(this, "Please enable NFC.",
                Toast.LENGTH_SHORT).show();
        startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
    }
    // Check whether Android Beam feature is enabled on device
    else if(!nfcAdapter.isNdefPushEnabled()) {
        // Android Beam is disabled, show the settings UI
        // to enable Android Beam
        Toast.makeText(this, "Please enable Android Beam.",
                Toast.LENGTH_SHORT).show();
        startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS));
    }
    else {


        Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
        chooseFile.setType("*/*");
        chooseFile = Intent.createChooser(chooseFile, "Choose a file");
        startActivityForResult(chooseFile, 1);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (data!=null) {
        Uri uri = data.getData();
        nfcAdapter.setBeamPushUris(new Uri[]{uri}, this);
    } else {
        Toast.makeText(this,"Please choose a file",Toast.LENGTH_SHORT).show();
    }
}


public void nextScreen(View view){
    startActivity(new Intent(MainActivity.this,SecondActivity.class));
}

public void reciveScreen(View view){
    startActivity(new Intent(MainActivity.this,RecieveScreen.class));
}


@Override
public void onNewIntent(Intent intent) {
    String action = intent.getAction();
    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

    String s = action + "\n\n" + tag.toString();

    // parse through all NDEF messages and their records and pick text type only
    Parcelable[] data = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);

    if (data != null) {
        try {
            for (int i = 0; i < data.length; i++) {
                NdefRecord[] recs = ((NdefMessage)data[i]).getRecords();
                for (int j = 0; j < recs.length; j++) {
                    if (recs[j].getTnf() == NdefRecord.TNF_WELL_KNOWN &&
                            Arrays.equals(recs[j].getType(), NdefRecord.RTD_TEXT)) {

                        byte[] payload = recs[j].getPayload();
                        String textEncoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16";
                        int langCodeLen = payload[0] & 0077;

                        s += ("\n\nNdefMessage[" + i + "], NdefRecord[" + j + "]:\n\"" +
                                new String(payload, langCodeLen + 1,
                                        payload.length - langCodeLen - 1, textEncoding) +
                                "\"");
                    }
                }
            }
        } catch (Exception e) {
            Log.e("TagDispatch", e.toString());
        }

    }

    mTextView.setText(s);
}

@Override
public void onResume() {
    super.onResume();

    if (nfcAdapter != null)
        nfcAdapter.enableForegroundDispatch(this, mPendingIntent, mIntentFilters, mNFCTechLists);
}

@Override
public void onPause() {
    super.onPause();

    if (nfcAdapter != null)
        nfcAdapter.disableForegroundDispatch(this);
}

}

This is my receiving screen, there may be some extra code but you can remove it

public class RecieveScreen extends AppCompatActivity {

private TextView mTextView;
private NfcAdapter mNfcAdapter;
private PendingIntent mPendingIntent;
private IntentFilter[] mIntentFilters;
private String[][] mNFCTechLists;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_recieve_screen);
    mTextView = (TextView)findViewById(R.id.recieve_tv);

    mNfcAdapter = NfcAdapter.getDefaultAdapter(this);

    if (mNfcAdapter != null) {
        mTextView.setText("Read an NFC tag");
    } else {
        mTextView.setText("This phone is not NFC enabled.");
    }

    // create an intent with tag data and deliver to this activity
    mPendingIntent = PendingIntent.getActivity(this, 0,
            new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

    // set an intent filter for all MIME data
    IntentFilter ndefIntent = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
    try {
        ndefIntent.addDataType("*/*");
        mIntentFilters = new IntentFilter[] { ndefIntent };
    } catch (Exception e) {
        Log.e("TagDispatch", e.toString());
    }

    mNFCTechLists = new String[][] { new String[] { NfcF.class.getName() } };
}


@Override
public void onNewIntent(Intent intent) {
    String action = intent.getAction();
    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

    String s = action + "\n\n" + tag.toString();

    // parse through all NDEF messages and their records and pick text type only
    Parcelable[] data = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);

    if (data != null) {
        try {
            for (int i = 0; i < data.length; i++) {
                NdefRecord[] recs = ((NdefMessage)data[i]).getRecords();
                for (int j = 0; j < recs.length; j++) {
                    if (recs[j].getTnf() == NdefRecord.TNF_WELL_KNOWN &&
                            Arrays.equals(recs[j].getType(), NdefRecord.RTD_TEXT)) {

                        byte[] payload = recs[j].getPayload();
                        String textEncoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16";
                        int langCodeLen = payload[0] & 0077;

                        s += ("\n\nNdefMessage[" + i + "], NdefRecord[" + j + "]:\n\"" +
                                new String(payload, langCodeLen + 1,
                                        payload.length - langCodeLen - 1, textEncoding) +
                                "\"");
                    }
                }
            }
        } catch (Exception e) {
            Log.e("TagDispatch", e.toString());
        }

    }

    mTextView.setText(s);
}

@Override
public void onResume() {
    super.onResume();

    if (mNfcAdapter != null)
        mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, mIntentFilters, mNFCTechLists);
}

@Override
public void onPause() {
    super.onPause();

    if (mNfcAdapter != null)
        mNfcAdapter.disableForegroundDispatch(this);
}
}

Let me know if you face any errors.

0
votes

Yes. You can use Android NFC Host-based card emulation(HCE).

https://developer.android.com/guide/topics/connectivity/nfc/hce

You can use your own HostApduService. But NFC reader should send APDU command to select your application ID(AID) at the first time. APDUs are defined in the ISO/IEC 7816-4 specification as well.

As mentioned previously, Android uses the AID to determine which HCE service the reader wants to talk to. Typically, the first APDU an NFC reader sends to your device is a "SELECT AID" APDU; this APDU contains the AID that the reader wants to talk to. Android extracts that AID from the APDU, resolves it to an HCE service, then forwards that APDU to the resolved service.

I am using ACR 122 NFC reader, I can use Android device as NFC card.

Please refer this git repo.

https://github.com/darryldecode/card-emulation

Thanks.