关闭

Android NFC 使用MifareUltralight读写数据

标签: androidnfcUltraLight
1166人阅读 评论(0) 收藏 举报
分类:

一、概述:
Mifare UltraLight又称为MF0,从UltraLight(超轻的)这个名字就可以看出来,它是一个低成本、小容量的卡片。低成本,是指它是目前市场中价格最低的遵守ISO14443A协议的芯片之一;小容量,是指其存储容量只有512bit(Mifare S50有8192bit)。
Mifare UltraLight的512bit存储容量分成16个Page,每个Page包含4个字节,如下图所示:
这里写图片描述
Page0和Page1以及Page2的第1个字节是卡片的7字节序列号及其校验字节,其中BCC0=0x88⊕SN0⊕SN1⊕SN2,BCC1=SN3⊕SN4⊕SN5⊕SN6,SN0是制造商代码,由于Mifare UltraLight是NXP公司出品,因而SN0固定为04H。Page2的第2个字节Internal作为内部数据保留。以上共10个字节出厂时固化在存储区内,用户无法更改。
Page3是一次性烧录(One Time Programmable,OTP)页,该页的内容在卡片出厂时全部被写为“0”,用户使用时只能把某一位的内容写为“1”,而永远也不能把“1”写为0,也就是说,新写入的4字节内容与卡内原来的内容进行异或,异或后的结果存储在卡片中。
Page4-Page15是可读写的用户数据区,出厂时其内容初始化为0,用户可以任意读写。
Page2的第3和第4个字节用于将存储区锁定为只读。如下图所示,L4-L15的某一位设置为1,则对应序号的Page内容锁定为只读,每一个Page都可以单独设置。Lotp用于锁定Page3为只读。“螳螂捕蝉,黄雀在后”,Lotp-L15可以锁定别人,这些位本身又被三个BL位锁定,BL15-10用于锁定L15-L10,BL9-4用于锁定L9-L4,BLotp用于锁定Lotp。所有的这16个锁定位也具有OTP特性,通俗的讲就是这些“锁”没有“钥匙”,一旦锁死就再也改不回来了,所以锁定时一定要小心。

二、代码实现:

package com.app.views.nfc;

import android.app.PendingIntent;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareUltralight;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Toast;

import com.app.views.R;

import java.io.IOException;
import java.nio.charset.Charset;

public class MifareultralightActivity extends AppCompatActivity {

    private CheckBox mWriteData;
    private NfcAdapter mNfcAdapter;
    private PendingIntent mPendingIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mifareultralight);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        mWriteData = (CheckBox) findViewById(R.id.checkbox_write);
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()), 0);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mNfcAdapter != null) {
            mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mNfcAdapter != null) {
            mNfcAdapter.disableForegroundDispatch(this);
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        String[] techList = tag.getTechList();
        boolean flag = false;
        for (String tech : techList) {
            if (tech.indexOf("MifareUltralight") >= 0) {
                flag = true;
                break;
            }
        }
        if (!flag) {
            Toast.makeText(this, "不支持MifareUltralight数据格式", Toast.LENGTH_LONG).show();
            return;
        }

        if (mWriteData.isChecked()){
            writeTag(tag);
        }else {
            String data = readTag(tag);
            if (data != null)
                Toast.makeText(this, data, Toast.LENGTH_LONG).show();
        }
    }

    private String readTag(Tag tag) {
        MifareUltralight light = MifareUltralight.get(tag);
        try {
            light.connect();
            byte[] bytes = light.readPages(4);
            return  new String(bytes, Charset.forName("utf-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void writeTag(Tag tag) {
        MifareUltralight light = MifareUltralight.get(tag);
        try {
            light.connect();
            light.writePage(4,"china1".getBytes(Charset.forName("utf-8")));
            light.writePage(5,"china2".getBytes(Charset.forName("utf-8")));
            light.writePage(6,"china3".getBytes(Charset.forName("utf-8")));
            light.writePage(7,"china4".getBytes(Charset.forName("utf-8")));
            Toast.makeText(this, "成功写入MifareUltralight格式数据!", Toast.LENGTH_LONG)
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                light.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

———————————————————————
(java 架构师全套教程,共760G, 让你从零到架构师,每月轻松拿3万)
有需求者请进站查看,非诚勿扰

https://item.taobao.com/item.htm?spm=686.1000925.0.0.4a155084hc8wek&id=555888526201

01.高级架构师四十二个阶段高
02.Java高级系统培训架构课程148课时
03.Java高级互联网架构师课程
04.Java互联网架构Netty、Nio、Mina等-视频教程
05.Java高级架构设计2016整理-视频教程
06.架构师基础、高级片
07.Java架构师必修linux运维系列课程
08.Java高级系统培训架构课程116课时
(送:hadoop系列教程,java设计模式与数据结构, Spring Cloud微服务, SpringBoot入门)
——————————————————————–

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:415588次
    • 积分:8339
    • 等级:
    • 排名:第2466名
    • 原创:467篇
    • 转载:24篇
    • 译文:0篇
    • 评论:67条
    最新评论