NFC CPU,M1芯片基础知识

tag dispatch系统定义了三种intent:ACTION_NDEF_DISCOVERED、ACTION_TECH_DISCOVERED、ACTION_TAG_DISCOVERED。它们的优先级优先级分由高到低。对于要识别的CPU卡和m1卡来说,要过滤的是ACTION_TECH_DISCOVERED。


支持的tag技术

Class Description
TagTechnology The interface that all tag technology classes must implement.
NfcA Provides access to NFC-A (ISO 14443-3A) properties and I/O operations.
NfcB Provides access to NFC-B (ISO 14443-3B) properties and I/O operations.
NfcF Provides access to NFC-F (JIS 6319-4) properties and I/O operations.
NfcV Provides access to NFC-V (ISO 15693) properties and I/O operations.
IsoDep Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations.
Ndef Provides access to NDEF data and operations on NFC tags that have been formatted as NDEF.
NdefFormatable Provides a format operations for tags that may be NDEF formattable.


CPU卡对应识别的是IsoDep,m1卡对应的是NfcA。


设置过滤规则

<project-root>/res/xml新建xml文件下设置改过滤规则,文件名称可以自己随便写。我这里设置名称为nfc_tech_filter

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.IsoDep</tech>
        <tech>android.nfc.tech.NfcA</tech>
        <tech>android.nfc.tech.NfcB</tech>
        <tech>android.nfc.tech.NfcF</tech>
        <tech>android.nfc.tech.NfcV</tech>
        <tech>android.nfc.tech.Ndef</tech>
        <tech>android.nfc.tech.NdefFormatable</tech>
        <tech>android.nfc.tech.MifareClassic</tech>
        <tech>android.nfc.tech.MifareUltralight</tech>
    </tech-list>
</resources>



AndroidManifest.xml里设置下面规则。

<activity>
...
<intent-filter>
    <action android:name="android.nfc.action.TECH_DISCOVERED"/>
</intent-filter>

<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
    android:resource="@xml/nfc_tech_filter" />
...
</activity>

开启权限

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


设置true是开启谷歌play的,如果不用google play的可以不设置这个

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


AndroidManifest.xml里的设置大致如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.cardreader"
    android:versionCode="1"
    android:versionName="1.0">
 
    <!-- NFC Reader Mode was added in API 19. -->
    <!-- Min/target SDK versions (<uses-sdk>) managed by build.gradle -->
    <uses-permission android:name="android.permission.NFC" />
    <uses-feature android:name="android.hardware.nfc" android:required="true" />
 
    <application android:allowBackup="true"
        android:label="@string/app_name"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
                  android:label="@string/app_name"
                  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.TECH_DISCOVERED" />
            </intent-filter>
            <meta-data
                android:name="android.nfc.action.TECH_DISCOVERED"
                android:resource="@xml/nfc_tech_filter" />
        </activity>
    </application>
 
 
</manifest>


import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.NfcA;
import android.nfc.tech.NfcF;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.example.android.cardreader.R;


import java.io.IOException;

public class NFCActivity extends Activity implements OnClickListener {

	private NfcAdapter mAdapter;
	private PendingIntent mPendingIntent;
	private IntentFilter[] mFilters;
	private String[][] mTechLists;
	private TextView mText;
	private int mCount = 0;
	private EditText input;
	private Button ipbt;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_nfc);
		mText = (TextView) findViewById(R.id.text);
		input = (EditText) findViewById(R.id.input);
		ipbt = (Button) findViewById(R.id.input_button);
		ipbt.setOnClickListener(this);
		initNFC();

	}

	private void initNFC() {
		mAdapter = NfcAdapter.getDefaultAdapter(this);
		mPendingIntent = PendingIntent.getActivity(this, 0,
				new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
		IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
		try {
			ndef.addDataType("*/*");

		} catch (IntentFilter.MalformedMimeTypeException e) {
			throw new RuntimeException("fail", e);
		}
		mFilters = new IntentFilter[] { ndef, };
		mTechLists = new String[][] { { IsoDep.class.getName() }, { NfcA.class.getName() }, };
		Log.d(" mTechLists", NfcF.class.getName() + mTechLists.length);

		if (mAdapter == null) {
			Toast.makeText(this, "设备不支持NFC!", Toast.LENGTH_LONG).show();
			finish();
			return;
		}
		if (!mAdapter.isEnabled()) {
			Toast.makeText(this, "请在系统设置中先启用NFC功能!", Toast.LENGTH_LONG).show();
			finish();
			return;
		}
	}

	
	

	@Override
	protected void onResume() {
		super.onResume();
		if (mAdapter != null) {
			mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists);
		}
	}

	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		mText.setText("Discovered tag " + ++mCount + " with intent: " + intent);
		Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
		Log.e("tagFromIntent", "tagFromIntent" + tagFromIntent);
		if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
			// 处理该intent
			//***********************识别intent后,这里处理你要intent的操作*****************************************
			Log.d("TECH_DISCOVERED", "NfcAdapter.ACTION_TECH_DISCOVERED");
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (mAdapter != null) {
			mAdapter.disableForegroundDispatch(this);
		}

	}

	@Override
	public void onClick(View v) {
		

	}
}
里面的mTechLists = new String[][] { { IsoDep.class.getName() }, { NfcA.class.getName() }, };是设置要过滤的tag。IsoDep.class.getName() 对应CPU卡的tag,NfcA.class.getName()对应m1卡的。其他卡就设置对应的tag。后面有“,”是让其他不属于这两个标签的intent也能进来给其他intent过滤器操作。

enableForegroundDispatch设置前台过滤器,这个能在activity启动后,优先拦截对应的intent。即使有其他应用设置了ACTION_NDEF_DISCOVERED过滤也没有该优先级高。