Android 实现 NFC 读取卡片信息

news2024/11/24 7:45:03

效果图:

因为朋友需要个读取NFC卡片数据的功能,所以最近看了一下Android 系统下NFC 读取卡片信息的操作。

NFC(近距离无线通信 ) 是一组近距离无线技术,通常只有在距离不超过 4 厘米时才能启动连接.借助 NFC,您可以在 NFC 标签与 Android 设备之间或者两台 Android 设备之间共享小型负载。

支持 NFC 的 Android 设备同时支持以下三种主要操作模式:
  • 读取器/写入器模式:支持 NFC 设备读取和/或写入被动 NFC 标签和贴纸。

  • 点对点模式:支持 NFC 设备与其他 NFC 对等设备交换数据;- Android Beam 使用的就是此操作模式。

  • 卡模拟模式:支持 NFC 设备本身充当 NFC 卡。然后,可以通过外部 NFC 读取器(例如 NFC 销售终端)访问模拟 NFC 卡。

NFC读取卡片数据流程:
  • Android 设备通常会在屏幕解锁后查找 NFC 标签(停用NFC除外)

  • 卡片接近启动标签调度系统

  • 数据通过Intent携带数据启动Activity

 标签调度系统定义了三种 Intent,按优先级从高到低列出如下:

    1.  ACTION_NDEF_DISCOVERED:如果扫描到包含 NDEF 负载的标签,并且可识别其类型,则使用此 Intent 启动 Activity。这是优先级最高的 Intent,标签调度系统会尽可能尝试使用此 Intent 启动 Activity,在行不通时才会尝试使用其他 Intent。

    2.  ACTION_TECH_DISCOVERED :如果没有登记要处理 ACTION_NDEF_DISCOVERED Intent 的 Activity,则标签调度系统会尝试使用此 Intent 来启动应用。此外,如果扫描到的标签包含无法映射到 MIME 类型或 URI 的 NDEF 数据,或者该标签不包含 NDEF 数据,但它使用了已知的标签技术,那么也会直接启动此 Intent(无需先启动 ACTION_NDEF_DISCOVERED)。

    3.  ACTION_TAG_DISCOVERED:如果没有处理 ACTION_NDEF_DISCOVERED 或者 ACTION_TECH_DISCOVERED Intent 的 Activity,则使用此 Intent 启动 Activity。
  • 启动Activity 处理Intent携带的数据

实现读取北京地铁卡数据功能

1. 配置NFC权限

    <!--    API 级别 9 仅通过  所以最低是10版本-->
    <uses-sdk android:minSdkVersion="10" />
    <!--    NFC 权限  -->
    <uses-permission android:name="android.permission.NFC" />
    <!--    以便您的应用仅在那些具备 NFC 硬件的设备的 Google Play 中显示:-->
    <uses-feature
        android:name="android.hardware.nfc"
        android:required="true" />

2. 配置NFC拉起页面的过滤器选项

        <!--NFC启动的页面 -->
        <activity android:name=".NFCActivity">
            <!--  配置过滤启动类型-->
            <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" />

            <!--            <intent-filter>-->
            <!--                <action android:name="android.nfc.action.NDEF_DISCOVERED"/>-->
            <!--                <category android:name="android.intent.category.DEFAULT"/>-->
            <!--                <data android:scheme="http"-->
            <!--                    android:host="developer.android.com"-->
            <!--                    android:pathPrefix="/index.html" />-->
            <!--            </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>-->

        </activity>

注意 nfc_tech_filter.xml 是过滤NFC 卡片类型

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <!-- 可以处理所有Android支持的NFC类型 -->
    <tech-list>
        <tech>android.nfc.tech.IsoDep</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcB</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcF</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcV</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NdefFormatable</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.MifareUltralight</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.MifareClassic</tech>
    </tech-list>
</resources>

4. 启动页面代码

import android.content.Intent
import android.nfc.NdefMessage
import android.nfc.NdefRecord.createMime
import android.nfc.NfcAdapter
import android.nfc.NfcEvent
import android.nfc.Tag
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.wkq.nfc.databinding.ActivityMainBinding

/**
 * NFC 拉起页面
 */
class NFCActivity : AppCompatActivity(), NfcAdapter.CreateNdefMessageCallback {

    //支持的标签类型
    private var nfcAdapter: NfcAdapter? = null
    private var binding: ActivityMainBinding? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        nfcAdapter = NfcAdapter.getDefaultAdapter(this)
        if (nfcAdapter==null){
            Toast.makeText(this, "该机型不支持NFC", Toast.LENGTH_LONG).show()   
            finish()
        }
        // Register callback  *设置一个回调,使用Android Beam(TM)动态生成要发送的NDEF消息。
        nfcAdapter?.setNdefPushMessageCallback(this, this)
    }


    override fun onResume() {
        super.onResume()
        // Check to see that the Activity started due to an Android Beam
        if (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action) {
            processIntent(intent)
        }
    }

    override fun onPause() {
        super.onPause()
        nfcAdapter!!.disableReaderMode(this)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        setIntent(intent)
    }

    /**
     * 处理Intent携带的数据
     */
    private fun processIntent(intent: Intent) {
        // 处理北京公交卡的数据
        var tag = intent.extras
        if (tag==null)return
  
        var content = NFCUtil.bytesToHex((tag!!.get("android.nfc.extra.TAG") as Tag).id)
        binding?.tvContent!!.text = content
        Toast.makeText(this, "获取北京地铁卡数据:" + content, Toast.LENGTH_LONG).show()
    }

    override fun createNdefMessage(event: NfcEvent?): NdefMessage {
        val text = "Beam me up, Android!\n\n" +
                "Beam Time: " + System.currentTimeMillis()
        return NdefMessage(
            arrayOf(
                createMime("application/vnd.com.example.android.beam", text.toByteArray())
            )
        )

    }
}

这里是简单的利用NFC读取卡片数据的操作,具体的数据处理只是简单的处理了北京公交卡的数据,具体项目业务上需要读取什么卡数据需要项目中具体去处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/365735.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jenkins使用SSH拉取gitlab代码

jenkins机器上操作 1 创建密钥对 ssh-keygen (一路回车生成密钥对) ssh-copy-id -i id_rsa.pub xxx.xxx.xxx.xxx 2 查看公钥配置gitlab ssh cat /root/.ssh/id_rsa.pub 配置gitlab ssh 3 在jenkins配置私钥 cat /root/.ssh/id_rsa 完成以上操作后 在jenkins机器上执行git…

线程的执行

承接上文CPU原理简介程序的执行是由控制器发信号推动整个程序一步一步向前走&#xff0c;将数据存储在寄存器&#xff0c;从程序计数器中获取指令&#xff0c;比如先把3放到寄存器&#xff0c;再把5放到寄存器&#xff0c;再做一个加法&#xff0c;加法就是一个指令&#xff0c…

Redis官方可视化工具使用体验

前言 我们在使用redis不可避免的使用一些可视化工具&#xff0c;本文来介绍一下官方的可视化工具RedisInsight的使用体验 官方网址&#xff1a;https://docs.redis.com/latest/ri/ 傻瓜式下载安装&#xff0c;此处不作赘述 使用 安装完成后我们当然要先创建一个连接体验一…

九龙证券|全面注册制落地后IPO新增注册准备程序

历经科创板、北交所以及存量商场创业板试点注册制改革&#xff0c;资本商场总算迎来了全面注册制时代。 为确保全面注册制改革技能预备作业的顺利推进&#xff0c;近日&#xff0c;证监会拟定、发布了《监管规矩适用指引——发行类第8号&#xff1a;股票发行上市注册作业规程》…

KMP算法详细理解

一、目的1.KMP应用场景&#xff1a;可以解决字符串匹配问题&#xff1b; 在一个串中查找是否出现过另一个串。2.KMP的经典思想就是:当出现字符串不匹配时&#xff0c;可以记录一部分之前已经匹配的文本内容&#xff0c;利用这些信息避免从头再去做匹配。3.KMP算法关键在于&…

NTP同步时钟为医院提供标准的时间信号

NTP同步时钟应用于城市重要公共领域&#xff0c;如车站、学校、医院、等。NTP同步时钟可提供准确的公众时间&#xff0c;为人们的日常生活提供便利&#xff0c;避免了因时钟不准确而带来的不便。NTP同步时钟采用智能模块化设计&#xff0c;与同类产品相比&#xff0c;更突出了安…

LoRaWAN的网络协议是怎样的?有哪些应用?

LoRaWAN是一种低功耗广域物联网协议&#xff0c;其网络结构包括三个主要组件&#xff1a;终端设备&#xff08;End Device&#xff09;、网关&#xff08;Gateway&#xff09;和网络服务器&#xff08;Network Server&#xff09;。终端设备通常是一些低功耗设备&#xff0c;例…

LeetCode 206. 反转链表

LeetCode 206. 反转链表 难度&#xff1a;easy\color{Green}{easy}easy 题目描述 给你单链表的头节点 headheadhead &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&a…

51. N 皇后 (Swift 版本)

题目 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案。 …

2023年Java进阶架构师的必备思维导图,让你少走弯路!

架构师是什么&#xff1f;要做什么&#xff1f; 架构师 &#xff1a;是一个既需要掌控整体又需要洞悉局部瓶颈并依据具体的业务场景给出解决方案的团队领导型人物。架构师不是一个人&#xff0c;他需要建立高效的体系&#xff0c;带领团队去攻城略地&#xff0c;在规定的时间内…

nodejs基于vue社区失物招领+房屋租赁+停车+宠物互助平台

1、一般用户的功能及权限 所谓一般用户就是指还没有注册的过客,他们可以浏览主页面上的信息。但如果有中意的社区互助信息时&#xff0c;要登录注册&#xff0c;只有注册成功才有的权限。 2、管理员的功能及权限 用户信息的添加和管理&#xff0c;社区互助详细信息添加和管理和…

【机器学习】生成式模型和判别式模型

在机器学习中&#xff0c;对于有监督学习可以将其分为两类模型&#xff1a;判别式模型和生成式模型。判别式模型是针对条件分布建模&#xff0c;而生成式模型则针对联合分布进行建模。 1.抛砖引玉 假设有训练数据(X,Y)&#xff0c;X是属性集合&#xff0c;Y是类别标记。这时来了…

【十】深入理解redolog,undolog和binlog的底层原理

MySql系列整体栏目 内容链接地址【一】深入理解mysql索引本质https://blog.csdn.net/zhenghuishengq/article/details/121027025【二】深入理解mysql索引优化以及explain关键字https://blog.csdn.net/zhenghuishengq/article/details/124552080【三】深入理解mysql的索引分类&a…

Java进击框架:Spring(一)

Java进击框架&#xff1a;Spring&#xff08;一&#xff09;前言创建Spring项目Spring IoC容器和Beans介绍Bean的概述Spring IoC配置元数据实例化Bean依赖注入循环依赖详细配置生命周期回调Bean定义继承基于注解的容器配置Component和进一步的原型注解自动检测类和注册Bean定义…

Qt 第1课、Qt 的窗口组件和窗口类型

GUI 程序的开发原理&#xff1a; GUI 程序在运行的时候&#xff0c;操作系统会为它创造一个消息队列&#xff0c;消息队列用于存储操作系统发过来的系统消息。 用户使用操作系统的过程中&#xff0c;操作系统内核检测到用户的操作&#xff08;鼠标&#xff0c;键盘&#xff09…

[数据结构]时间复杂度与空间复杂度

[数据结构]时间复杂度与空间复杂度 如何衡量一个算法的好坏 long long Fib(int N) {if(N < 3)return 1;return Fib(N-1) Fib(N-2); } 这是一个求斐波那契数列的函数&#xff0c;使用递归的方法求得&#xff0c;虽然代码看起来很简洁&#xff0c;但是简洁真的就好吗&#…

Apache Hadoop生态部署-zookeeper单机安装

目录 查看服务架构图-服务分布、版本信息 一&#xff1a;安装前准备 1&#xff1a;zookeeper安装包选择--官网下载 2&#xff1a;zookeeper3.5.7安装包--百度网盘 二&#xff1a;安装与常用配置 2.1&#xff1a;下载解压zk安装包 2.2&#xff1a;配置修改 2.3&#xff1…

Codeforces Round #848 (Div. 2)(A~D)

A. Flip Flop Sum给出一个只有1和-1的数组&#xff0c;修改一对相邻的数&#xff0c;将它们变为对应的相反数&#xff0c;修改完后数组的和最大是多少。思路&#xff1a;最优的情况是修改一对-1&#xff0c;其次是一个1一个-1&#xff0c;否则修改两个1。AC Code&#xff1a;#i…

订单超时自动取消的 3 种解决方案,yyds!

大家对电商购物应该都比较熟悉了&#xff0c;我们应该注意到&#xff0c;在下单之后&#xff0c;通常会有一个倒计时&#xff0c;如果超过支付时间&#xff0c;订单就会被自动取消。下单今天&#xff0c;我们来聊聊订单超时未支付自动取消的几种方案。1.定时任务这是最容易想到…

啥是原神?女友说想要全角色语音+表情包,顺手用python把高清图也整下来了

原神全角色中日语音表情包高清图人生苦短 我用python表情包部分&#xff1a;1. 素材来自&#xff1a;2. 准备模块3. 调用浏览器驱动4. 页面滚动5. 保存数据5. 效果全角色语音高清彩图部分1.准备工具2. 准备模块3. 请求链接4. 本次目标5. 分析数据来源6. 开始代码7. 执行结果8. …