Android 4.4更新了NFC的读卡器模式,具体API差异可以查看官方报告,本篇将梳理Android 4.3、Android 4.4以及之后版本的NFC读卡器模式的写法。(主要是对CPU卡的操作)

官方更新说明

新的 NFC 读取器模式允许 Activity 将所有 NFC Activity 限制为在前台时仅读取 Activity 感兴趣的标记类型。您可以使用 enableReaderMode() 为您的 Activity 启用读取器模式,提供一个 NfcAdapter.ReaderCallback 的实现,用于在检测到新的标记时接收回调。

Android 4.3 NFC读卡器模式

import android.app.PendingIntent;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.NfcF;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;import java.util.Arrays;/*** Created by ZP on 2017/9/20.*/public class NfcJellyBeanActivity extends AppCompatActivity {private static final String TAG = "NfcJellyBeanActivity";private NfcAdapter mNfcAdapter;private PendingIntent pendingIntent;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mNfcAdapter = NfcAdapter.getDefaultAdapter(this);pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);}@Overrideprotected void onResume() {Log.d(TAG, "onResume: ");super.onResume();String[][] techListsArray = new String[][]{new String[]{NfcF.class.getName()},new String[]{IsoDep.class.getName()}};mNfcAdapter.enableForegroundDispatch(this, pendingIntent, null, techListsArray);}@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);if (intent != null) {Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);Log.d(TAG, "onNewIntent: " + Arrays.toString(tag.getTechList()));} else {Log.d(TAG, "onNewIntent: ");}}@Overrideprotected void onPause() {Log.d(TAG, "onPause: ");super.onPause();mNfcAdapter.disableForegroundDispatch(this);}
}

在生命周期onResume和onPause分别启动和禁止读卡器模式,一旦CPU卡片贴到手机NFC感应区,将回调到onNewIntent,并且NFC读取到的Tag将从intent中获取。

卡片贴紧NFC感应处后,输出日志:

D/NfcJellyBeanActivity: onNewIntent: [android.nfc.tech.IsoDep, android.nfc.tech.NfcA]

关键在于调用了NfcAdapter.enableForegroundDispatch()方法,此方法有四个参数,官方注释对四个参数都进行了详细的说明。

  • 第三个参数:涉及NFC标签的分发机制,官方说明如下图

  • 第四个参数:当分发ACTION_TECH_DISCOVERED时,可以设置处理Tag的类型。

  • 如果两个参数都设置为null,则全部Tag都分发给当前Activity进行处理。

Android 4.4 NFC读卡器模式

import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;import com.ppy.nfclib.Util;import java.util.Arrays;/*** Created by ZP on 2017/9/20.*/@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public class NfcKikKatActivity extends AppCompatActivity {private static final String TAG = "NfcKikKatActivity";private static final int READER_FLAGS = NfcAdapter.FLAG_READER_NFC_A| NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK | NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS;private NfcAdapter mNfcAdapter;private NfcAdapter.ReaderCallback mReaderCallback = new NfcAdapter.ReaderCallback() {@Overridepublic void onTagDiscovered(Tag tag) {Log.d(TAG, "onTagDiscovered: " + Arrays.toString(tag.getTechList()));}};@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Overrideprotected void onResume() {super.onResume();enableReaderMode();}@Overrideprotected void onPause() {super.onPause();disableReaderMode();}private void enableReaderMode() {Log.i(TAG, "Enabling reader mode");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);if (nfc != null) {nfc.enableReaderMode(this, mReaderCallback, READER_FLAGS, null);}}}private void disableReaderMode() {Log.i(TAG, "Disabling reader mode");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);if (nfc != null) {nfc.disableReaderMode(this);}}}
}

在生命周期onResume和onPause分别启动和禁止读卡器模式,一旦CPU卡片贴到手机NFC感应区,将回调到NfcAdapter.ReaderCallback,并且回调中返回NFC读取到的Tag。

卡片贴紧NFC感应处后,输出日志:

D/NfcKikKatActivity: onTagDiscovered: [android.nfc.tech.IsoDep, android.nfc.tech.NfcA]

Android 4.4之后关键在于调用了NfcAdapter.enableReaderMode() 方法,此方法需要四个参数,源码注释也给出详细说明。

  • 第二个参数是回调,一旦读取到合适的Tag,将分发给当前Activity处理时,将Tag回调。

  • 第三个参数是Flag,设置将处理Tag的类型,并且可以开启NFC读取到Tag时是否有系统默认声音。

  • 第四个参数可以null,也可以传一个带有NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY 字段的Bundle,这个参数用于对卡片的延迟检测。

Android 4.4 更新的API

  • 新增了NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY 用于Tag的回调

  • 新增了一些Flag,值得注意的是FLAG_READER_NO_PLATFORM_SOUNDS,可以禁止NFC标签时默认的系统声音。

具体参考官网

NFC适配库

封装了一个NFC读卡器模式的库,主要是对CPU卡的操作API,Sample已经完成读取羊城通和深圳通的卡号、余额、交易记录。详情可以看Github,欢迎提Issue和PR,一起完善。
https://github.com/scauzhangpeng/NfcSample

Android适配 - 实现4.3以后NFC的CardReader模式相关推荐

  1. Android 适配指南

    AndroidVersionAdapter: 安卓版本适配全套指南 Android 版本适配全套指南 项目地址:Github.码云 当我在做 Android 版本适配工作的时候很痛苦,那个时候我在想有 ...

  2. 【Android】Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法

    Android适配器之ArrayAdapter.SimpleAdapter和BaseAdapter的简单用法与有用代码片段 ArrayAdapter.SimpleAdapter和BaseAdapter ...

  3. android ui布局适配,Android适配全面总结(一)----屏幕适配

    前言 Android适配是一个老生常谈的问题,很多程序员觉得很恶心,不愿意做适配,但是又不得不做.然后老板说,这位兄弟,做好了,今天晚饭给你加个鸡腿,然后程序员开始找各种资料,忙活起来了,最终在苦逼的 ...

  4. Android 适配(一)

    一.Android适配基础参数 1.常见分辨率(px) oppx 2340x1080 oppR15 2280x1080 oppor11sp 2160*1080 1080*1920 (主流屏幕16:9) ...

  5. android底部滑动出现虚拟按键,Android适配底部虚拟按键的方法详解

    Android适配底部虚拟按键的方法详解 发布时间:2020-10-09 05:26:12 来源:脚本之家 阅读:171 作者:yuanzhihui123 最近项目进行适配的时候发现部分(如华为手机) ...

  6. Android适配虚拟按键-亲测华为小米手机有效

    Android适配虚拟按键-亲测华为小米手机有效 应用上传华为应用市场,结果被拒,原因是真人测试手机带虚拟按键,结果导致虚拟按键和屏幕某点击事件冲突,一点击就会退出到手机主页.废话不多说,直接上代码. ...

  7. Android适配全面屏

    Android适配全面屏 测试了很多方法,下面这个是我找到的可以用的 首先sdk的版本要在28及以上 然后使用代码 在setContentView之前插入代码 @Overrideprotected v ...

  8. Android适配--dimen

    说起Android适配,大家是不是觉得特别头疼,但是Android适配技能是每个Android程序员必备的,也是面试中会必须问到的. 适配的方式有好多种,什么图片适配啊,布局适配啊,当然还有现在的开源 ...

  9. Android适配全面总结(一)----屏幕适配

    版权声明:本文为博主原创文章(部分引用他人博文,已加上引用说明),未经博主允许不得转载.https://www.jianshu.com/p/7aa34434ad4d 转载请标明出处: https:// ...

最新文章

  1. 机房收费--主界面(控件随窗体成比例改变)
  2. [再寄小读者之数学篇](2014-06-22 求导数 [中国科学技术大学2014年高等数学B考研试题])...
  3. Python小练习:批量删除多个文件夹内的相同文件
  4. Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
  5. yii2 mysql between_yii2:多条件多where条件下碰到between时,between语句如何处理呢?
  6. 用Unity开发一款塔防游戏(一):攻击方设计
  7. linux重置root密码
  8. mysql g月份分组_PowerBI快捷键——视觉对象分组功能
  9. ActionBar本部分适用述评
  10. 下厨房 APP 崩了!原来年夜饭都是边学边做?
  11. 清华大学MOOC《操作系统》第1讲:“操作系统概述”总结(转)
  12. Unit Testing with Sinon.JS
  13. 东北大学计算机学院生产实习,东北大学生产实习报告.doc
  14. 新西兰计算机预科学费,2018年新西兰ACG预科课程介绍(含学费、开学时间)
  15. yolov5使用GPU
  16. platformIO配合vscode搭建STM32开发平台
  17. 实验一 R语言的基本操作和数据组织
  18. 解决vagrant下载box过慢问题
  19. 2020-09-01 关于shiro的org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager异常
  20. NC移动审批2.0版本介绍

热门文章

  1. 总结:那些热门的开源游戏服务器框架,还不看你就out了
  2. JAVA各种加密与解密方式
  3. 隧道无线通信覆盖与隧道调频广播覆盖方案
  4. 阿里巴巴风鸣:做技术Leader要有危机意识
  5. MySQL索引含义解析及使用
  6. 倾斜模型精细化处理_倾斜摄影与地面激光点云融合精细化建模研究
  7. 变电站三维激光扫描应用的介绍_吉优赛维数字孪生建模供应商
  8. Interview之CV:人工智能领域求职岗位—计算机视觉算法工程师的职位简介、薪资介绍、知识结构之详细攻略
  9. 【C】 打印菱形图案
  10. php分解字符串_php字符串分割的详解