uniapp—android原生插件开发(2原生插件开发)

本篇文章从实战角度出发,将UniApp集成新大陆PDA设备RFID的全过程分为四部曲,涵盖环境搭建、插件开发、AAR打包、项目引入和功能调试。通过这份教程,轻松应对安卓原生插件开发与打包需求!

***环境问题移步至:uniapp—android原生插件开发(1环境准备)

一、将App离线SDK解压,并导入Android Studio中

下载地址:Android 离线SDK - 正式版 | uni小程序SDK

***强烈建议:不要不听劝,本人踩了两天坑,不然有意想不到的问题等着你解决

  1. 下载最新版本Android 离线SDK - 正式版,不然会出现不兼容问题。
  2. 最好用案例中的gradle版本,不然会出现不兼容问题。
  3. 包名能共用一个就共用一个,不然难的去找问题。
  • 解压App离线SDK、并将UniPlugin-Hello-AS项目导入Android Studio中

           

  • 等待编译完成,需要较长的时间(15分钟左右,根据电脑性能、网速决定)

二、新建自定义模块(uniplugin_rfid)

***强烈建议:不要不听劝,本人踩了两天坑,不然有意想不到的问题等着你解决

  1. 把模块名定义好。
  2. 把事先定义好的包名直接拿过来用(事先生成的appKey中填写的包名,此处用之前定义好的包名),当然也可以重新定义新的包名,然后再去改appKey中的包名,再重新生成appKey即可。
  • 新建模块,

  • 定义模块名、定义包名,生成模块

  • 中途可能会因为build.gradle编译报错,直接将uniplugin_module模块下的build.gradle覆盖刚生成模块下的build.gradle,然后点击Try Again或者Sync Now

  • 覆盖AndroidManifest.xml文件,并修改配置,此处会报错,会提示你新建一个java类,直接创建,然后UniModule类(必须继承UniModule,必须@UniJSMethod注解),此时AndroidManifest.xml还会报错,按照提示修复即可变成同样的结构。

  • 创建RfidModule类,如果上一步已创建则忽略此步骤

注意:必须继承UniModule,必须@UniJSMethod注解

  • 添加测试方法:
package com.recognition.uniplugin_rfid;

import android.content.Context;
import android.util.Log;

import com.alibaba.fastjson.JSONObject;
import com.nlscan.uhf.lib.UHFReader;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import io.dcloud.feature.uniapp.annotation.UniJSMethod;
import io.dcloud.feature.uniapp.bridge.UniJSCallback;
import io.dcloud.feature.uniapp.common.UniModule;

public class RfidModule extends UniModule {

    // 使用UniJSMethod注解,才能使用js调用
    @UniJSMethod(uiThread = false)
    public void  add(JSONObject json, UniJSCallback callback) {
        final int a = json.getInteger("a");
        final int b = json.getInteger("b");
        callback.invoke(new JSONObject() {{
            put("code", 0);
            put("result", a + b);
        }});
    }


    private MyUhfManager uhfManager;

    // 初始化UHF设备
    @UniJSMethod(uiThread = false)
    public void initialize(Context context) {
        if (context != null) {
            uhfManager = uhfManager.getInstance(context.getApplicationContext());
        } else {
            Log.e("UHFPlugin", "Context is null, using application context instead.");
            uhfManager = uhfManager.getInstance(context.getApplicationContext());
        }
    }

    // 连接UHF设备
    @UniJSMethod(uiThread = false)
    public boolean connect() {
        if (uhfManager != null) {
            final CountDownLatch latch = new CountDownLatch(1);
            final boolean[] isConnected = {false};

            uhfManager.powerOn(result -> {
                isConnected[0] = result;
                latch.countDown(); // 回调完成时释放锁
            });

            try {
                // 等待回调完成(设定超时以防止无尽等待)
                latch.await(5, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            return isConnected[0];
        }
        return false;
    }

    // 断开连接
    @UniJSMethod(uiThread = false)
    public boolean disconnect() {
        if (uhfManager != null && uhfManager.isPowerOn()) {
            // 假设调用 stopInventory 后达到断开效果
            UHFReader.READER_STATE stopInventoryState = uhfManager.stopInventory();

            // 如果有设置功率的方法,也可以尝试将功率设为零来模拟断开
            uhfManager.setReadPower(0, result -> {
                // 此处 result 用于表示功率设为0是否成功
            });

            // 检查 stopInventory 的状态是否成功
            return stopInventoryState == UHFReader.READER_STATE.OK_ERR;
        }
        return false;
    }



    // 启动盘点
    @UniJSMethod(uiThread = false)
    public boolean startInventory() {
        if (uhfManager != null) {
            UHFReader.READER_STATE state = uhfManager.startInventory();
            return state == UHFReader.READER_STATE.OK_ERR;
        }
        return false;
    }

    // 停止盘点
    @UniJSMethod(uiThread = false)
    public boolean stopInventory() {
        if (uhfManager != null) {
            UHFReader.READER_STATE state = uhfManager.stopInventory();
            return state == UHFReader.READER_STATE.OK_ERR;
        }
        return false;
    }

    // 读取标签数据
    @UniJSMethod(uiThread = false)
    public String readTagData(int bank, int address, int blkcnt, String accessPassword) {
        if (uhfManager != null) {
            byte[] data = uhfManager.getDataByArea(bank, accessPassword, blkcnt);
            return data != null ? UHFReader.bytes_Hexstr(data) : null;
        }
        return null;
    }

    // 写入标签数据到EPC区
    @UniJSMethod(uiThread = false)
    public boolean writeTagDataToEPC(String data, String accessPassword) {
        if (uhfManager != null) {
            final CountDownLatch latch = new CountDownLatch(1);
            final boolean[] writeSuccess = {false};

            uhfManager.writeDataToEPC(data, accessPassword, (result, state) -> {
                writeSuccess[0] = result;  // 将回调结果存储到数组中
                latch.countDown();         // 回调完成时释放锁
            });

            try {
                // 等待回调完成(设置超时防止阻塞)
                latch.await(5, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            return writeSuccess[0];  // 返回写入操作的结果
        }
        return false;
    }

    // 写入标签数据到用户区
    @UniJSMethod(uiThread = false)
    public boolean writeTagDataToUser(String data, String accessPassword) {
        if (uhfManager != null) {
            final CountDownLatch latch = new CountDownLatch(1);
            final boolean[] writeSuccess = {false};

            uhfManager.writeDataToUser(data, accessPassword, (result, state) -> {
                writeSuccess[0] = result;  // 将回调结果存储到数组中
                latch.countDown();         // 回调完成时释放锁
            });

            try {
                // 等待回调完成(设置超时防止阻塞)
                latch.await(5, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            return writeSuccess[0];  // 返回写入操作的结果
        }
        return false;
    }

}

三、将自定义插件添加到unapp插件中

  • 在app中的build.gradle中添加自定义插件模块

  • 在app中的dcloud_uniplugin.json添加自定义插件暴露的方法

编译通过即可,下一步进行真机调试。

快速通道:

uniapp—android原生插件开发(1环境准备)

uniapp—android原生插件开发(3Android真机调试)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/912617.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【DCCMCI】多模态情感分析的层次去噪、表征解纠缠和双通道跨模态-上下文交互

abstract 多模态情感分析旨在从文本、声音和视觉数据等各种模态中提取情感线索,并对其进行操作,以确定数据中固有的情感极性。尽管在多模态情感分析方面取得了重大成就,但在处理模态表征中的噪声特征、消除模态表征之间情感信息的实质性差距…

【网络安全】线程安全分析及List遍历

未经许可,不得转载。 文章目录 线程线程安全问题遍历List的方式方式一方式二方式三方式四(Java 8)方式五(Java 8 Lambda)遍历List的同时操作ListVector是线程安全的?使用线程安全的CopyOnWriteArrayList使用线程安全的List.forEach线程 线程是程序执行的最小单位。一个程…

基于MFC实现的赛车游戏

一、问题描述 游戏背景为一环形车道图,选择菜单选项“开始游戏”则可开始游戏。游戏的任务是使用键盘上的方向键操纵赛道上的蓝色赛车追赶红色赛车,红色赛车沿车道顺时针行驶,出发点和终点均位于车道左上方。任一赛车先达到终点则比赛结束。…

SpringBoot赋能的共享汽车业务管理系统

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示: 图4-1系统工作原理…

「QT」几何数据类 之 QLineF 浮点型直线类

✨博客主页何曾参静谧的博客📌文章专栏「QT」QT5程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid…

Elasticsearch专栏-4.es基本用法-查询api

es基本用法-查询api 说明查询所有某一字段匹配查询多字段查询bool查询范围查询精确查询正则匹配模糊查询结果处理 说明 es对数据的检索,总结下来就是两部分,即查询和处理。查询指的是查找符合条件的数据,包括查询所有、匹配查询、布尔查询、…

讨论一个mysql事务问题

最近在阅读一篇关于隔离级别的文章,文章中提到了一种场景,我们下面来分析一下。 文章目录 1、实验环境2、两个实验的语句执行顺序3、关于start transaction和start transaction with consistent snapshot4、实验结果解释4.1、实验14.2、实验24.3、调整实…

【AIGC】腾讯云语音识别(ASR)服务在Spring Boot项目中的集成与实践

腾讯云语音识别(ASR)服务在Spring Boot项目中的集成与实践 引言 在现代软件开发中,语音识别技术的应用越来越广泛,从智能助手到自动客服系统,语音识别技术都在发挥着重要作用。腾讯云提供了强大的语音识别服务&#…

基于Spring Boot的工程认证计算机课程管理系统

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及,互联网成为人们查找信息的重要场所,二十一世纪是信息的时代,所以信息的管理显得特别重要。因此,使用计算机来管理基于工程教育认证的计算机课程管理平台的相…

2024年度国际荐酒师(香港)协会花式马刀开香槟表演赛在穗举行

2024年度国际荐酒师(香港)协会花式马刀开香槟表演赛在穗举行 近日,一场别开生面的花式马刀开香槟表演赛在广州四季酒店盛大举行,此次活动由国际荐酒师(香港)协会精心指导,广东海上丝绸之路文化促…

mysql全量与增量备份

binlog日志: 从上一次全量备份到下一次全量备份直接产生的数据。 一、全备和增量备份介绍 1、全量备份: 备份所有数据库或只备份一个数据库,全量备份之后,全量备份之前的binlog日志就没用了,一般生产环境会保留3-7天…

Web前端开发--HTML语言

文章目录 前言1.介绍2.组成3.基本框架4.常见标签4.1双标签4.1.1.标题标签4.2.2段落标签4.1.3文本格式化标签4.1.4超链接标签4.1.5视频标签4.1.6 音频标签 4.2单标签4.2.1换行标签和水平线标签4.2.2 图像标签 5.表单控件结语 前言 生活中处处都有网站,无论你是学习爬…

存算一体化与边缘计算:重新定义智能计算的未来

随着数据量爆炸式增长和智能化应用的普及,计算与存储的高效整合逐渐成为科技行业关注的重点。数据存储和处理需求的快速增长推动了对计算架构的重新设计,“存算一体化”技术应运而生。同时,随着物联网、5G网络、人工智能(AI&#…

Kubernetes-ArgoCD篇-03-部署

1、从 Git 存储库创建应用程序 包含留言簿应用程序的示例存储库可在 https://github.com/argoproj/argocd-example-apps.git 上找到,以演示 Argo CD 的工作原理。 1.1 argocd server port-forward 我们这里通过port-forward 访问 Argo CD: kubectl p…

6层板设计常用知识笔记

1. 6层板设计叠层方案 (1)叠层方案优选以下方式 (2)过孔做固定孔时 plated作为固定孔时需要去掉勾选,焊盘去金属化。 (3)屏蔽罩:电源、主控存储、wifi需要加屏蔽罩,屏蔽…

【mongodb】数据库的安装及连接初始化简明手册

NoSQL(NoSQL Not Only SQL ),意即"不仅仅是SQL"。 在现代的计算系统上每天网络上都会产生庞大的数据量。这些数据有很大一部分是由关系数据库管理系统(RDBMS)来处理。 通过应用实践证明,关系模型是非常适合于客户服务器…

Unity跨平台基本原理

目录 前言 ​编辑 Mono Unity和Mono的关系 Unity跨平台必备概念 Mono利用 Mono主要构成部分 基于Mono跨平台的优缺点 IL2CPP Mono和IL2CPP的区别 Mono IL2CPP Mono和IL2CPP的使用建议 安装IL2CPP IL2CPP打包存在的问题 类型裁剪 泛型问题 前言 Unity跨平台的基…

【go从零单排】接口(interface)和多态(Polymorphism)

🌈Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 📗概念 在Go语言中,interface 是一种重要的类型,用于定义一组方法…

Science Robotics 综述揭示演化研究新范式,从机器人复活远古生物!

在地球46亿年的漫长历史长河中,生命的演化过程充满着未解之谜。如何从零散的化石证据中还原古生物的真实面貌?如何理解关键演化节点的具体过程?10月23日,Science Robotics发表重磅综述,首次系统性提出"古生物启发…

WPS文档中的“等线”如何删除

如何删除“等线”占用的行如何删除表格之间的空行WPS文档中的“等线”是什么如果删除脚注文本占用的行 如下这种,在文档中添加了表格和脚注,发现上下表格之间有多行空行,鼠标选中,显示是“等线”,那么如何去除等线占用…