NFC读写标签数据

应一些同学的需要,在此专门对NFC读写Tag标签进行适配,如遇到相关什么问题在此贴进行讨论学习,代码如下,

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title></title>

<script>

var NfcAdapter;

var NdefRecord;

var NdefMessage;

function listenNFCStatus() {

try{

var main = plus.android.runtimeMainActivity();

var Intent = plus.android.importClass('android.content.Intent');

var Activity = plus.android.importClass('android.app.Activity');

var PendingIntent = plus.android.importClass('android.app.PendingIntent');

var IntentFilter = plus.android.importClass('android.content.IntentFilter');

NfcAdapter = plus.android.importClass('android.nfc.NfcAdapter');

var nfcAdapter = NfcAdapter.getDefaultAdapter(main);

var intent = new Intent(main, main.getClass());

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

var pendingIntent = PendingIntent.getActivity(main, 0, intent, 0);

var ndef = new IntentFilter("android.nfc.action.TECH_DISCOVERED");

ndef.addDataType("*/*");

var intentFiltersArray = [ndef];

var techListsArray = [

["android.nfc.tech.IsoDep"],

["android.nfc.tech.NfcA"],

["android.nfc.tech.NfcB"],

["android.nfc.tech.NfcF"],

["android.nfc.tech.Nfcf"],

["android.nfc.tech.NfcV"],

["android.nfc.tech.NdefFormatable"],

["android.nfc.tech.MifareClassi"],

["android.nfc.tech.MifareUltralight"]

];

document.addEventListener("newintent",

function() {

console.error('newintent');

setTimeout(handle_nfc_data1, 1000);

}, false);

document.addEventListener("pause", function(e) {

if (nfcAdapter) {

nfcAdapter.disableForegroundDispatch(main);

console.log('pause');

}

}, false);

document.addEventListener("resume", function(e) {

if (nfcAdapter) {

console.log('resume');

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

}

}, false);

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

}catch(e){

console.error(e);

}

}



function handle_nfc_data1()

{

NdefRecord = plus.android.importClass("android.nfc.NdefRecord");

NdefMessage = plus.android.importClass("android.nfc.NdefMessage");

var main = plus.android.runtimeMainActivity();

var intent = main.getIntent();

console.log("action type:" + intent.getAction());

if("android.nfc.action.TECH_DISCOVERED" == intent.getAction()){

if(readyWriteData){

__write(intent);

readyWriteData = false;

}else if(readyRead){

__read(intent);

readyRead = false;

}

}

}

function showToast(msg){

plus.nativeUI.toast(msg);

}



function __write(intent){

try{

waiting.setTitle('请勿移开标签\n正在写入...');

var text = document.getElementById('text').value;

console.log("text=" + text);

var textBytes = plus.android.invoke(text,"getBytes");

// image/jpeg text/plain

var textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,

plus.android.invoke("text/plain","getBytes"), plus.android.invoke("","getBytes"), textBytes);

var message = new NdefMessage([textRecord]);

var Ndef = plus.android.importClass('android.nfc.tech.Ndef');

var NdefFormatable = plus.android.importClass('android.nfc.tech.NdefFormatable');

var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

var ndef = Ndef.get(tag);

if (ndef != null) {

var size = message.toByteArray().length;

console.log("size=" + size);

ndef.connect();

if (!ndef.isWritable()) {

showToast("tag不允许写入");

waiting.close();

return ;

}

if (ndef.getMaxSize() < size) {

showToast("文件大小超出容量");

waiting.close();

return ;

}



ndef.writeNdefMessage(message);

waiting.close();

showToast("写入数据成功.");

return ;

} else {

var format = NdefFormatable.get(tag);

if (format != null) {

try {

format.connect();

format.format(message);

showToast("格式化tag并且写入message");

waiting.close();

return ;

} catch (e) {

showToast("格式化tag失败.");

waiting.close();

return ;

}

} else {

showToast("Tag不支持NDEF");

waiting.close();

return ;

}

}

}catch(e){

console.log("error=" + e);

waiting.close();

alert('写入失败');

}



}



function __read(intent){

waiting.setTitle('请勿移开标签\n正在读取数据...');

var Parcelable = plus.android.importClass("android.os.Parcelable");

var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES");

records = rawmsgs[0].getRecords();

var result = records[0].getPayload();

var s = plus.android.newObject("java.lang.String",result);

document.getElementById('content').textContent = s;

waiting.close();

}

document.addEventListener('plusready',listenNFCStatus,false);



var waiting ;

var readyWriteData = false;

var readyRead = false;

function writeData(){

var textEle = document.getElementById('text');

if(!textEle.value){

alert('请输入要写入的内容');

return;

}

readyWriteData = true;

waiting = plus.nativeUI.showWaiting("请将NFC标签靠近!");

}

function readData(){

readyRead = true;

waiting = plus.nativeUI.showWaiting("请将NFC标签靠近!");

}

</script>



<style>

button{

width: 50%;

height: 50px;

}

</style>

</head>

<body>

输入要写入的内容:<br/><textarea id="text">姓名:张二蛋年龄:29地址:北京海淀区</textarea><br/>

<button onclick="writeData()">写入</button>

<button onclick="readData()">读取</button><br/>

读取的内容:

<div id="content"/>

</body>

</html>

\n

2015-11-27 17:23 1 条评论 分享
已邀请:
1

大山

赞同来自: 爱h5

经过一天的测试,发现楼主提供的代码不怎么严谨,而且也没有再启动时增加是否支持nfc的判断定:
1。增加判断的代码:
var nfcAdapter = NfcAdapter.getDefaultAdapter(main);

if(nfcAdapter == null){
alert("设备不支持NFC!");
return;
}
if (!nfcAdapter.isEnabled()) {

alert("请在系统设置中先启用NFC功能!");

return;

}

2、对于数据处理时用的一些id其实可以用android原生的变量:
intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES");中"android.nfc.extra.NDEF_MESSAGES" == NfcAdapter.EXTRA_NDEF_MESSAGES
这样就和android原生代码一致了,比较好理解。NfcAdapter是啥看看代码头部的调用赋值就应该能明白吧。


1

records = rawmsgs[0].getRecords(); 读IC卡这句时报错,过不去,加try catch提示TypeError: Cannot read property '0' of null’


1

无法读取加密的扇区内容。。。


1

如何把url写入nfc标签


0

驾驭小超人

赞同来自:

请问一下,把你这份代码复制过来就可以进行测试吗?


0

lostyouth

赞同来自:

我试了下,官方给的例子确实很好用,正好解决了我好长时间都在头疼的nfc读写问题


0

启动错误

赞同来自:

enableForegroundDispatch;
java.lang.SecurityException: NFC permission required: Neither user 10214 nor current process has android.permission.NFC. at index.html:59

------刷不出来,怎么会报这个错呢?


0

笑果科技

赞同来自:

function __read(intent) {
try {
waiting.setTitle('请勿移开标签\n正在读取数据...');
var Parcelable = plus.android.importClass("android.os.Parcelable");
console.log(Parcelable);
var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES")
console.log(rawmsgs);
records = rawmsgs[0].getRecords();
用来读取银行卡和公交卡的时候,运行到上面这一句话直接报错:‘
TypeError: Cannot read property '0' of null’

                var result = records[0].getPayload();
var s = plus.android.newObject(&quot;java.lang.String&quot;, result);
document.getElementById('content').textContent = s;
waiting.close();
} catch (e) {
console.log(e);
waiting.close();
}
}
\n
0

大菜鸟

赞同来自:

我也这个问题,你读IC卡正常吗?


0

samon

赞同来自:

启动时,提示“enableForegroundDispatch;java.lang.reflect.InvocationTargetException”什么原因呢,把这段代码注释掉,没有反应


0

samon

赞同来自:

enableForegroundDispatch;java.lang.reflect.InvocationTargetException 的报错是什么问题呢


0

785189333@qq.com

赞同来自:

请问我创建一个java web 项目,新建一个html网页,在手机端使用浏览器访问这个页面,不能达到效果。请问是不是还需要一些配置?


0

uniip@163.com

赞同来自:

求助一下,我把这段代码打了个包测试NFC读取,但是我一读取成功后就跳转到手机主页了,另外一个问题,我手机上有多个NFC读取APP的话,如何设置读取这个NFC读取的时候回自动调用我指定的app或者app内的指定页面? 希望大家能帮助一下


0

爱h5

赞同来自:

在webview方式集成中,"android.nfc.action.TECH_DISCOVERED" == intent.getAction()
该条件不成立,intent.getAction() 获取到的一直是 android.intent.action.MAIN
,求帮助


0

2313452533@qq.com

赞同来自:

原生的Tag类有getId();这个方法可以得到NFC芯片的id,用这个怎么得到NFC的id,在线等,急。。。。。。。。


0

无言的飞雪

赞同来自:

@DCloud_Android_磊子:

techListsArray有错误,应该为:
var techListsArray = [
["android.nfc.tech.IsoDep"],
["android.nfc.tech.NfcA"],
["android.nfc.tech.NfcB"],
["android.nfc.tech.NfcF"],
["android.nfc.tech.Ndef"],
["android.nfc.tech.NfcV"],
["android.nfc.tech.NdefFormatable"],
["android.nfc.tech.MifareClassic"],
["android.nfc.tech.MifareUltralight"]
];

还有,我扫描北京公交卡没有成功,在__read(intent)方法中
var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES");
rawmsgs为null,怎么解决?


0

无言的飞雪

赞同来自:

@DCloud_Android_磊子:
@DCloud_SDK_骁骑:

解决了一部分,但是又有个地方卡住了。

为什么plus.android.importClass("android.nfc.tech.MifareClassic");不成功呢?
执行上面一句后,再调用MifareClassic报错。。

看源码知道是有构造方法的:


0

36707644@qq.com

赞同来自:

我复制改代码,打包app,运行没有任何反应。就是没有读取的动作。设备有声音,就是没有读取的信息


0

闪电抽击

赞同来自:

是不是一般的nfc白卡都可以用你们写的实例,需要买什么样的nfc卡


0

小包子和蜗牛

赞同来自:

直接复制楼主的代码运行,当把卡贴近手机时会闪退,... 安卓7.0@DCloud_Android_磊子


0

煮酒吃豆豆

赞同来自:

试了北京公交卡和提供的标签卡都是运行到这行出问题
var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES");
rawmsgs是个null,这个如何处理 @DCloud_Android_磊子


0

星海

赞同来自:

感谢楼主的分享,可以正常读取标签数据。在真机运行中也可以读写数据。现在想利用手机读NFC标签ID验证身份。
现在无法解析id:
var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

var Ndef = plus.android.importClass('android.nfc.tech.Ndef');
console.log(tag.getId());
错误信息:
Uncaught TypeError: tag.getId is not a function at index.html:162

如果直接读取id:
var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_ID);

console.log(tag);
信息如下:
null at index.html:162

无法读出id,


0

14166803@qq.com

赞同来自:

楼主您好,非常感谢你的NFC代码分享,现在遇到这种情况,在真机调度下运行时,读NFC内容正常,但生成发布包后去正式安装读NFC时就出现闪退,请求楼主帮助。


0

qsh.cui@tasily.com

赞同来自:

不支持iOS版本的nfc吗? @DCloud_Android_磊子


0

大仓

赞同来自:

java.io.IOException;at android.nfc.tech.Ndef.connect
写入NFC标签的时候报这个错,有没有遇到过的同学


0

916767363@qq.com

赞同来自:

请问ios的NFC有吗


0

123321150@qq.com

赞同来自:

获取NFC的ID
bytesId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
console.log(ByteArrayToHexString(bytesId));
下面是字节流转16进制的函数,将网上JAVA的代码改成JS,谢谢原作者(我也不知道作者是谁)

function ByteArrayToHexString(inarray) { // converts byte arrays to string
var i, j, inn;
hex = [&quot;0&quot;, &quot;1&quot;, &quot;2&quot;, &quot;3&quot;, &quot;4&quot;, &quot;5&quot;, &quot;6&quot;, &quot;7&quot;, &quot;8&quot;, &quot;9&quot;, &quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;, &quot;F&quot;];
out = &quot;&quot;;

for(j = 0; j &lt; inarray.length; ++j) {
inn = inarray[j] &amp; 0xff;
i = (inn &gt;&gt;&gt; 4) &amp; 0x0f;
out += hex[i];
i = inn &amp; 0x0f;
out += hex[i];
}
return out;
}
\n

亲自测试成功的!


0

276099181@qq.com

赞同来自:

var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES");
读完 rawmsgs 是 null
有人能解决吗


0

小小小鸟

赞同来自:

怎么限制一下仅在本应用中响应NFC 不跳转到系统自带的NFC应用呢,谢谢


0

1821275424@qq.com

赞同来自:

@Android_磊子 这个H5的实现方式,是否可以直接读,不需要先写入;如果是直接读的话能成功吗?我这边报错跟他们一样,在var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES"); 这个地方报空指针异常,有什么解决方案吗


0

1821275424@qq.com

赞同来自:

想问一下,我用var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);这行代码想要获取我要读的卡的标签类型,但是我打印了一下是{"UUID":"Invocation405839258","TYPE":"JSBObject","className":"android.net.wifi.ScanResult"}这种信息,这样的话,type这一列是JSBObeject,NFC标签应该没有这种类型吧,这样我是该读哪个类型标签的数据呢?


0

请问一下,这个程序,我返回桌面之后,再刷卡,怎么让他进入系统的那个候选列表呢,求解答,不胜感激!!!!


要回复问题请先登录注册