糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > android NFC读写卡Demo

android NFC读写卡Demo

时间:2020-03-26 23:15:55

相关推荐

android NFC读写卡Demo

学习链接:

/guide/topics/connectivity/nfc/nfc

/alex_wsc/android-wifi-nfc-gps/414141

第一步:AndroidManifest.xml中申明权限

<uses-permission android:name="android.permission.NFC"/><uses-feature android:name="android.hardware.nfc" android:required="true"/> 添加了这句代码,会使得在应用商店下载应用是过滤掉不支持NFC功能的设备。

第二步:AndroidManifest.xml中申明与NFC目标交互的activity

<activity android:name=".MainActivity"android:launchMode="singleTop"android:screenOrientation="portrait"android:windowSoftInputMode="adjustUnspecified|stateHidden"android:configChanges="orientation|keyboardHidden"><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.NDEF_DISCOVERED"/><category android:name="android.intent.category.DEFAULT"/><data android:mimeType="text/plain" /></intent-filter><intent-filter><action android:name="android.nfc.action.TAG_DISCOVERED"/></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>

这里声明了三种intent筛选条件,分别是action为

android.nfc.action.NDEF_DISCOVERED,

android.nfc.action.TECH_DISCOVERED,

android.nfc.action.TAG_DISCOVERED。

这一步可以帮助android系统内的NFC模块在扫描到一个NFC目标的时候寻找到我们的activity来进行交互。

android系统内的NFC模块在扫描到一个NFC目标后会通过以下几步来寻找到合适的处理NFC消息的activity。在这之前先介绍两个概念,1、Tag代表一个NFC目标,当android设备扫描到一个NFC目标的时候会将相关数据封装成一个Tag实例,通过Intent传递给合适的activity去做处理。2、TagTechnology表示NFC标签支持的技术,可以通过Tag的getTechList()获取。

Tag的分发步骤:

1、先看Tag中是否包含了系统支持的NDEF数据,如果包含则分发给注册了action为ACTION_NEDF_DISCOVERED的activity。

2、如果Tag中不包含系统支持的NDEF数据或者没有找到注册了action为ACTION_NDEF_DISCOVERED的activity,则NFC系统模块尝试分发给一个action为ACTION_TECH_DISCOVERED的activity。NFC系统模块在分发是首先分析NFC Tag支持的Tag Technology,然后寻找支持这类Tag Technology的activity,然后封装了Tag数据的Intent分发给对应的activity。

3、如果上面两种都不满足,则发送action为ACTION_TAG_DISCOVERED的intent

第三步,编写activity及相关工具类,和NFC目标进行读卡,发送指令等交互动作

public class MainActivity extends AppCompatActivity implements NfcView{private static final String TAG = MainActivity.class.getName();@BindView(R.id.rev_data) EditText mRevDataEt;@BindView(R.id.send_command_et) EditText mSendCommandEt;@BindView(R.id.read_btn) Button mReadCardBtn;@BindView(R.id.send_command_btn) Button mSendCommandBtn;private NfcHandler mNfcHandler;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.d(TAG, "onCreate()! ");mNfcHandler = new NfcHandler(this);mNfcHandler.init(this);ButterKnife.bind(this);}@Overrideprotected void onNewIntent(Intent intent) {Log.d(TAG, "onNewIntent()! action is:" + intent.getAction());super.onNewIntent(intent);setIntent(intent);}@Overrideprotected void onResume() {super.onResume();Log.d(TAG, "onResume()! intent action is:" + getIntent().getAction());mNfcHandler.enableNfc(this);}@Overrideprotected void onPause() {super.onPause();mNfcHandler.disableNfc(this);}@Overrideprotected void onDestroy() {super.onDestroy();mNfcHandler.onDestroy();}@Overridepublic void appendResponse(String response) {mRevDataEt.append(response);}@OnClick({R.id.send_command_btn, R.id.read_btn})void onBtnClick(View view) {switch (view.getId()) {case R.id.read_btn:mNfcHandler.readCardId(getIntent());break;case R.id.send_command_btn:mNfcHandler.sendCommand(this, mSendCommandEt.getText().toString());break;default:break;}}}

public class NfcHandler {private NfcAdapter mNfcAdapter;private IsoDep mIsoDep;private NfcView mView;public NfcHandler(NfcView view) {this.mView = view;}public void init(Context context) {mNfcAdapter = NfcAdapter.getDefaultAdapter(context);}private boolean checkNfc(Context context) {if (mNfcAdapter == null) {Toast.makeText(context, "未找到NFC设备!", Toast.LENGTH_SHORT).show();return false;} else if (!mNfcAdapter.isEnabled()) {Toast.makeText(context, "请在设置中打开NFC开关!", Toast.LENGTH_SHORT).show();return false;}return true;}/*** 通过tag.getTechList()可以获取当前目标Tag支持的Tag Technology,这里默认支持IsoDep。* 通过IsoDep.get(tag)方式获取IsoDep的实例。然后通过函数connect()我们应用和IC卡之间建立联系,* 建立联系后我们可以往IC卡发送指令进行交互。* @param intent*/private void connectNfc(Intent intent) {if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()) ||NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) ||NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);if (tag != null) {mIsoDep = IsoDep.get(tag);try {mIsoDep.connect(); //这里建立我们应用和IC卡} catch (IOException e) {e.printStackTrace();}}}}/*** 这个函数可以获取IC卡的序列号* @param intent*/public void readCardId(Intent intent) {Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);if (tag != null && mView != null) {byte[] ids = tag.getId();String uid = DataUtil.bytesToHexString(ids, ids.length);mView.appendResponse("\n uid is:" + uid);}}public void sendCommand(final Context context, final String command) {Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {@Overridepublic void subscribe(ObservableEmitter<String> emitter){if (mIsoDep == null) {emitter.onError(new Throwable("NFC设备未连接!"));return;}try {if (!mIsoDep.isConnected()) {mIsoDep.connect();}byte[] sendData = DataUtil.hexStringToBytes(command);if (sendData == null) {emitter.onError(new Throwable("指令输入有误!"));return;}byte[] responseData = mIsoDep.transceive(sendData);emitter.onNext(DataUtil.bytesToHexString(responseData, responseData.length));} catch (IOException e) {emitter.onError(new Throwable("NFC连接中断!"));}}});observable.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {@Overridepublic void accept(String s) {if (s == null) {Toast.makeText(context, "指令输入有误!", Toast.LENGTH_SHORT).show();} else {mView.appendResponse("\n apdu is:" + s);}}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) {Toast.makeText(context, throwable.getMessage(), Toast.LENGTH_SHORT).show();}});}public void enableNfc(Activity activity) {if (checkNfc(activity)) {PendingIntent pendingIntent = PendingIntent.getActivity(activity,0, new Intent(activity, activity.getClass()), 0);mNfcAdapter.enableForegroundDispatch(activity, pendingIntent, null, null);connectNfc(activity.getIntent());}}public void disableNfc(Activity activity) {if (mIsoDep != null && mIsoDep.isConnected()) {try{mIsoDep.close();} catch (IOException e) {e.printStackTrace();}}if (mNfcAdapter != null) {mNfcAdapter.disableForegroundDispatch(activity);}}public void onDestroy() {mView = null;}}

Demo地址:/Wcuren/android_nfc_demo

如果觉得《android NFC读写卡Demo》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。