HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

uniapp app 安卓端 百度语音识别 "code": 4004,App name unknown

百度语音识别
plus.speech.startRecognize(  
                    options,  
                    function(s) {  
                        console.log("pass----",s);  
                        _this.sayData = s;  
                        plus.speech.stopRecognize();  
                        uni.redirectTo({  
                            url: '/pages/recentsearch/recentsearch?sayData='   _this.sayData  
                        })  

                    },   
                    function(e) {//失败  
                        console.log("fail----",e);  
                        uni.showToast({  
                            title: '语音识别失败',  
                            icon: 'none'  
                        });  
                    }  
                );

错误提示信息


{  
    "code": 4004,  
    "message": "App name unknown[(-3004)asr authentication failed[info:-3004]]"  
}

解决方法:
1、我们用的是个人的百度语音免费权限,权限过期了,重新换账号申请了一个并申请了免费的额度
2、在manifest配置最新的账号
3、真机调试时,把原来手机上的删除,重新制作自定义基座,基座完成后,重新运行到基座,即可实现语音功能!!!!!

继续阅读 »
plus.speech.startRecognize(  
                    options,  
                    function(s) {  
                        console.log("pass----",s);  
                        _this.sayData = s;  
                        plus.speech.stopRecognize();  
                        uni.redirectTo({  
                            url: '/pages/recentsearch/recentsearch?sayData='   _this.sayData  
                        })  

                    },   
                    function(e) {//失败  
                        console.log("fail----",e);  
                        uni.showToast({  
                            title: '语音识别失败',  
                            icon: 'none'  
                        });  
                    }  
                );

错误提示信息


{  
    "code": 4004,  
    "message": "App name unknown[(-3004)asr authentication failed[info:-3004]]"  
}

解决方法:
1、我们用的是个人的百度语音免费权限,权限过期了,重新换账号申请了一个并申请了免费的额度
2、在manifest配置最新的账号
3、真机调试时,把原来手机上的删除,重新制作自定义基座,基座完成后,重新运行到基座,即可实现语音功能!!!!!

收起阅读 »

普通vue项目打包为app

App离线打包
  1. vue路由设置为hash模式
  2. 打包
  3. 通过hbuilder创建5+APP项目
  4. 将打包问题覆盖到根目录
  5. 云打包

其实最重要就是hash模式 不然就是白屏。

  1. vue路由设置为hash模式
  2. 打包
  3. 通过hbuilder创建5+APP项目
  4. 将打包问题覆盖到根目录
  5. 云打包

其实最重要就是hash模式 不然就是白屏。

npm install报错

执行npm install报错

npm ERR! code CERT_HAS_EXPIRED  
npm ERR! errno CERT_HAS_EXPIRED  
npm ERR! request to https://registry.npm.taobao.org/@dcloudio/uni-helper-json failed, reason: certificate has expired

我并不知道这个应该怎么去解决当删除package.json中的"@dcloudio/uni-helper-json": "^1.0.13",npm就能完成下载并且用HbuilderX也能正常运行到开发者工具,请问应该怎么解决这个报错呢

继续阅读 »

执行npm install报错

npm ERR! code CERT_HAS_EXPIRED  
npm ERR! errno CERT_HAS_EXPIRED  
npm ERR! request to https://registry.npm.taobao.org/@dcloudio/uni-helper-json failed, reason: certificate has expired

我并不知道这个应该怎么去解决当删除package.json中的"@dcloudio/uni-helper-json": "^1.0.13",npm就能完成下载并且用HbuilderX也能正常运行到开发者工具,请问应该怎么解决这个报错呢

收起阅读 »

技术合伙人

1能力和待遇(饼向)
要求:主要是前端和后端精通就行,安卓原生要有个1年的经验起,因为很多uniapp搞不定的,需要自行写,有些买不起,太贵!年龄没有限制,学历也没有限制,我个人的技术全是学来的,初中毕业。

1能力和待遇(饼向)
要求:主要是前端和后端精通就行,安卓原生要有个1年的经验起,因为很多uniapp搞不定的,需要自行写,有些买不起,太贵!年龄没有限制,学历也没有限制,我个人的技术全是学来的,初中毕业。

UniPush-谷歌推送FCM新版V1配置指南

unipush fcm

FCM旧版HTTP 将在2024年6月20日后废弃,建议在此时间前迁移到最新的HTTP V1。

一、下载 V1 版本密钥文件

1,登录Firebase官网,进入项目设置

2,选择配置语言,点击生成新的私钥

3,生成密钥

4,生成密钥后,会下载到本地一个json文件

二、保存配置

登录Dcloud官网,上传并保存密钥文件。
⚠️注意:若google-services.json文件有变更,保存后需要重新云打包。若无变更,则仅需在后台保存配置。

继续阅读 »

FCM旧版HTTP 将在2024年6月20日后废弃,建议在此时间前迁移到最新的HTTP V1。

一、下载 V1 版本密钥文件

1,登录Firebase官网,进入项目设置

2,选择配置语言,点击生成新的私钥

3,生成密钥

4,生成密钥后,会下载到本地一个json文件

二、保存配置

登录Dcloud官网,上传并保存密钥文件。
⚠️注意:若google-services.json文件有变更,保存后需要重新云打包。若无变更,则仅需在后台保存配置。

收起阅读 »

前端网页托管,H5使用history路由模式,除了首页刷新白屏,文件不存在解决办法

找到前端网页托管=>参数配置=>配置404页面就可以解决

找到前端网页托管=>参数配置=>配置404页面就可以解决

***



邮箱验证的时候收不到邮件

邮箱验证的时候,可以收到验证码,但是收不到验证邮箱的消息
下面以网易邮箱为例:

  1. 用网易邮箱登录Hbuilder时会提示“当前账号尚未验证邮箱,请登录开发者中心 https://dev.dcloud.net.cn 完成邮箱验证后再登录”
  2. 去该网址验证时,登录的邮箱可以收到验证码,但是到验证的步骤,点击‘验证’按钮时会出现附件中的提示,然后邮箱中也收不到验证的消息
    重点来了!!!!!
    解决办法(以网易邮箱为例):
    网易邮箱-设置-反垃圾/黑白名单-白名单 里面添加 dev.dcloud.net.cn

我已经验证成功了!!!给小伙伴们避雷!!!

继续阅读 »

邮箱验证的时候,可以收到验证码,但是收不到验证邮箱的消息
下面以网易邮箱为例:

  1. 用网易邮箱登录Hbuilder时会提示“当前账号尚未验证邮箱,请登录开发者中心 https://dev.dcloud.net.cn 完成邮箱验证后再登录”
  2. 去该网址验证时,登录的邮箱可以收到验证码,但是到验证的步骤,点击‘验证’按钮时会出现附件中的提示,然后邮箱中也收不到验证的消息
    重点来了!!!!!
    解决办法(以网易邮箱为例):
    网易邮箱-设置-反垃圾/黑白名单-白名单 里面添加 dev.dcloud.net.cn

我已经验证成功了!!!给小伙伴们避雷!!!

收起阅读 »

在App中使用editor,遇到的editorContext无效问题

App环境下,
问题产生原因:
二级页面使用editor, id唯一情况下

//只有首次进入时, context 能追踪到元素本身  
  uni.createSelectorQuery().select(`#${this.dynamicID}`).context((res) => {  
        this.editorCtx = res.context  
}).exec()

再次或多次进入二级页面,context存在,但使用其内部方法无法追踪到当前元素本身;
(执行clear 方法 回调success,但是无效化,没有对当前元素进行操作)
(执行insertText 方法 无回调,内部程序 报错)
示例 1

//执行插入文字  
this.editorCtx.insertText({  
       text: 'test demo',  
       success: (res) => {  
            // 无响应反馈  
            console.log('success', res);  
        },  
       fail: (err) => {  
            // 无响应反馈  
            console.log('fail', err);  
      }  
});  
// 内部程序 报错 - 显示  
15:15:18.072 [WARNING] :addRange(): The given range isn't in document. at __uniappquill.js:7  
15:15:18.072 Uncaught TypeError: Cannot read properties of null (reading 'index') at uni-app-view.umd.js:1  

// 内部程序 报错 代码片段  
 case 'insertText':  
      {  
              range = quill.getSelection(true)  
              const { text = '' } = options  
              quill.insertText(range.index, text, Quill.sources.USER)  
              quill.setSelection(range.index + text.length, 0, Quill.sources.SILENT)  
      }  
break

我的解决办法:使用动态生成ID
使用动态生成ID后,上述问题便没有复现;

继续阅读 »

App环境下,
问题产生原因:
二级页面使用editor, id唯一情况下

//只有首次进入时, context 能追踪到元素本身  
  uni.createSelectorQuery().select(`#${this.dynamicID}`).context((res) => {  
        this.editorCtx = res.context  
}).exec()

再次或多次进入二级页面,context存在,但使用其内部方法无法追踪到当前元素本身;
(执行clear 方法 回调success,但是无效化,没有对当前元素进行操作)
(执行insertText 方法 无回调,内部程序 报错)
示例 1

//执行插入文字  
this.editorCtx.insertText({  
       text: 'test demo',  
       success: (res) => {  
            // 无响应反馈  
            console.log('success', res);  
        },  
       fail: (err) => {  
            // 无响应反馈  
            console.log('fail', err);  
      }  
});  
// 内部程序 报错 - 显示  
15:15:18.072 [WARNING] :addRange(): The given range isn't in document. at __uniappquill.js:7  
15:15:18.072 Uncaught TypeError: Cannot read properties of null (reading 'index') at uni-app-view.umd.js:1  

// 内部程序 报错 代码片段  
 case 'insertText':  
      {  
              range = quill.getSelection(true)  
              const { text = '' } = options  
              quill.insertText(range.index, text, Quill.sources.USER)  
              quill.setSelection(range.index + text.length, 0, Quill.sources.SILENT)  
      }  
break

我的解决办法:使用动态生成ID
使用动态生成ID后,上述问题便没有复现;

收起阅读 »

软键盘挤压页面导致露出上一页的内容

在input输入的时候点击点击拍照导致页面露出上一页,可以在input添加离开事件直接调用uni.hideKeyboard();恢复页面

在input输入的时候点击点击拍照导致页面露出上一页,可以在input添加离开事件直接调用uni.hideKeyboard();恢复页面

uni-app,NFC标签读取和写入网址,手机识别在浏览器中跳转

Android uniapp NFC

参考文章链接:
uniapp 实现 NFC标签读取 和 写入

背景:
最近遇到一个需求,app需要对NFC标签写入网址(比如是商品链接),然后把NFC标签贴到商品上面,用户使用手机NFC感应可以直接跳转网页(商品详情)。
过程:
首先就是想到了在Dcloud社区查找文档,阅读量最高的就是吃辣条的大妖怪写的[uniapp 实现 NFC标签读取 和 写入]这篇文章。然后直接粘贴文章的代码去运行。发现确实能写入内容了,但是手机识别NFC只能显示新标签已收集。点击显示的是text/plain,没有显示具体内容,也跳转不了网站。一开始以为是TNF类型有问题,然后就把NdefRecord.TNF_MIME_MEDIA类型改成NdefRecord. TNF_ABSOLUTE_URI,结果还是不行。反正就是对new NdefRecord里面的几个参数各种修改,最后还是不行。后面想到能不能去通过原生Android的NFC写入代码来给自己一点灵感,下面找到的是一段Android原生代码。
文档链接:Android实现NFC读写

    /**   
     * 往nfc写入数据   
     */    
    public static void writeNFCToTag(String data, Intent intent) throws IOException, FormatException {    
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);    
        Ndef ndef = Ndef.get(tag);    
        ndef.connect();    
        NdefRecord ndefRecord = NdefRecord.createTextRecord(null, data);    
        NdefRecord[] records = {ndefRecord};    
        NdefMessage ndefMessage = new NdefMessage(records);    
        ndef.writeNdefMessage(ndefMessage);    
    } 

通过这段代码,我发现NdefRecord.createTextRecord就可以实现NDEF创建,不需要通过new NdefRecord。然后在uniapp中直接把new NdefRecord方法改成了NdefRecord.createTextRecord。

// 创建包含 文本 的新 NDEF 记录  
var ndefRecord = NdefRecord.createTextRecord(str);

写入成功!很激动的用手机去读取,发现现在是打开备忘录了。哎,有戏!但是和我想的还是不一样啊!NdefRecord类是不是还有别的方法呢?然后就去查阅Android文档,找到了CreateUri方法,它可以创建包含 URI 的新 NDEF 记录。文档链接:NdefRecord.CreateUri 方法
然后又把代码换成

// 创建包含 URI 的新 NDEF 记录  
var ndefRecord = NdefRecord.createUri(str);

写入成功!用手机去读取,成功识别到写入的是一个网址,点击可以直接跳转浏览器打开!大功告成!目前试了小米、华为、1加、iPhone 11和13 等机型,除了小米都是可以成功识别并跳转浏览器的。

注:通过NdefRecord.createUri写入网址一定要加https://开头。

好了,下面贴上我所有的代码,希望可以帮助到大家,也希望大家可以多多交流。(我的代码是放在pages/main/index.vue页面下的。)

<template>  
    <view class="content">  
        <view class="uni-common-mt">  
            <view class="uni-form-item uni-column">  
                <input class="uni-input" v-model="inputValue" focus placeholder="请输入NFC要写入的内容" />  
                <button type="default" @click="writeData()">写入NFC</button>  
                <button type="default" @click="readData()">读取NFC</button>  
            </view>  
        </view>  
    </view>  
</template>  

<script>  
    var NfcAdapter;  
    var NdefRecord;  
    var NdefMessage;  
    var waiting  
    var readyRead = false;  
    var readyWriteData = false;  
    var nfcAdapter, main, pendingIntent, intentFiltersArray, techListsArray, IntentFilter  

    export default {  
        data() {  
            return {  
                inputValue: '',  
                currentNFCInfo: [], //NFC 读取消息;    
                bannerShow: false,  
                remark: "",  
                message: "",  
                count: 0,  
                timestampHide: "",  
                timestampShow: ""  
            };  
        },  
        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;  
                    }  
                    if (readyWriteData) {  
                        this.__write(intent);  
                        readyWriteData = false;  
                    }  
                } else {  
                    // waiting.close();    
                    console.log("nfc读取失败")  
                    uni.showToast({  
                        title: "NFC获取失败.",  
                        icon: "none"  
                    });  
                }  
            },  
            __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("android.nfc.extra.NDEF_MESSAGES");    
                    var rawmsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);  

                    if (rawmsgs != null && rawmsgs.length > 0) {  
                        waiting.close();  
                        console.log(JSON.stringify(rawmsgs[0]));  
                        var records = rawmsgs[0].getRecords();  
                        var result = records[0].getPayload();  
                        console.log(JSON.stringify(result))  
                        if (result != null) {  
                            var s = plus.android.newObject("java.lang.String", result);  
                            console.log(s);  
                            this.currentNFCInfo = s;  
                            uni.showModal({  
                                title: 'NFC信息',  
                                showCancel: false,  
                                content: JSON.stringify(s),  
                            });  
                        } else {  
                            this.currentNFCInfo = "";  
                        }  
                    } else {  
                        console.log("NFC获取失败");  
                        uni.showToast({  
                            title: "NFC获取失败.",  
                            icon: "none"  
                        });  
                    }  

                } catch (e) {  
                    console.log(e);  
                    console.log("NFC获取失败,丢出异常");  
                    waiting.close();  
                    uni.showToast({  
                        title: "NFC获取失败,丢出异常.",  
                        icon: "none"  
                    });  
                    //TODO handle the exception    
                }  
            },  
            readData() {  
                readyRead = true;  
                //  waiting = plus.nativeUI.showWaiting("请将NFC标签靠近!");    
                setTimeout(this.handle_nfc_data, 1000);  
            },  
            __write(intent) {  
                try {  
                    waiting = plus.nativeUI.showWaiting("请将NFC标签靠近!");  
                    waiting.setTitle('请勿移开标签\n正在写入...');  
                    // var textBytes = plus.android.invoke(this.inputValue, "getBytes");  
                    // var typeBytes = plus.android.invoke('text/plain', 'getBytes')  
                    // 创建 NDEF 记录    
                    // var textRecord = new NdefRecord(  
                    //  NdefRecord.TNF_MIME_MEDIA, // TNF 类型    
                    //  typeBytes, // 类型(MIME 类型)    
                    //  null, // ID(留空以自动生成)    
                    //  textBytes, // 有效负载(文本的字节表示)    
                    // );  

                    // 创建包含 URI 的新 NDEF 记录  
                    var ndefRecord = NdefRecord.createUri(this.inputValue);  

                    var message = new NdefMessage([ndefRecord]);  
                    console.log('messgae=' + message)  
                    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()) {  
                            console.log("tag不允许写入");  
                            waiting.close();  
                            uni.showToast({  
                                title: "tag不允许写入.",  
                                icon: "none"  
                            });  
                            return;  
                        }  
                        if (ndef.getMaxSize() < size) {  
                            console.log("文件大小超出容量");  
                            waiting.close();  
                            uni.showToast({  
                                title: "文件大小超出容量.",  
                                icon: "none"  
                            });  
                            return;  
                        }  
                        // console.log('写入数据:' + JSON.stringify(message) + ' __TYPE__: ' + JSON.stringify(message.__TYPE__));    
                        console.log("message:" + message)  
                        ndef.writeNdefMessage(message);  

                        waiting.close();  
                        console.log("写入数据成功.");  
                        uni.showToast({  
                            title: "写入数据成功.",  
                            icon: "none"  
                        });  
                        return;  
                    } else {  
                        var format = NdefFormatable.get(tag);  
                        if (format != null) {  
                            try {  
                                format.connect();  
                                format.format(message);  
                                console.log("格式化tag并且写入message")  
                                waiting.close();  
                                return;  
                            } catch (e) {  
                                console.log("格式化tag失败.");  
                                waiting.close();  
                                uni.showToast({  
                                    title: "格式化tag失败.",  
                                    icon: "none"  
                                });  
                                return;  
                            }  
                        } else {  
                            console.log("Tag不支持NDEF");  
                            uni.showToast({  
                                title: "Tag不支持NDEF",  
                                icon: "none"  
                            });  
                            waiting.close();  
                            return;  
                        }  
                    }  
                } catch (e) {  
                    console.log("error=" + e);  
                    waiting.close();  
                    console.log('写入失败');  
                }  
            },  
            writeData() {  
                readyWriteData = true;  
                // waiting = plus.nativeUI.showWaiting("请将NFC标签靠近!");    
                setTimeout(this.handle_nfc_data, 1000);  
            },  
        },  
        onLoad: function(option) {  
            console.log('onLoad')  
            this.listenNFCStatus()  
        },  
        onShow: function() {  
            console.log('page Show');  
            this.listenNFCStatus()  
            this.timestampShow = (new Date()).getTime();  
            console.log(this.timestampShow)  
            var TimeScale = this.timestampShow - this.timestampHide;  
            console.log(TimeScale, nfcAdapter, '134 line');  
            if (nfcAdapter == null) {  
                alert("设备不支持NFC!");  
                return;  
            }  
            if (!nfcAdapter.isEnabled()) {  
                alert("请在系统设置中先启用NFC功能!");  
                return;  
            }  
            nfcAdapter && nfcAdapter.enableForegroundDispatch(main, pendingIntent, intentFiltersArray, techListsArray);  
            if (this.count++ == 0) {  
                // this.listenNFCStatus()    
                return false;  
            } else if (TimeScale > 400) {  
                return false;  
            } else {  
                // this.readData();  
                // this.writeData();  
            }  
        },  
        onHide: function() {  
            console.log("onHide");  
            this.timestampHide = (new Date()).getTime();  
            console.log(this.timestampHide);  
        }  
    }  
</script>  

<style>  
    .content {  
        display: flex;  
        flex-direction: column;  
        align-items: center;  
        justify-content: center;  
    }  

    .logo {  
        height: 200rpx;  
        width: 200rpx;  
        margin-top: 200rpx;  
        margin-left: auto;  
        margin-right: auto;  
        margin-bottom: 50rpx;  
    }  

    .text-area {  
        display: flex;  
        justify-content: center;  
    }  

    .title {  
        font-size: 36rpx;  
        color: #8f8f94;  
    }  
</style>
继续阅读 »

参考文章链接:
uniapp 实现 NFC标签读取 和 写入

背景:
最近遇到一个需求,app需要对NFC标签写入网址(比如是商品链接),然后把NFC标签贴到商品上面,用户使用手机NFC感应可以直接跳转网页(商品详情)。
过程:
首先就是想到了在Dcloud社区查找文档,阅读量最高的就是吃辣条的大妖怪写的[uniapp 实现 NFC标签读取 和 写入]这篇文章。然后直接粘贴文章的代码去运行。发现确实能写入内容了,但是手机识别NFC只能显示新标签已收集。点击显示的是text/plain,没有显示具体内容,也跳转不了网站。一开始以为是TNF类型有问题,然后就把NdefRecord.TNF_MIME_MEDIA类型改成NdefRecord. TNF_ABSOLUTE_URI,结果还是不行。反正就是对new NdefRecord里面的几个参数各种修改,最后还是不行。后面想到能不能去通过原生Android的NFC写入代码来给自己一点灵感,下面找到的是一段Android原生代码。
文档链接:Android实现NFC读写

    /**   
     * 往nfc写入数据   
     */    
    public static void writeNFCToTag(String data, Intent intent) throws IOException, FormatException {    
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);    
        Ndef ndef = Ndef.get(tag);    
        ndef.connect();    
        NdefRecord ndefRecord = NdefRecord.createTextRecord(null, data);    
        NdefRecord[] records = {ndefRecord};    
        NdefMessage ndefMessage = new NdefMessage(records);    
        ndef.writeNdefMessage(ndefMessage);    
    } 

通过这段代码,我发现NdefRecord.createTextRecord就可以实现NDEF创建,不需要通过new NdefRecord。然后在uniapp中直接把new NdefRecord方法改成了NdefRecord.createTextRecord。

// 创建包含 文本 的新 NDEF 记录  
var ndefRecord = NdefRecord.createTextRecord(str);

写入成功!很激动的用手机去读取,发现现在是打开备忘录了。哎,有戏!但是和我想的还是不一样啊!NdefRecord类是不是还有别的方法呢?然后就去查阅Android文档,找到了CreateUri方法,它可以创建包含 URI 的新 NDEF 记录。文档链接:NdefRecord.CreateUri 方法
然后又把代码换成

// 创建包含 URI 的新 NDEF 记录  
var ndefRecord = NdefRecord.createUri(str);

写入成功!用手机去读取,成功识别到写入的是一个网址,点击可以直接跳转浏览器打开!大功告成!目前试了小米、华为、1加、iPhone 11和13 等机型,除了小米都是可以成功识别并跳转浏览器的。

注:通过NdefRecord.createUri写入网址一定要加https://开头。

好了,下面贴上我所有的代码,希望可以帮助到大家,也希望大家可以多多交流。(我的代码是放在pages/main/index.vue页面下的。)

<template>  
    <view class="content">  
        <view class="uni-common-mt">  
            <view class="uni-form-item uni-column">  
                <input class="uni-input" v-model="inputValue" focus placeholder="请输入NFC要写入的内容" />  
                <button type="default" @click="writeData()">写入NFC</button>  
                <button type="default" @click="readData()">读取NFC</button>  
            </view>  
        </view>  
    </view>  
</template>  

<script>  
    var NfcAdapter;  
    var NdefRecord;  
    var NdefMessage;  
    var waiting  
    var readyRead = false;  
    var readyWriteData = false;  
    var nfcAdapter, main, pendingIntent, intentFiltersArray, techListsArray, IntentFilter  

    export default {  
        data() {  
            return {  
                inputValue: '',  
                currentNFCInfo: [], //NFC 读取消息;    
                bannerShow: false,  
                remark: "",  
                message: "",  
                count: 0,  
                timestampHide: "",  
                timestampShow: ""  
            };  
        },  
        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;  
                    }  
                    if (readyWriteData) {  
                        this.__write(intent);  
                        readyWriteData = false;  
                    }  
                } else {  
                    // waiting.close();    
                    console.log("nfc读取失败")  
                    uni.showToast({  
                        title: "NFC获取失败.",  
                        icon: "none"  
                    });  
                }  
            },  
            __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("android.nfc.extra.NDEF_MESSAGES");    
                    var rawmsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);  

                    if (rawmsgs != null && rawmsgs.length > 0) {  
                        waiting.close();  
                        console.log(JSON.stringify(rawmsgs[0]));  
                        var records = rawmsgs[0].getRecords();  
                        var result = records[0].getPayload();  
                        console.log(JSON.stringify(result))  
                        if (result != null) {  
                            var s = plus.android.newObject("java.lang.String", result);  
                            console.log(s);  
                            this.currentNFCInfo = s;  
                            uni.showModal({  
                                title: 'NFC信息',  
                                showCancel: false,  
                                content: JSON.stringify(s),  
                            });  
                        } else {  
                            this.currentNFCInfo = "";  
                        }  
                    } else {  
                        console.log("NFC获取失败");  
                        uni.showToast({  
                            title: "NFC获取失败.",  
                            icon: "none"  
                        });  
                    }  

                } catch (e) {  
                    console.log(e);  
                    console.log("NFC获取失败,丢出异常");  
                    waiting.close();  
                    uni.showToast({  
                        title: "NFC获取失败,丢出异常.",  
                        icon: "none"  
                    });  
                    //TODO handle the exception    
                }  
            },  
            readData() {  
                readyRead = true;  
                //  waiting = plus.nativeUI.showWaiting("请将NFC标签靠近!");    
                setTimeout(this.handle_nfc_data, 1000);  
            },  
            __write(intent) {  
                try {  
                    waiting = plus.nativeUI.showWaiting("请将NFC标签靠近!");  
                    waiting.setTitle('请勿移开标签\n正在写入...');  
                    // var textBytes = plus.android.invoke(this.inputValue, "getBytes");  
                    // var typeBytes = plus.android.invoke('text/plain', 'getBytes')  
                    // 创建 NDEF 记录    
                    // var textRecord = new NdefRecord(  
                    //  NdefRecord.TNF_MIME_MEDIA, // TNF 类型    
                    //  typeBytes, // 类型(MIME 类型)    
                    //  null, // ID(留空以自动生成)    
                    //  textBytes, // 有效负载(文本的字节表示)    
                    // );  

                    // 创建包含 URI 的新 NDEF 记录  
                    var ndefRecord = NdefRecord.createUri(this.inputValue);  

                    var message = new NdefMessage([ndefRecord]);  
                    console.log('messgae=' + message)  
                    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()) {  
                            console.log("tag不允许写入");  
                            waiting.close();  
                            uni.showToast({  
                                title: "tag不允许写入.",  
                                icon: "none"  
                            });  
                            return;  
                        }  
                        if (ndef.getMaxSize() < size) {  
                            console.log("文件大小超出容量");  
                            waiting.close();  
                            uni.showToast({  
                                title: "文件大小超出容量.",  
                                icon: "none"  
                            });  
                            return;  
                        }  
                        // console.log('写入数据:' + JSON.stringify(message) + ' __TYPE__: ' + JSON.stringify(message.__TYPE__));    
                        console.log("message:" + message)  
                        ndef.writeNdefMessage(message);  

                        waiting.close();  
                        console.log("写入数据成功.");  
                        uni.showToast({  
                            title: "写入数据成功.",  
                            icon: "none"  
                        });  
                        return;  
                    } else {  
                        var format = NdefFormatable.get(tag);  
                        if (format != null) {  
                            try {  
                                format.connect();  
                                format.format(message);  
                                console.log("格式化tag并且写入message")  
                                waiting.close();  
                                return;  
                            } catch (e) {  
                                console.log("格式化tag失败.");  
                                waiting.close();  
                                uni.showToast({  
                                    title: "格式化tag失败.",  
                                    icon: "none"  
                                });  
                                return;  
                            }  
                        } else {  
                            console.log("Tag不支持NDEF");  
                            uni.showToast({  
                                title: "Tag不支持NDEF",  
                                icon: "none"  
                            });  
                            waiting.close();  
                            return;  
                        }  
                    }  
                } catch (e) {  
                    console.log("error=" + e);  
                    waiting.close();  
                    console.log('写入失败');  
                }  
            },  
            writeData() {  
                readyWriteData = true;  
                // waiting = plus.nativeUI.showWaiting("请将NFC标签靠近!");    
                setTimeout(this.handle_nfc_data, 1000);  
            },  
        },  
        onLoad: function(option) {  
            console.log('onLoad')  
            this.listenNFCStatus()  
        },  
        onShow: function() {  
            console.log('page Show');  
            this.listenNFCStatus()  
            this.timestampShow = (new Date()).getTime();  
            console.log(this.timestampShow)  
            var TimeScale = this.timestampShow - this.timestampHide;  
            console.log(TimeScale, nfcAdapter, '134 line');  
            if (nfcAdapter == null) {  
                alert("设备不支持NFC!");  
                return;  
            }  
            if (!nfcAdapter.isEnabled()) {  
                alert("请在系统设置中先启用NFC功能!");  
                return;  
            }  
            nfcAdapter && nfcAdapter.enableForegroundDispatch(main, pendingIntent, intentFiltersArray, techListsArray);  
            if (this.count++ == 0) {  
                // this.listenNFCStatus()    
                return false;  
            } else if (TimeScale > 400) {  
                return false;  
            } else {  
                // this.readData();  
                // this.writeData();  
            }  
        },  
        onHide: function() {  
            console.log("onHide");  
            this.timestampHide = (new Date()).getTime();  
            console.log(this.timestampHide);  
        }  
    }  
</script>  

<style>  
    .content {  
        display: flex;  
        flex-direction: column;  
        align-items: center;  
        justify-content: center;  
    }  

    .logo {  
        height: 200rpx;  
        width: 200rpx;  
        margin-top: 200rpx;  
        margin-left: auto;  
        margin-right: auto;  
        margin-bottom: 50rpx;  
    }  

    .text-area {  
        display: flex;  
        justify-content: center;  
    }  

    .title {  
        font-size: 36rpx;  
        color: #8f8f94;  
    }  
</style>
收起阅读 »