只有遵守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)的更多相关文章

  1. NFC(9)NDEF文本格式规范及读写示例(解析与封装ndef 文本)

    只有遵守NDEF文本格式规范的数据才能写到nfc标签上. NDEF文本格式规范 不管什么格式的数据本质上都是由一些字节组成的.对于NDEF文本格式来说. 1,这些数据的第1个字节描述了数据的状态, 2 ...

  2. NFC(11)MifareUltralight格式规范及读写示例

    注意 MifareUltralight 不支三种过滤方式之一,只支持第四种(用代码,activity singleTop ) 见  NFC(4)响应NFC设备时启动activity的四重过滤机制 Mi ...

  3. 11、NFC技术:NDEF Uri格式解析

    NDEF Uri格式规范 与NDEF文本格式一样,存储在NFC标签中的Uri也有一定的格式 http://www.nfc-forum.org/specs/spec_dashboard 编写可以解析Ur ...

  4. 9、NFC技术:NDEF文本格式解析

    NDEF文本格式规范     不管什么格式的数据本质上都是由一些字节组成的.对于NDEF文本格式来说.这些数据的第1个字节描述了数据的状态,然后若干个字节描述文本的语言编码,最后剩余字节表示文本数据. ...

  5. GeoJSON格式规范说明

    GeoJSON格式规范说明 1.简介 GeoJSON是一种对各种地理数据结构进行编码的格式.GeoJSON对象可以表示几何.特征或者特征集合.GeoJSON支持下面几何类型:点.线.面.多点.多线.多 ...

  6. OverWatch团队文档格式规范

    V1.0 最终修改于2016/10/19 概述 软件工程中,一份优雅的文档不仅能降低团队成员之间的沟通难度,而且能给之后的开发者提供一个非常有效的引导.本团队为了规范整个项目中文档的格式,便于统一管理 ...

  7. C语言ini格式配置文件的读写

    依赖的类 /*1 utils.h *# A variety of utility functions. *# *# Some of the functions are duplicates of we ...

  8. 理解CSV格式规范(解析CSV必备)

    什么是CSV逗号分隔值(Comma-Separated Values,CSV),其文件以纯文本形式存储表格数据(数字和文本),文件的每一行都是一个数据记录.每个记录由一个或多个字段组成,用逗号分隔.使 ...

  9. IOS格式规范

    IOS格式规范 目录 概述 日期格式 NSDateFormatter格式说明 概述 日期格式 声明时间格式:NSDateFormatter *date_formatter = [[NSDateForm ...

随机推荐

  1. 【转】分享10VPN

    以下介绍的vpn,都是有免费流量赠送的免费vpn,完全不免费的不在之列. 免费vpn因为用的人比较多,所以高峰时段可能会有点慢,但是人少时,还是比较顺畅的.对于偶尔浏览外网,看看新闻的同学来说,免费v ...

  2. VB.Net 文件处理类

    1.编写日志 2.本地文件的读取和写入 3.Base64与图片的互相转换 Imports System.IO Imports System.Text Public Class Cls_File #Re ...

  3. C++ 编写 CorelDRAW CPG 插件例子(1)—WelcomeScreen

    据我所知,这是国外论坛最早的一个例子,原贴在此:http://forum.oberonplace.com/showthread.php?t=1880&highlight=Plugins 贴上主 ...

  4. 帝国cms中 内容分页的SEO优化

    关于内容页如果存在分页的话,我们想区分第一页和后面数页,当前的通用做法是在标题上加入分页码,帝国cms中如何做到呢.我们可以修改在e/class/functions.php中的源码.找到找到GetHt ...

  5. java指令集

    0x00 nop      什么都不做 0x01 aconst_null 将null推送至栈顶 0x02 iconst_m1   将int型-1推送至栈顶 0x03 iconst_0   将int型0 ...

  6. (转载)猫都能学会的Unity3D Shader入门指南(一)

    原文地址 http://onevcat.com/2013/07/shader-tutorial-1/ 动机 自己使用Unity3D也有一段时间了,但是很多时候是流于表面,更多地是把这个引擎简单地用作脚 ...

  7. DB天气app冲刺第十二天

    今天其实不算冲刺了 ,因为今天没怎么花时间在软件上,而是花时间在老师留的作业上了.所以也算作是软件工程这门课的冲刺吧. DB天气这款app上今天的api接口还是木有弄好.明天会继续弄.但是全国城市的数 ...

  8. git/ TortoiseGit 在bitbucket.org 使用证书登陆

    背景:使用https协议在bitbucket中进行pull,push 时每次都要输入密码,比较麻烦还耽误时间,在网上找了下保存密码的方式 使用在用户环境变量中配置_netrc 文件的方式(http:/ ...

  9. OGRE1.8.1源码编译(VS2008)

    最近在学习图形学,想看看OGRE源码,于是就去OGRE官网下载源码,配置环境,这里记录一下.鉴于电脑太破,VS2010比较慢,所以使用VS2008. 准备工作: CMake2.8       下载地址 ...

  10. 过长文字自动换行的技巧 Word-Break Word-Wrap

    在很多时候,为了防止内容过长把表格或容器撑破, 我们都需要为容器加上自动换行的功能. 实现自动换行,用CSS来实现,通常有两种方式: word-break: 取值为 normal, break-all ...