只有遵守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. Spring多数据源的动态切换

    Spring多数据源的动态切换 目前很多项目中只能配置单个数据源,那么如果有多个数据源肿么办?Spring提供了一个抽象类AbstractRoutingDataSource,为我们很方便的解决了这个问 ...

  2. SQL Server中批量替换数据

    SQL Server数据库中批量替换数据的方法 SQL Server数据库操作中,我们可能会根据某写需要去批量替换数据,那么如何批量修改替换数据呢?本文我们就介绍这一部分内容,接下来就让我们一起来了解 ...

  3. NodeJS + Socket.io聊天服务器连接数达到1024后就连不上了

    如果是亚马逊的Engine Yard服务器,解决办法为: 1.查看端口占用情况,找到nodejs进程号,例如我这里是8000端口 lsof -i:8000  找到pid 例如为 8213 2.设置no ...

  4. php curl基本操作

    如何使用cURL的基本方法?首先,修改php.ini文件的设置,找到php_curl.dll,取消下在的注释extension=php_curl.dll,因为php默认是不开启cURL的. cURL是 ...

  5. 关于B/S系统在移动端应用的一些注意的地方(不断更新)

    1.不要直接把PC端的页面直接搬到移动端来用.这里举个例子:有个活动页面,在PC端和手机端的Safari里展现都好,但是当用手机APP(如手机淘宝)扫码打开后,却没法顺畅的异步获取到jsonp的信息. ...

  6. 十二、mysql sql_mode 简学

    .一般默认情况下sql_mode默认为空,也就是不严格的sql检查 .如果sql_mode为空的情况下,测试: )); //定义一个name字段长度为定长2的tt3表 insert into tt3 ...

  7. php源代码安装常见错误与解决办法分享

    错误:configure: error: libevent >= 1.4.11 could not be found 解决:yum -y install libevent libevent-de ...

  8. Android中Google地图路径导航,使用mapfragment地图上画出线路(google map api v2)详解

    在这篇里我们只聊怎么在android中google map api v2地图上画出路径导航,用mapfragment而不是mapview,至于怎么去申请key,manifest.xml中加入的权限,系 ...

  9. maven3.1安装及配置

    1.首先下载maven3,并安装 2.环境变量配置与JAVA_HOME的配置一样 3.打开MyEclipse preferences>>Maven4MyEclipse>>Mav ...

  10. hdu 4707 Pet(DFS水过)

    http://acm.hdu.edu.cn/showproblem.php?pid=4707 [题目大意]: Lin Ji 的宠物鼠丢了,在校园里寻找,已知Lin Ji 在0的位置,输入N D,N表示 ...