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过滤也没有该优先级高。