NFC(10)NDEF uri格式规范及读写示例(解析与封装ndef uri)
只有遵守NDEF uri 格式规范的数据才能写到nfc标签上.
NDEF uri 格式规范
uri 只有两部分:
第1个字节是uri协议映射值,如:0x01 表示uri以 http://www.开头.
然后是uri的内容 ,如 www.g.cn

uri协议映射值表

示例
ReadWriteUriActivity.java
import android.app.Activity;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast; /*
* 本apk主activity,拦截nfc标签事件
* 把读到的内容传给ShowNFCTagContentActivity
* 把封装好的uri写到临近的nfc标签.
*/
public class ReadWriteUriMainActivity extends Activity {
private TextView mSelectUri;
private String mUri; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_read_write_uri_main);
mSelectUri = (TextView) findViewById(R.id.textview_uri); } public void onClick_SelectUri(View view) {
Intent intent = new Intent(this, UriListActivity.class);
startActivityForResult(intent, ); } @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == && resultCode == ) {
mUri = data.getStringExtra("uri");
mSelectUri.setText(mUri);
}
} /*
* 如果本aty中的mUri空,就读nfc标签内容存到mUri中,
* 不空就封装uri并把它写到nfc标签中
*/
@Override
public void onNewIntent(Intent intent) {
if (mUri == null) {//读nfc标签内容存到mUri中,并显示
//把读到的内容传给ShowNFCTagContentActivity
Intent myIntent = new Intent(this, ShowNFCTagContentActivity.class);
myIntent.putExtras(intent);
myIntent.setAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
startActivity(myIntent);
} else {// 封装uri并把它写到nfc标签中 //封装uri并把它写到nfc标签 第1步,取nfc标签
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); //封装uri并把它写到nfc标签 第2步,构造NdefMessage,其中有NdefRecord,NdefRecord中有封装的uri
NdefMessage ndefMessage = new NdefMessage(
new NdefRecord[] { createUriRecord(mUri) }); //封装uri并把它写到nfc标签 第3步,封装uri并写入
if (writeTag(ndefMessage, tag)) {
mUri = null;
mSelectUri.setText("");
}
}
} /*
* 封装uri格式数据
* 现部分组成: 第一个字节是uri协议映射值
* uri协议映射值,如:0x01 表示uri以 http://www.开头.
* uri的内容 如:www.g.cn
*/
public NdefRecord createUriRecord(String uriStr) {
/*
* 封装uri格式数据 第1步, 根据uriStr中的值找到构造第一个字节的内容:uri协议映射值
*/
byte prefix = ;
for (Byte b : UriRecord.URI_PREFIX_MAP.keySet()) {
String prefixStr = UriRecord.URI_PREFIX_MAP.get(b).toLowerCase();
if ("".equals(prefixStr))
continue;
if (uriStr.toLowerCase().startsWith(prefixStr)) {
prefix = b;
uriStr = uriStr.substring(prefixStr.length());
break;
} }
/*
* 封装uri格式数据 第2步, uri的内容就是本函数的参数 uriStr
*/
/*
* 封装uri格式数据 第3步, 申请分配空间
*/
byte[] data = new byte[ + uriStr.length()]; /*
* 封装uri格式数据 第4步, 把uri头的映射值和uri内容写到刚申请的空间中
*/
data[] = prefix;
System.arraycopy(uriStr.getBytes(), , data, , uriStr.length()); /*
* 封装uri格式数据 第5步, 根据uri构造一个NdefRecord
*/
NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
NdefRecord.RTD_URI, new byte[], data);
return record;
} /*
* 将封装好uri格式的NdefMessage写入到nfc标签中.
*/
boolean writeTag(NdefMessage message, Tag tag) {
int size = message.toByteArray().length;
try {
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect();
if (!ndef.isWritable()) {
return false;
}
if (ndef.getMaxSize() < size) {
return false;
}
ndef.writeNdefMessage(message);
Toast.makeText(this, "ok", Toast.LENGTH_LONG).show();
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
UriRecord.java
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import android.net.Uri;
import android.nfc.NdefRecord; public class UriRecord { private final Uri mUri;// 存uri /*
* uri 格式数据中 第一个字节 存uri的头值映射表
* 如 0x01 表示uri以 http://www.开头,
* 存uri的头值是为了省空间.
*/
public static final Map<Byte, String> URI_PREFIX_MAP = new HashMap<Byte, String>(); static {
URI_PREFIX_MAP.put((byte) 0x00, "");
URI_PREFIX_MAP.put((byte) 0x01, "http://www.");
URI_PREFIX_MAP.put((byte) 0x02, "https://www.");
URI_PREFIX_MAP.put((byte) 0x03, "http://");
URI_PREFIX_MAP.put((byte) 0x04, "https://");
URI_PREFIX_MAP.put((byte) 0x05, "tel:");
URI_PREFIX_MAP.put((byte) 0x06, "mailto:");
URI_PREFIX_MAP.put((byte) 0x07, "ftp://anonymous:anonymous@");
URI_PREFIX_MAP.put((byte) 0x08, "ftp://ftp.");
URI_PREFIX_MAP.put((byte) 0x09, "ftps://");
URI_PREFIX_MAP.put((byte) 0x0A, "sftp://");
URI_PREFIX_MAP.put((byte) 0x0B, "smb://");
URI_PREFIX_MAP.put((byte) 0x0C, "nfs://");
URI_PREFIX_MAP.put((byte) 0x0D, "ftp://");
URI_PREFIX_MAP.put((byte) 0x0E, "dav://");
URI_PREFIX_MAP.put((byte) 0x0F, "news:");
URI_PREFIX_MAP.put((byte) 0x10, "telnet://");
URI_PREFIX_MAP.put((byte) 0x11, "imap:");
URI_PREFIX_MAP.put((byte) 0x12, "rtsp://");
URI_PREFIX_MAP.put((byte) 0x13, "urn:");
URI_PREFIX_MAP.put((byte) 0x14, "pop:");
URI_PREFIX_MAP.put((byte) 0x15, "sip:");
URI_PREFIX_MAP.put((byte) 0x16, "sips:");
URI_PREFIX_MAP.put((byte) 0x17, "tftp:");
URI_PREFIX_MAP.put((byte) 0x18, "btspp://");
URI_PREFIX_MAP.put((byte) 0x19, "btl2cap://");
URI_PREFIX_MAP.put((byte) 0x1A, "btgoep://");
URI_PREFIX_MAP.put((byte) 0x1B, "tcpobex://");
URI_PREFIX_MAP.put((byte) 0x1C, "irdaobex://");
URI_PREFIX_MAP.put((byte) 0x1D, "file://");
URI_PREFIX_MAP.put((byte) 0x1E, "urn:epc:id:");
URI_PREFIX_MAP.put((byte) 0x1F, "urn:epc:tag:");
URI_PREFIX_MAP.put((byte) 0x20, "urn:epc:pat:");
URI_PREFIX_MAP.put((byte) 0x21, "urn:epc:raw:");
URI_PREFIX_MAP.put((byte) 0x22, "urn:epc:");
URI_PREFIX_MAP.put((byte) 0x23, "urn:nfc:");
} private UriRecord(Uri uri) {
this.mUri = uri;
} public Uri getUri() {
return mUri;
} /*
* 这时,uri数据里没有uri头值,整个uri数据就是一个uri
*/
private static UriRecord parseAbsolute(NdefRecord ndefRecord) {
//1,取得数据流
byte[] payload = ndefRecord.getPayload();
//2,解析出一个uri
String uriStr = new String(payload, Charset.forName("UTF-8"));
Uri uri = Uri.parse(uriStr);
return new UriRecord(uri); }
/*
* 解析nfc uri格式的数据
*
*/
private static UriRecord parseWellKnown(NdefRecord ndefRecord) {
//解析uri第1步,判断record中是否是 uri
if (!Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_URI))
return null;
//解析uri第2步,获取字节数据.
byte[] payload = ndefRecord.getPayload(); //解析uri第3步,解析出uri头,如https://等
String prefix = URI_PREFIX_MAP.get(payload[]);
//解析uri第4步,解析出uri的内容,如:www.g.cn
byte[] prefixBytes = prefix.getBytes(Charset.forName("UTF-8")); //解析uri第5步,合并uri头各内容.
byte[] fullUri = new byte[prefixBytes.length + payload.length - ];
System.arraycopy(prefixBytes, , fullUri, , prefixBytes.length);
System.arraycopy(payload, , fullUri, prefixBytes.length,payload.length - );
//解析uri第6步,构造Uri
String fullUriStr = new String(fullUri, Charset.forName("UTF-8"));
Uri uri = Uri.parse(fullUriStr);
//解析uri第7步,
return new UriRecord(uri); }
/*
* 解析uri格式数据.
*/
public static UriRecord parse(NdefRecord record) {
short tnf = record.getTnf();
if (tnf == NdefRecord.TNF_WELL_KNOWN) {
return parseWellKnown(record);
} else if (tnf == NdefRecord.TNF_ABSOLUTE_URI) {
return parseAbsolute(record);
}
throw new IllegalArgumentException("Unknown TNF " + tnf);
}
}
NFC(10)NDEF uri格式规范及读写示例(解析与封装ndef uri)的更多相关文章
- NFC(9)NDEF文本格式规范及读写示例(解析与封装ndef 文本)
只有遵守NDEF文本格式规范的数据才能写到nfc标签上. NDEF文本格式规范 不管什么格式的数据本质上都是由一些字节组成的.对于NDEF文本格式来说. 1,这些数据的第1个字节描述了数据的状态, 2 ...
- NFC(11)MifareUltralight格式规范及读写示例
注意 MifareUltralight 不支三种过滤方式之一,只支持第四种(用代码,activity singleTop ) 见 NFC(4)响应NFC设备时启动activity的四重过滤机制 Mi ...
- 11、NFC技术:NDEF Uri格式解析
NDEF Uri格式规范 与NDEF文本格式一样,存储在NFC标签中的Uri也有一定的格式 http://www.nfc-forum.org/specs/spec_dashboard 编写可以解析Ur ...
- 9、NFC技术:NDEF文本格式解析
NDEF文本格式规范 不管什么格式的数据本质上都是由一些字节组成的.对于NDEF文本格式来说.这些数据的第1个字节描述了数据的状态,然后若干个字节描述文本的语言编码,最后剩余字节表示文本数据. ...
- GeoJSON格式规范说明
GeoJSON格式规范说明 1.简介 GeoJSON是一种对各种地理数据结构进行编码的格式.GeoJSON对象可以表示几何.特征或者特征集合.GeoJSON支持下面几何类型:点.线.面.多点.多线.多 ...
- OverWatch团队文档格式规范
V1.0 最终修改于2016/10/19 概述 软件工程中,一份优雅的文档不仅能降低团队成员之间的沟通难度,而且能给之后的开发者提供一个非常有效的引导.本团队为了规范整个项目中文档的格式,便于统一管理 ...
- C语言ini格式配置文件的读写
依赖的类 /*1 utils.h *# A variety of utility functions. *# *# Some of the functions are duplicates of we ...
- 理解CSV格式规范(解析CSV必备)
什么是CSV逗号分隔值(Comma-Separated Values,CSV),其文件以纯文本形式存储表格数据(数字和文本),文件的每一行都是一个数据记录.每个记录由一个或多个字段组成,用逗号分隔.使 ...
- IOS格式规范
IOS格式规范 目录 概述 日期格式 NSDateFormatter格式说明 概述 日期格式 声明时间格式:NSDateFormatter *date_formatter = [[NSDateForm ...
随机推荐
- KnockoutJS(2)-监控属性
本节主要涉及到3个内容: 1. 监控属性 Observables (这个用的比较多,但是其本身使用比较简单,唯一需要注意就是,它监控的对象是一个方法,所以取值和设置值的时候容易混淆) 2. 计算属性 ...
- [Linux]学习笔记(2)
本节主要学习: whoami who am i who w users tty 6个命令的用法. (1)whoami whoami用于查询当前是以哪个用户登录Linux系统: [root@linuxf ...
- centos 安装ecshop出现date错误
centos 安装ecshop 错误提示 Warning: date(): It is not safe to rely on the system's timezone settings. You ...
- dapper 自定义数据库字段和代码中Model字段不一致时候的mapping方法
namespace YourNamespace { /// <summary> /// Uses the Name value of the ColumnAttribute specifi ...
- wpf 绑定失效的原因及解决方案
有时候,您会发现在程序开始时还能正常运行的绑定失效了.就个人经验而言,绑定的失效主要分为两种情况:对于One-way绑定而言,如果软件开发人员绕过绑定直接更改了目标属性,那么绑定将会失效.而对于Two ...
- 浅谈string
#include <string>// 注意是<string>,不是<string.h>,带.h的是C语言中的头文件 using std::string;using ...
- Mysql数据库备份和还原常用的命令
Mysql数据库备份和还原常用的命令是进行Mysql数据库备份和还原的关键,没有命令,什么都无从做起,更谈不上什么备份还原,只有给系统这个命令,让它去执行,才能完成Mysql数据库备份和还原的操作,下 ...
- Java中的异常处理(三) - 自定义异常处理
1.异常处理类 package second; public class MyException extends Exception { MyException (){ } MyException ( ...
- mysql慢查询优化之explain的各列含义
mysql> explain select customer_id,first_name,last_name from customer; +----+-------------+------- ...
- centos修改ssh端口
1.编辑防火墙配置:vi /etc/sysconfig/iptables防火墙增加新端口2222-A INPUT -m state --state NEW -m tcp -p tcp --dport ...