0

I want to develop a android application witch can read the ID of a RFID card(mifare classic type A) usin NFC but my Application detect the card but it does not return any thing .. help please btw i hqve 2 class

class MainActivity:

package com.example.nfcreader;

import android.app.Activity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
static String TAG = "NFCREADER";

NFCForegroundUtil nfcForegroundUtil = null;

private TextView  info;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
   info = (TextView)findViewById(R.id.title);

    nfcForegroundUtil = new NFCForegroundUtil(this);
}

public void onPause() {
    super.onPause();
    nfcForegroundUtil.disableForeground();
}   

public void onResume() {
    super.onResume();
    nfcForegroundUtil.enableForeground();

    if (!nfcForegroundUtil.getNfc().isEnabled())
    {
        Toast.makeText(getApplicationContext(), 
                "Please activate NFC and press Back to return to the application!", 
                Toast.LENGTH_LONG).show();
        startActivity(
                new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
    }

}

public void onNewIntent(Intent intent) {
    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    /*StringBuilder sb = new StringBuilder();
    for(int i = 0; i < tag.getId().length; i++){
        sb.append(new Integer(tag.getId()[i]) + " ");
    }*/
   info.setText("TagID: " + bytesToHex(tag.getId()));    
    //byte[] id = tag.getId();
}

/**
 *  Convenience method to convert a byte array to a hex string.
 *
 * @param  data  the byte[] to convert
 * @return String the converted byte[]
 */

public static String bytesToHex(byte[] data) {
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < data.length; i++) {
        buf.append(byteToHex(data[i]).toUpperCase());
        buf.append(" ");
    }
    return (buf.toString());
}

/**
 *  method to convert a byte to a hex string.
 *
 * @param  data  the byte to convert
 * @return String the converted byte
 */
public static String byteToHex(byte data) {
    StringBuffer buf = new StringBuffer();
    buf.append(toHexChar((data >>> 4) & 0x0F));
    buf.append(toHexChar(data & 0x0F));
    return buf.toString();
}

/**
 *  Convenience method to convert an int to a hex char.
 *
 * @param  i  the int to convert
 * @return char the converted char
 */
public static char toHexChar(int i) {
    if ((0 <= i) && (i <= 9)) {
        return (char) ('0' + i);
    } else {
        return (char) ('a' + (i - 10));
    }
  }    

}

class NFCForegroundUtil:

package com.example.nfcreader;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.nfc.NfcAdapter;
import android.nfc.tech.NfcA;
import android.util.Log;

public class NFCForegroundUtil {
 private NfcAdapter nfc;

private Activity activity;
private IntentFilter intentFiltersArray[];
private PendingIntent intent;
private String techListsArray[][];

public NFCForegroundUtil(Activity activity) {
    super();
    this.activity = activity; 
    nfc = NfcAdapter.getDefaultAdapter(activity.getApplicationContext());

    intent = PendingIntent.getActivity(activity, 0, new Intent(activity,
            activity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

    IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);

    try {
        ndef.addDataType("*/*");
    } catch (MalformedMimeTypeException e) {
        throw new RuntimeException("Unable to speciy */* Mime Type", e);
    }
    intentFiltersArray = new IntentFilter[] { ndef };

    techListsArray = new String[][] { new String[] { NfcA.class.getName() } };

}

public void enableForeground()
{
    Log.d("demo", "Foreground NFC dispatch enabled");
    nfc.enableForegroundDispatch(
            activity, intent, intentFiltersArray, techListsArray);     
}

public void disableForeground()
{
    Log.d("demo", "Foreground NFC dispatch disabled");
    nfc.disableForegroundDispatch(activity);
}

public NfcAdapter getNfc() {
    return nfc;
  }   
}

and my AndroidManifest

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

 <uses-sdk 
   android:minSdkVersion="10"
   android:targetSdkVersion="20" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />

   <application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
         <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.TAG_DISCOVERED"/>
 <category android:name="android.intent.category.DEFAULT"/> 
</intent-filter> 

    </activity>
</application>

</manifest>
Michael Roland
  • 39,663
  • 10
  • 99
  • 206
Ahmed Jemli
  • 1
  • 1
  • 1
  • 1

4 Answers4

2

I'm going to assume you've looked here:

Near field communication overview

and here:

NFC basics

I've noticed some rather odd behaviors in onNewIntent in other contexts, so I would do as the second link above indicates:

public void onResume() {
    super.onResume();
    ...
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        if (rawMsgs != null) {
            msgs = new NdefMessage[rawMsgs.length];
            for (int i = 0; i < rawMsgs.length; i++) {
                msgs[i] = (NdefMessage) rawMsgs[i];
            }
        }
    }
    //process the msgs array
}

Also make sure your manifest is properly set up per the second links guidance

Wrigglenite
  • 119
  • 7
Nathaniel D. Waggoner
  • 2,856
  • 2
  • 19
  • 41
2

The intent filter that you are currently using for the foreground dispatch system is sensitive on tags that contain an NDEF record with the MIME type */*. Note that this seems to match any MIME type on some devices, even though the documentation clearly states (see this) that wildcard matching may only be used in the sub-type (e.g. text/*). So this may only match MIME types that contain the type */something.

Anyways, as you want to trigger upon any type A tag, I suggest, that you change your intent filter to actually trigger for any type A tag:

PendingIntent intent = PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter[] intentFilters = new IntentFilter[] {
    new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED),
};
String[][] techLists = new String[][] {
    new String[] {
        NfcA.class.getName()
    },
};
nfc.enableForegroundDispatch(
    activity,
    intent,
    intentFilters,
    techLists);

Moreover, you should avoid using the TAG_DISCOVERED intent filter in your app's manifest. This intent filter is meant as a fallback (and for backwards compatibility to API level 9) only. If you want your app to be started by a tag, use a specific filter instead (i.e. a TECH_DISCOVERED filter for NfcA or an NDEF_DISCOVERED filter for the NDEF message on your tag).

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
1

Mifare is not supported on all NFC enabled smart devices. Basically, the NFC controller needs to be manufactured from NXP controller. E.g. nexus 5 useses a broadcom chip set and thus can't read mifare. This is b/c NXP owns mifare classic and thus owns the propriety crypto-1 algorithm. Mifare classic sits between iso14443 part 3 and 4.

Paul
  • 652
  • 5
  • 16
0

I just had to do a similar thing on Android 9 with a Samsung Tab Active Pro and a MifareClassic NfcA with no Ndef data.

I found a sample app here that worked:

https://github.com/xamarin/monodroid-samples/tree/master/CardReader

That worked. One of the key parts was the following:

// Recommend NfcAdapter flags for reading from other Android devices. Indicates that this
// activity is interested in NFC-A devices (including other Android devices), and that the
// system should not check for the presence of NDEF-formatted data (e.g. Android Beam).
public NfcReaderFlags READER_FLAGS = NfcReaderFlags.NfcA | NfcReaderFlags.SkipNdefCheck;

Being passed into here:

    private void EnableReaderMode ()
    {
        Log.Info (TAG, "Enabling reader mode");
        Activity activity = this.Activity;
        NfcAdapter nfc = NfcAdapter.GetDefaultAdapter (activity);
        if (nfc != null)
        {
            nfc.EnableReaderMode(activity, mLoyaltyCardReader, READER_FLAGS , null);
        }
    }