Android_磊子
Android_磊子
  • 发布:2015-11-27 17:23
  • 更新:2019-12-25 19:23
  • 阅读:45507

NFC读写标签数据

分类:Native.js

应一些同学的需要,在此专门对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>
2015-11-27 17:23 1 条评论 负责人:无 分享
已邀请:
大山

大山

经过一天的测试,发现楼主提供的代码不怎么严谨,而且也没有再启动时增加是否支持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是啥看看代码头部的调用赋值就应该能明白吧。

  • 爱h5

    在webview方式集成中,"android.nfc.action.TECH_DISCOVERED" == intent.getAction()

    该条件不成立,intent.getAction() 获取到的一直是 android.intent.action.MAIN

    ,求帮助

    2016-10-18 13:53

大菜鸟

大菜鸟

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

  • Android_磊子 (作者)

    那应该是var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES"); 这里没有得到数据,还请查一下资料ic卡的数据如何保存,保存在什么字段中。

    2016-03-29 10:54

  • k***@163.com

    评论1楼 ,这个无法获取到,你说的查一下资料ic卡数据,在哪里查?现在解决问题没有?官方提供的这个方法 intent.getParcelableArrayExtra()根本没用;而且看大部分的资料过这个字段是没有问题的"android.nfc.extra.NDEF_MESSAGES"。如果解决了请回复我一下,

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

    2017-05-01 19:27

  • 小宇DeDe

    回复 Android_磊子:var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSA这个方法获得的是null,无法继续往下读取怎么办?

    2017-05-06 16:17

  • 水域心诚

    @862805551@qq.com:问题解决了么

    2017-11-21 16:41

  • s***@163.com

    是啊,没有东西,显示是NULL

    2017-12-12 21:48

  • 7R4ATMqQPOPKjR

    回复 k***@163.com:请问这个问题解决了吗?我遇到同样问题,过不去了。

    2018-06-26 17:38

  • g***@163.com

    回复 7R4ATMqQPOPKjR: 哥们nfc读卡问题实现了吗?有偿求助实现同样的功能。

    2019-06-03 21:07

  • 1***@163.com

    回复 g***@163.com: 兄弟 这个问题解决了么?

    2019-06-06 13:56

  • 1***@qq.com

    回复 Android_磊子: 如果不写入,直接读,为什么只显示请勿移开标签正在读取数据

    2019-06-12 11:11

  • 1***@qq.com

    回复 1***@163.com: 回复 1***@163.com: 同问

    2019-06-12 11:29

  • 1***@qq.com

    回复 g***@163.com: 可以读卡片ID了

    2019-06-13 10:09

  • 2hai

    回复 1***@qq.com: 我的var rawmsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);

    这句也是null,请问你解决了么

    2019-06-13 17:11

  • 1***@qq.com

    回复 2hai: http://ask.dcloud.net.cn/article/35046 推荐给你亲测可行

    2019-06-17 11:15

  • s***@163.com

    回复 1***@qq.com: http://ask.dcloud.net.cn/article/35046 ,这个demo是不是无法读取加密的扇区内容呀

    2019-09-17 16:23

2***@qq.com

2***@qq.com - amao

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

  • Android_磊子 (作者)

    加密扇区内容是怎么个意思,是读出来的二进制内容还需要解密?

    2016-06-27 18:25

  • m***@163.com

    大哥,请问下你的加密扇区的内容能读出来了吗,交流一下

    2019-08-13 15:27

舌尖跳舞

舌尖跳舞 - 现在不减肥,以后徒伤悲。

如何把url写入nfc标签

1***@163.com

1***@163.com - 90后前端菜鸟

多次读取nfc信息时,监听事件newintent触发的次数为啥会逐次增加呢?有人遇到这个问题吗

  • 1***@163.com

    这个问题是我把监听事件写在了onShow里,写onLoad里就好了

    2019-06-06 09:53

驾驭小超人

驾驭小超人

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

  • Android_磊子 (作者)

    是的,有什么问题可以提问。

    2015-12-09 14:12

lostyouth

lostyouth

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

启动错误

启动错误

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

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

  • Android_磊子 (作者)

    没有加入权限。

    1,云打包时,在mainifest.json试图|模块权限配置,勾选权限,重新云打包

    2,离线打包,自行在AndroidManifest.json中配置好。

    2016-01-11 17:04

  • 启动错误

    权限是否只有android.premission.NFC这个勾选上,还是除了这个还有其他需要勾选的呢?

    2016-01-11 17:20

  • 启动错误

    为什么勾选了这个权限,真机联调的时候应用启动的时候还是会报这个错误呢?手机是三星s5移动定制版

    2016-01-11 17:53

  • Android_磊子 (作者)

    回复 启动错误:重新打包了吗

    2016-01-12 13:47

  • 启动错误

    回复 Android_磊子:真机联调在读取NFC标签的时候应用会闪退,重新打包后还是会提示这个错误,似乎是抛出的异常项。。。

    2016-01-12 15:26

  • Android_磊子 (作者)

    回复 启动错误:确认勾选此权限并云打包了的话吧,把你的apk发给我看看 QQ609029981

    2016-01-12 16:11

笑果科技

笑果科技

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("java.lang.String", result);  
                document.getElementById('content').textContent = s;  
                waiting.close();  
            } catch (e) {  
                console.log(e);  
                waiting.close();  
            }  
        }
大菜鸟

大菜鸟

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

samon

samon

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

samon

samon

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

  • m***@163.com

    这是手机不支持nfc功能

    2019-08-13 15:28

7***@qq.com

7***@qq.com

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

u***@163.com

u***@163.com

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

爱h5

爱h5

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

2***@qq.com

2***@qq.com

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

  • LINEQ

    怎么读取到tag的id ?求助

    2017-08-17 15:45

无言的飞雪

无言的飞雪

@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,怎么解决?

无言的飞雪

无言的飞雪

@DCloud_Android_磊子:
@DCloud_SDK_骁骑:

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

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

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

  • 无言的飞雪

    原因找到了:是由于代码中添加了/* @hide /,Google官方给出的结果是,允许内部调用,不允许外部调用。这个问题怎么解决?

    2016-11-04 20:10

  • 1***@qq.com

    楼主解决问题没有

    2019-01-11 14:26

3***@qq.com

3***@qq.com

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

闪电抽击

闪电抽击

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

  • 星海

    我之前也是这样,打包是没有加上NFC 权限。manifest.json 文件,在“代码视图”中权限行手工加入"permissions": ["<uses-permission android:name=\"android.permission.NFC\" />",

    2017-12-15 23:18

小包子和蜗牛

小包子和蜗牛

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

煮酒吃豆豆

煮酒吃豆豆

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

星海

星海

感谢楼主的分享,可以正常读取标签数据。在真机运行中也可以读写数据。现在想利用手机读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,

  • 星海

    <!DOCTYPE html>

    <html>

    <head>

    <meta charset="utf-8">

    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

    <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);

    handle_nfc_data1();

    }, 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()){
    __read(intent);

    // 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 ByteArrayToHexString(inarray) {
    var i, j, tmp;
    var hex = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A","B", "C", "D", "E", "F" ];
    var out = "";
    console.log("here");

    for (j = 0; j < inarray.length; ++j) {
    tmp = inarray[j] & 0xff;
    i = (tmp >> 4) & 0x0f;
    out += hex[i];
    i = tmp & 0x0f;
    out += hex[i];
    }
    return out;
    }

    function __read(intent){

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

    //showToast("111");

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

    //showToast("222");

    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 = document.getElementById('content').textContent+'|'+s;

    //手机终端编码

    console.log(plus.device.imei);

    // console.info(plus.device.uuid);

    // 读取ID

    var tagid = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);

    console.log(ByteArrayToHexString(tagid));


    // 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>


    **以上代码是在楼主代码基础做的微调


    运行显示数据如下:

    newintent at index.html:39

    resume at index.html:51

    action type:android.nfc.action.TECH_DISCOVERED at index.html:67

    990004774535110,356760060444444 at index.html:171

    here at index.html:148

    04BA59423C4D80 at index.html:179

    pause at index.html:46


    以上可以读取nfc卡号,读取出手机IMEI设备编号,可以将2者加密传输到后台,就可以在绑定手机终端的基础上,实现用户读卡认证(网络传输和加密请自行处理)。

    2017-12-16 00:37

1***@qq.com

1***@qq.com

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

  • 1***@qq.com

    在清单文件上面加上NFC的权限,如果不加权限,直接运行可以,但是打包会报缺少权限

    2018-07-19 17:56

q***@tasily.com

q***@tasily.com

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

9***@qq.com

9***@qq.com

请问ios的NFC有吗

1***@qq.com

1***@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 = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];  
            out = "";  

            for(j = 0; j < inarray.length; ++j) {   
                inn = inarray[j] & 0xff;  
                i = (inn >>> 4) & 0x0f;  
                out += hex[i];  
                i = inn & 0x0f;  
                out += hex[i];  
            }  
            return out;  
        }  

亲自测试成功的!

  • 1***@qq.com

    我的vue框架里面需要调手机的nfc识别卡内的信息, 一直不知道哪里出问题了

    2019-01-08 16:06

2***@qq.com

2***@qq.com

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

  • g***@163.com

    我碰到了同样的问题,哥们nfc读卡问题实现了吗?有偿求助实现同样的功能。

    2019-06-03 21:09

  • s***@163.com

    回复 g***@163.com: 我也遇到了这个问题,你解决了吗

    2019-09-17 16:04

小小小鸟

小小小鸟

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

  • 1***@qq.com

    你系统没有授权才会这样吧

    2018-09-13 11:57

  • 小小小鸟

    恩恩 是的用的安卓离线打的包忘记给授权了,谢谢

    2018-10-03 13:29

1***@qq.com

1***@qq.com

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

  • l***@live.com

    var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES");这句代码是针对NDEF格式的数据有效。你的NFC标签可能不是NDEF(比如是NcfA、IsoDep或其他的)。我也不是百分之百确定,只是估计。

    2018-09-19 16:32

  • 小小段

    回复 l***@live.com: 这个问题我也有 是要先了解nfc是什么格式的数据才能使用对应的方法去处理吗?

    2019-07-25 15:37

1***@qq.com

1***@qq.com

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

  • Jayhoo

    Native.js 获取到的安卓对象都是封装成这个样子的,主要看className,把相应的className用plus.android.importClass引入进来就可以了

    2019-12-11 00:39

吃个魔方压压惊

吃个魔方压压惊

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

吃辣条的大妖怪

吃辣条的大妖怪 - 宝子们,现在公司没在用app开发了,纯H5开发,之后的后期有空在补笔记

解决rawmsgs为null的问题:

var rawmsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);

  • 1***@163.com

    改成NfcAdapter.EXTRA_NDEF_MESSAGES 依然还是null是因为啥呢

    2019-06-06 15:42

  • 小小段

    回复 1***@163.com: 请问 你这个问题解决了吗? 我也遇到了

    2019-07-25 15:43

  • s***@163.com

    回复 小小段:我也遇到了,你们解决了吗

    2019-09-17 14:55

2***@qq.com

2***@qq.com

无法触发newintent事件,只接同时触发pause和resume 事件是怎么回事,应该如何修改?????
报错信息及输出信息如下:
pause at plus/zhh_nfc.html:44
18:02:58.584 resume at plus/zhh_nfc.html:49
18:04:00.871 Uncaught java.lang.IllegalStateException: You must disable foreground dispatching while your activity is still resumed;at android.nfc.NfcAdapter.disableForegroundDispatch at plus/zhh_nfc.html:1

  • 2***@qq.com

    你解决了吗?我读取成功。 问个小问题。加下我QQ512951614

    2019-03-27 14:06

  • s***@163.com

    回复 2***@qq.com: NFC读写标签数据,在var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES"); 这个地方报空指针异常,你是怎么解决的呀

    2019-09-17 16:18

lyle

lyle - 归来仍是少年

[ERROR] java.lang.SecurityException: NFC permission required: Neither user 10235 nor current process has android.permission.NFC.;at android.nfc.NfcAdapter.enableForegroundDispatch at pages/nfc/nfc.vue:64
配置了权限,一直提示没得权限?重新打包自定义基座测试,一直提示这个。删除本地基座,后面重新打包又可以了。

但随后,uniapp下,又出现[ERROR] TypeError: Cannot read property 'addEventListener' of undefined at pages/nfc/nfc.vue:84
uniapp下怎么使用监听呢?

  • 吃辣条的大妖怪

    uniapp 用onShow和onHide

    2019-04-11 11:29

  • lyle

    回复 吃辣条的大妖怪: 感谢提醒,总算在uniapp下把老子的公交卡,门禁卡读出数据了。 卡片ID等数据给其他设备读出数据一致。

    2019-05-09 17:15

  • s***@163.com

    回复 lyle: uniapp中怎么实现读取nfc卡信息呢,可以提供一下代码吗?不胜感激

    2019-09-16 17:33

4***@qq.com

4***@qq.com

我在读取身份证时,怎么读出来的不是身份信息,而是一串字节数组ID呢

xzsxzs

xzsxzs - 90后大四学生

看起来很厉害,可以给讲解一下吗

coderYang

coderYang

@Android_磊子 你好,请问下MifareClassic格式标签和 NDEF格式标签加密的怎么处理啊?就是读写加密的NFC标签,用现在的程序,总是提示“格式化tag失败”,帮忙看下呢,不胜感激

  • m***@163.com

    查看下安卓sdk

    https://www.androiddoc.com/reference/android/nfc/tech/MifareClassic.html#authenticateSectorWithKeyB(int,%20byte[])

    需要用到 揭秘函数

    authenticateSectorWithKeyA (int sectorIndex, byte[] key)

    authenticateSectorWithKeyB (int sectorIndex, byte[] key)

    2019-08-22 12:29

  • coderYang

    回复 m***@163.com: 嗯 谢谢啦,已经解决了

    2019-08-26 23:48

  • 乘风hexiii

    你好,请问加密是怎么实现的?

    2019-10-29 15:05

吃个魔方压压惊

吃个魔方压压惊

uniapp可以使用

**plus.globalEvent.addEventListener('newintent', ()=>{

});
监听newintent事件了**
https://uniapp.dcloud.io/use-html5plus

三岁四颗小虎牙

三岁四颗小虎牙

Uncaught Attempt to invoke virtual method 'java.lang.Class java.lang.reflect.Method.getReturnType()' on a null object reference;at android.nfc.tech.MifareClassic.authenticateSectorWithKeyA
请问一下这个是什么问题?如何解决!

  • 一只小菜鸡

    我遇到了同样的问题。请问解决了吗??

    2019-07-27 17:33

  • m***@163.com

    我也遇到同样类似的问题

    Uncaught Attempt to invoke virtual method 'java.lang.Class java.lang.reflect.Method.getReturnType()' on a null object reference;at android.nfc.tech.MifareClassic.writeBlock at wrnfc.html:1

    2019-08-22 12:30

菜鸟66

菜鸟66

var NfcAdapter;
var NdefRecord;
var NdefMessage;
var waiting;
var readyRead = false;
var nfcAdapter, main, pendingIntent, intentFiltersArray, techListsArray, IntentFilter;
export default {
data() {
return {
currentNFCInfo: [], //NFC 读取消息;
bannerShow: false,
remark: '',
message: '',
count: 0,
timestampHide: '',
timestampShow: ''
};
},
onLoad() {
this.listenNFCStatus();
},
methods: {
listenNFCStatus() {
try {
console.log('Init NFC...');
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');
IntentFilter = plus.android.importClass('android.content.IntentFilter');
NfcAdapter = plus.android.importClass('android.nfc.NfcAdapter');
nfcAdapter = NfcAdapter.getDefaultAdapter(main);
var intent = new Intent(main, main.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
pendingIntent = PendingIntent.getActivity(main, 0, intent, 0);
var ndef = new IntentFilter('android.nfc.action.TECH_DISCOVERED');
ndef.addDataType('/');
intentFiltersArray = [ndef];
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']
];
} catch (e) {
console.error(e);
}
},
handle_nfc_data() {
NdefRecord = plus.android.importClass('android.nfc.NdefRecord');
NdefMessage = plus.android.importClass('android.nfc.NdefMessage');
main = plus.android.runtimeMainActivity();
var intent = main.getIntent();
console.log('action type:' + intent.getAction());
if ('android.nfc.action.TECH_DISCOVERED' == intent.getAction()) {
if (readyRead) {
this.read(intent);
readyRead = false;
}
} else {
console.log('nfc读取失败');
}
},
read(intent) {
try {
var content = '';
waiting = plus.nativeUI.showWaiting('请将NFC标签靠近!');
waiting.setTitle('请勿移开标签\n正在读取数据...');
var tag = plus.android.importClass('android.nfc.Tag');
waiting.close();
var Parcelable = plus.android.importClass('android.os.Parcelable');
var rawmsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);

            if (rawmsgs != null && rawmsgs.length > 0) {  
                waiting.close();  
                var records = rawmsgs[0].getRecords();  
                var result = records[0].getPayload();  
                if (result != null) {  
                    var s = plus.android.newObject('java.lang.String', result);  
                    console.log(s);  
                    this.currentNFCInfo = s;  
                } else {  
                    this.currentNFCInfo = '';  
                }  
            } else {  
                console.log('NFC获取失败');  
                uni.showToast({  
                    title: 'NFC获取失败.',  
                    icon: 'none'  
                });  
            }  
        } catch (e) {  
    handle_nfc_data.log(e);  
            console.log('NFC获取失败,丢出异常');  
            waiting.close();  
            uni.showToast({  
                title: 'NFC获取失败,丢出异常.',  
                icon: 'none'  
            })  
        }  
    }  
}  

};

大神们,这是我的原码,我直接调用handle_nfc_data之后,程序跑到var intent = main.getIntent();这句代码的时候,打印出来intent为null,大神们,该怎么解决,求打救,谢谢!

菜鸟66

菜鸟66

      var intent = main.getIntent();    
      console.log("action type:" + intent.getAction());    

intent 对象为空,怎么解决,有没有人遇到过?

小小段

小小段

  var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES");   返回null 有经历过的大佬指导一下 
1***@qq.com

1***@qq.com

请问大神我直接用你这个个demo测试,是不是必须先写入再读取;还有就是写入的时候提示格式tag错误要怎么解决啊

zj369

zj369

你好,你写的这个怎么让app进入系统候选列表

月遇丛云

月遇丛云

请问,能读取身份证吗?

大海的凡夫俗子

大海的凡夫俗子

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

  • 1***@qq.com

    大佬解决了吗 我也遇到了

    2019-12-09 11:09

该问题目前已经被锁定, 无法添加新回复