Android NFC read MifareClassic RFID tag, with android.nfc.action.TECH_DISCOVERED

This example show using intent-filter of "android.nfc.action.TECH_DISCOVERED", specify target tech of android.nfc.tech.MifareClassic, and read basic info my MifareClassic RFID tag.


Edit AndroidManifest.xml, to specify <uses-permission> of "android.permission.NFC", and <uses-feature> of "android.hardware.nfc".
Add <intent-filter>> of "android.nfc.action.TECH_DISCOVERED", and <meta-data> for "@xml/nfc_tech_filter".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blogspot.android_er.androidnfctechdiscovered" >

<uses-permission android:name="android.permission.NFC"/>
<uses-feature android:name="android.hardware.nfc"
android:required="true"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity" >
<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.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>


Create xml/nfc_tech_filter.xml. In order to make it simple, we specify one tech only, android.nfc.tech.MifareClassic.
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.MifareClassic</tech>
</tech-list>
</resources>

MainActivity.java
package com.blogspot.android_er.androidnfctechdiscovered;

import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareClassic;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

private NfcAdapter nfcAdapter;
TextView textViewInfo, textViewTagInfo;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewInfo = (TextView)findViewById(R.id.info);
textViewTagInfo = (TextView)findViewById(R.id.taginfo);

nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if(nfcAdapter == null){
Toast.makeText(this,
"NFC NOT supported on this devices!",
Toast.LENGTH_LONG).show();
finish();
}else if(!nfcAdapter.isEnabled()){
Toast.makeText(this,
"NFC NOT Enabled!",
Toast.LENGTH_LONG).show();
finish();
}
}

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

Intent intent = getIntent();
String action = intent.getAction();

if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
Toast.makeText(this,
"onResume() - ACTION_TECH_DISCOVERED",
Toast.LENGTH_SHORT).show();

Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if(tag == null){
textViewInfo.setText("tag == null");
}else{
String tagInfo = tag.toString() + "\n";

tagInfo += "\nTag Id: \n";
byte[] tagId = tag.getId();
tagInfo += "length = " + tagId.length +"\n";
for(int i=0; i<tagId.length; i++){
tagInfo += Integer.toHexString(tagId[i] & 0xFF) + " ";
}
tagInfo += "\n";

String[] techList = tag.getTechList();
tagInfo += "\nTech List\n";
tagInfo += "length = " + techList.length +"\n";
for(int i=0; i<techList.length; i++){
tagInfo += techList[i] + "\n ";
}

textViewInfo.setText(tagInfo);

//Only android.nfc.tech.MifareClassic specified in nfc_tech_filter.xml,
//so must be MifareClassic
readMifareClassic(tag);
}
}else{
Toast.makeText(this,
"onResume() : " + action,
Toast.LENGTH_SHORT).show();
}
}

public void readMifareClassic(Tag tag){
MifareClassic mifareClassicTag = MifareClassic.get(tag);

String typeInfoString = "--- MifareClassic tag ---\n";
int type = mifareClassicTag.getType();
switch(type){
case MifareClassic.TYPE_PLUS:
typeInfoString += "MifareClassic.TYPE_PLUS\n";
break;
case MifareClassic.TYPE_PRO:
typeInfoString += "MifareClassic.TYPE_PRO\n";
break;
case MifareClassic.TYPE_CLASSIC:
typeInfoString += "MifareClassic.TYPE_CLASSIC\n";
break;
case MifareClassic.TYPE_UNKNOWN:
typeInfoString += "MifareClassic.TYPE_UNKNOWN\n";
break;
default:
typeInfoString += "unknown...!\n";
}

int size = mifareClassicTag.getSize();
switch(size){
case MifareClassic.SIZE_1K:
typeInfoString += "MifareClassic.SIZE_1K\n";
break;
case MifareClassic.SIZE_2K:
typeInfoString += "MifareClassic.SIZE_2K\n";
break;
case MifareClassic.SIZE_4K:
typeInfoString += "MifareClassic.SIZE_4K\n";
break;
case MifareClassic.SIZE_MINI:
typeInfoString += "MifareClassic.SIZE_MINI\n";
break;
default:
typeInfoString += "unknown size...!\n";
}

int blockCount = mifareClassicTag.getBlockCount();
typeInfoString += "BlockCount \t= " + blockCount + "\n";
int sectorCount = mifareClassicTag.getSectorCount();
typeInfoString += "SectorCount \t= " + sectorCount + "\n";

textViewTagInfo.setText(typeInfoString);
}
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:orientation="vertical"
tools:context=".MainActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold"/>

<TextView
android:id="@+id/info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="italic"/>

<TextView
android:id="@+id/taginfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"/>

</LinearLayout>


Reference:
http://developer.android.com/guide/topics/connectivity/nfc/nfc.html
http://developer.android.com/guide/topics/connectivity/nfc/advanced-nfc.html
http://developer.android.com/reference/android/nfc/tech/MifareClassic.html

Next:
Android NFC: readBlock() for MifareClassic, to dump data in RFID tag