标签分发协议php,NFC标签前台分发及数据读写

文件配置

要实现前台分发功能,首先需要配置Manifest文件,其中LanchActivity只是一个简单的启动页面,跳转到MainActivity(这才是要处理NFC标签的页面)。按官方的文档,处理标签扫描结果的Activity就是程序的启动页面,但是我们一般不会在启动页面处理数据。

android:name="android.hardware.nfc"

android:required="true"/>

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:supportsRtl="true"

android:theme="@style/AppTheme">

android:resource="@xml/nfc_tech_filter"/>

@xml/nfc_tech_filter文件,该文件中是应用程序支持的NFC技术列表

android.nfc.tech.MifareClassic

官网文档支持的所有技术列表如下(我们只需要是其子集即可):

android.nfc.tech.IsoDep

android.nfc.tech.NfcA

android.nfc.tech.NfcB

android.nfc.tech.NfcF

android.nfc.tech.NfcV

android.nfc.tech.Ndef

android.nfc.tech.NdefFormatable

android.nfc.tech.MifareClassic

android.nfc.tech.MifareUltralight

根据官网说明,标签分发拦截有以下步骤:

1、在onCreate方法中创建全局的PendingIntent对象,以便扫描到NFC标签时系统可以用扫描到的tag信息填充该pendingIntent对象。代码如下:

pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

2、定义你要拦截的intent过滤器。当设备扫描到一个标签时,系统前台分发系统根据收到的intent来校验是否符合我们指定的intentFilter。如果匹配,应用程序将会处理该intent,否则,调用系统intent分发系统。如果指定intent过滤器和技术过滤数组为空,你将会接收到TAG_DISCOVERED上的所有标记。(即,如果要拦截系统标签分发系统到我们前台Activity,需要定义拦截的intent过滤器、我们要处理的技术过滤数组)

系统示例代码如下:

IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);

try {

ndef.addDataType("*/*"); /* Handles all MIME based dispatches.

You should specify only the ones that you need. */

}

catch (MalformedMimeTypeException e) {

throw new RuntimeException("fail", e);

}

intentFiltersArray = new IntentFilter[] {ndef, };

在我测试的过程中,没有用到mime类型:

techListsArray = new String[][]{new String[]{MifareClassic.class.getName()}};//支持的技术类别

IntentFilter ndef = new IntentFilter();

ndef.addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);//要过滤的标签级别

intentFiltersArray = new IntentFilter[]{ndef};

3、覆写系统方法

@Override

protected void onNewIntent(Intent intent) {

processIntent(intent);//处理返回数据的方法,扫描到的标签数据都在intent中

}

@Override

protected void onPause() {

super.onPause();

nfcAdapter.disableForegroundDispatch(this);

}

@Override

protected void onResume() {

super.onResume();

nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);

if (getIntent().getAction() != null) {

if (NfcAdapter.ACTION_TECH_DISCOVERED.endsWith(getIntent().getAction())) {

processIntent(getIntent());

}

}

}

其中,onResume方法中的if判断是为了当程序未运行时扫描到NFC标签也可以接收到数据。

然后重要的是数据读写,这里只是简单的操作,具体还是要参考官方文档:

//读取所有block中的数据

private void readData(final MifareClassic mfc) {

if (mfc != null) {

if (mfc.isConnected()) {

try {

String result = "";

tvStatus.setText("正在读取数据");

for (int i = 0; i < mfc.getSectorCount(); i++) {//循环读取所有的扇区

int bindex;

int bCount;

if (mfc.authenticateSectorWithKeyA(i, MifareClassic.KEY_DEFAULT)) {//读取的时候要校验key,否则无法读取

bindex = mfc.sectorToBlock(i);

bCount = mfc.getBlockCountInSector(i);

result += "Sector " + i + "验证成功\n";

for (int j = 0; j < bCount; j++) {//循环读取指定扇区所有的块,每个扇区最后一个块是该块的key,除非要加密,否则不要轻易改变

byte[] data = mfc.readBlock(bindex);

result += "Block " + bindex + " : " + new String(data, Charset.forName("UTF-8")) + "\n";

bindex++;

}

}

}

tvStatus.setText("数据读取完成");

tvReadData.setText(result);

} catch (Exception ex) {

tvStatus.setText("读取失败:" + ex.getMessage());

}

}

} else {

Toast.makeText(this, "未扫描到NFC", Toast.LENGTH_SHORT).show();

}

}

//向标签指定block写入数据

private void writeData(final MifareClassic mfc, final int blockIndex, String msg) {

if (mfc != null) {

try {

Log.e(TAG, "writeData: isConnected:" + mfc.isConnected());

if (mfc.isConnected()) {

byte[] temp = msg.getBytes(Charset.forName("UTF-8"));

final byte[] write = new byte[MifareClassic.BLOCK_SIZE];//每一块最大存储字节数

for (int i = 0; i < MifareClassic.BLOCK_SIZE; i++) {

if (i < temp.length)

write[i] = temp[i];

else

write[i] = 0;

}

tvStatus.setText("正在写入");

new Thread(new Runnable() {

@Override

public void run() {

try {

Log.e(TAG, "run: 写入内容:" + new String(write));

mfc.writeBlock(blockIndex, write);//写入方法是一个阻塞函数,不能在UI线程调用

runOnUiThread(new Runnable() {

@Override

public void run() {

tvStatus.setText("写入完成");

}

});

} catch (final Exception ex) {

Log.e(TAG, "writeData_Ex: " + ex.getMessage());

runOnUiThread(new Runnable() {

@Override

public void run() {

tvStatus.setText("写入失败:" + ex.getMessage());

}

});

}

}

}).start();

} else {

Toast.makeText(this, "NFC连接断开", Toast.LENGTH_SHORT).show();

}

} catch (Exception ex) {

Log.e(TAG, "writeData: " + ex.getMessage());

}

} else {

Toast.makeText(this, "未扫描到NFC卡片", Toast.LENGTH_SHORT).show();

}

}

NFCWRDemo

PS:写的不好,仅为记录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值