Android适配 - 实现4.3以后NFC的CardReader模式
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模式相关推荐
- Android 适配指南
AndroidVersionAdapter: 安卓版本适配全套指南 Android 版本适配全套指南 项目地址:Github.码云 当我在做 Android 版本适配工作的时候很痛苦,那个时候我在想有 ...
- 【Android】Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法
Android适配器之ArrayAdapter.SimpleAdapter和BaseAdapter的简单用法与有用代码片段 ArrayAdapter.SimpleAdapter和BaseAdapter ...
- android ui布局适配,Android适配全面总结(一)----屏幕适配
前言 Android适配是一个老生常谈的问题,很多程序员觉得很恶心,不愿意做适配,但是又不得不做.然后老板说,这位兄弟,做好了,今天晚饭给你加个鸡腿,然后程序员开始找各种资料,忙活起来了,最终在苦逼的 ...
- Android 适配(一)
一.Android适配基础参数 1.常见分辨率(px) oppx 2340x1080 oppR15 2280x1080 oppor11sp 2160*1080 1080*1920 (主流屏幕16:9) ...
- android底部滑动出现虚拟按键,Android适配底部虚拟按键的方法详解
Android适配底部虚拟按键的方法详解 发布时间:2020-10-09 05:26:12 来源:脚本之家 阅读:171 作者:yuanzhihui123 最近项目进行适配的时候发现部分(如华为手机) ...
- Android适配虚拟按键-亲测华为小米手机有效
Android适配虚拟按键-亲测华为小米手机有效 应用上传华为应用市场,结果被拒,原因是真人测试手机带虚拟按键,结果导致虚拟按键和屏幕某点击事件冲突,一点击就会退出到手机主页.废话不多说,直接上代码. ...
- Android适配全面屏
Android适配全面屏 测试了很多方法,下面这个是我找到的可以用的 首先sdk的版本要在28及以上 然后使用代码 在setContentView之前插入代码 @Overrideprotected v ...
- Android适配--dimen
说起Android适配,大家是不是觉得特别头疼,但是Android适配技能是每个Android程序员必备的,也是面试中会必须问到的. 适配的方式有好多种,什么图片适配啊,布局适配啊,当然还有现在的开源 ...
- Android适配全面总结(一)----屏幕适配
版权声明:本文为博主原创文章(部分引用他人博文,已加上引用说明),未经博主允许不得转载.https://www.jianshu.com/p/7aa34434ad4d 转载请标明出处: https:// ...
最新文章
- 机房收费--主界面(控件随窗体成比例改变)
- [再寄小读者之数学篇](2014-06-22 求导数 [中国科学技术大学2014年高等数学B考研试题])...
- Python小练习:批量删除多个文件夹内的相同文件
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
- yii2 mysql between_yii2:多条件多where条件下碰到between时,between语句如何处理呢?
- 用Unity开发一款塔防游戏(一):攻击方设计
- linux重置root密码
- mysql g月份分组_PowerBI快捷键——视觉对象分组功能
- ActionBar本部分适用述评
- 下厨房 APP 崩了!原来年夜饭都是边学边做?
- 清华大学MOOC《操作系统》第1讲:“操作系统概述”总结(转)
- Unit Testing with Sinon.JS
- 东北大学计算机学院生产实习,东北大学生产实习报告.doc
- 新西兰计算机预科学费,2018年新西兰ACG预科课程介绍(含学费、开学时间)
- yolov5使用GPU
- platformIO配合vscode搭建STM32开发平台
- 实验一 R语言的基本操作和数据组织
- 解决vagrant下载box过慢问题
- 2020-09-01 关于shiro的org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager异常
- NC移动审批2.0版本介绍