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 ...
随机推荐
- mysql配置优化测试
http://bjlfp.blog.163.com/blog/static/77368461201211695924524/ 感觉真不错啊.观察几天看看
- 利用Linux下的pthread_mutex_t类型来实现哲学家进餐问题
首先说一下什么是哲学家进餐问题,这是操作系统课程中一个经典的同步问题, 问题如下:如上图,有6个哲学家和6根筷子(那个蓝色部分表示哲学家,那个紫色长条部分表示筷子),他们分别被编了0~5的号!如果某个 ...
- Mac OS X安装OpenCV 3.1.0
在我的上一篇文章“”中已经介绍了Linux下OpenCV的安装配置方法,在这里仅仅记录Mac上相对于Linux的一点点差异. 1. 安装依赖包 Mac上安装软件包使用的工具是brew,用此来替代Ubu ...
- C插入排序
#include "stdio.h" int main() { ,,,,,}; int i,j; ;j<]);j++) { int key = a[j]; ;i>=&a ...
- 正则应用—queryURLParameter()
在项目中,我们做详情页的时候,需要获取到用户从哪里来点击进来,获取到用户的点击地址,根据不同的地址传进的参数向服务器获取不同的数据,然后加载不同的详情页面. 大部分企业都采用字符串截取的方式,quer ...
- Apache+PHP+MySql 的安装及配置
每一项技术用的人多了,就会有人将其进行优化,做成一个简单.实用.大众化的工具,这对于初识者来说是非常方便的,但是对于长久学习或工作这方面的人技术人员来说是不可取的,所以还是要学习基础的实用方法.因此, ...
- 大型网站用什么技术比较好,JSP,PHP,ASP.NET
大型网站,我建议要考虑的问题: 首先讨论一下大型网站需要注意和考虑的问题. 数据库海量数据处理:负载量不大的情况下select.delete和update是响应很迅速的,最多加几个索引就可以搞定,但千 ...
- Oracle监听器—动态注册
注册就是将数据库作为一个服务注册到监听程序.客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到数据库.这个服务名可能与实例名一样,也有可能不一样. 注册分: 1. 静 ...
- Oracle修改表空间大小
在向orale数据库导入数据的时候报 ORA-01658: 无法为表空间 XXX中的段创建 INITIAL 区错误. Oracle我在创建表空间的时候初始化大小为200M,当数据库中数据量达到这个值, ...
- iOS 进阶 第一天(0323)
0323 Storyboard连线错误 如下图: 不允许直接修改对象的结构体属性成员,但允许直接整体修改对象的结构体属性 如下图: 打印一个控件对象的frame 如下图: 如果一个控件无论怎么改变它的 ...