QT for android 获取PDA扫码的广播数据

前记

笔者接触到的PDA扫码枪,有三种, 一种是蓝牙枪,连接到手机或者电脑上之后,可以直接把扫描到的数据传送到焦点所在的文本框中;另外两种是普通的掌上扫码枪,笔者手中的一款也可以和蓝牙枪一样,操作系统中有设置,可以把扫描到的数据直接送到焦点所在的文本框中;还有一款是操作系统中没并有这个设置,而是通过Android的广播机制来进行发送,而前一种实际也是利用广播机制。
在Android Studio中,这一机制还是比较容易实现的,下面这一段Kotlin代码可以实现:

而在Qt中,如果要利用Android的广播,C++和QML都无法直接实现,需要用到Java。Qt官方有两个实例:Jni Messenger,Android Service with BroadcastReceiver,在Qt的欢迎界面搜索就可以查看源代码。这两个实例比较好的解释了广播机制的运用。

参考

笔者这里参考了一篇文章:QT for android 获取PDA扫码的广播数据并在QML中显示,这篇文章中实现了通过广播获取扫描到的数据的过程,但是这个数据只停留在Java中,C++页面如果想获取数据,必须要C++自己去Java中拿,Java不能直接把数据推给C++。博主的方法可能是设置个时间,然后不停地刷新向Java要数据。

实现

笔者这里的实现是以Qt的实例Android Service with BroadcastReceiver为基础,作了下修改。在QT for android 获取PDA扫码的广播数据并在QML中显示这篇博文中,还有QtAndroid详解(1):QAndroidJniObject这一篇中,都有介绍怎么让C++获取Java的数据,所以笔者这里加入这一块,代码只有Java主动推送给C++的功能。

AndroidManifest.xml

上面两篇博文中好像都没有写到对这个文件的修改,实际上这个文件很重要,在Qt6.0版本之后,QtCreater默认显示的界面,只展示了可以让开发者修改的部分,避免修改不必要的部分。QT for android 获取PDA扫码的广播数据并在QML中显示,这篇文章中的MainActivity.java是扩展了Activity类,所以有一处修改:

而Qt官方的实例Android Service with BroadcastReceiver,这里没有修改,但是也对AndroidManifest.xml文件有要求,修改的地方如下:

原本是false,需要改为true。

包名

Qt官方的实例Android Service with BroadcastReceiver中引入了两个Java文件,ActivityUtils.java和QtAndroidService.java,这两个文件的头一行均是package org.qtproject.example.qtandroidservice;
如果要自己使用这两个文件的话,这里需要更改为自己的包名,同样,也是在AndroidManifest.xml一起修改:

需要注意的是,这两个Java文件不是放在.pro文件同级目录中,Qtt生成AndroidManifest.xml文件时会生成一个android文件夹,在这下面新建一个src文件夹,然后根据包名往下新建文件夹:包名是org.qtproject.example的话,就依次新建org->qtproject->example,然后把两个Java文件放在example文件夹中,最后在QtCreater中添加这两个文件。

源码

工程项目源文件不附了,这里附4个文件的源码,如前述,主功能为Java通过广播获取PDA扫描的数据,然后把数据主动推给C++,笔者这里没有用QML,C++与QML通信请参考其他。
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QObject>
#include <QtAndroid>
#include <QAndroidIntent>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();static MainWindow *instance() { return m_instance; }
public slots:void slot_test(QString);private:Ui::MainWindow *ui;
private:void registerNatives();void registerBroadcastReceiver();static MainWindow *m_instance;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"#include <QAndroidJniEnvironment>
#include <QAndroidIntent>
#include <QtDebug>
MainWindow *MainWindow::m_instance = nullptr;static void receivedFromAndroidService(JNIEnv *env, jobject /*thiz*/, jstring value)
{emit MainWindow::instance()->slot_test(env->GetStringUTFChars(value, nullptr));
}
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);m_instance = this;registerNatives();registerBroadcastReceiver();
}
void MainWindow::slot_test(QString x)
{ui->textBrowser->append(x);
}
MainWindow::~MainWindow()
{delete ui;
}void MainWindow::registerNatives()
{JNINativeMethod methods[] {{"sendToQt", "(Ljava/lang/String;)V", reinterpret_cast<void *>(receivedFromAndroidService)}};QAndroidJniObject javaClass("org/qtproject/example/ActivityUtils");QAndroidJniEnvironment env;jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());env->RegisterNatives(objectClass,methods,sizeof(methods) / sizeof(methods[0]));env->DeleteLocalRef(objectClass);
}void MainWindow::registerBroadcastReceiver()
{QAndroidJniEnvironment env;jclass javaClass = env.findClass("org/qtproject/example/ActivityUtils");QAndroidJniObject classObject(javaClass);classObject.callMethod<void>("registerServiceBroadcastReceiver","(Landroid/content/Context;)V",QtAndroid::androidContext().object());
}

ActivityUtils.java

package org.qtproject.example;import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;public class ActivityUtils {private static native void sendToQt(String message);private static final String TAG = "ActivityUtils";public static final String BROADCAST_NAME_ACTION = "android.intent.ACTION_DECODE_DATA";public void registerServiceBroadcastReceiver(Context context) {IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(BROADCAST_NAME_ACTION);context.registerReceiver(serviceMessageReceiver, intentFilter);Log.i(TAG, "Registered broadcast receiver");}private BroadcastReceiver serviceMessageReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {Log.i(TAG, "In OnReceive broadcast receiver");if (BROADCAST_NAME_ACTION.equals(intent.getAction())) {String name = intent.getStringExtra("barcode_string");Log.i(TAG, "Service received name: " + name);String message = "Hello " + name;sendToQt(message);Log.i(TAG, "Service sent back message: " + message);}}};
}

QtAndroidService.java

package org.qtproject.example;import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.os.IBinder;
import org.qtproject.qt5.android.bindings.QtService;
import android.content.IntentFilter;public class QtAndroidService extends QtService
{private static final String TAG = "QtAndroidService";@Overridepublic void onCreate() {super.onCreate();Log.i(TAG, "Creating Service");}@Overridepublic void onDestroy() {super.onDestroy();Log.i(TAG, "Destroying Service");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {int ret = super.onStartCommand(intent, flags, startId);String name = new String(intent.getByteArrayExtra("barcode_string"));Intent sendToUiIntent = new Intent();sendToUiIntent.setAction(ActivityUtils.BROADCAST_NAME_ACTION);Log.i(TAG, "Service sending broadcast");return ret;}@Overridepublic IBinder onBind(Intent intent) {return super.onBind(intent);}
}

笔者的Qt版本更新到了6.2.4,但是官方的例程是5.15.2,在6.0版本之后,Qt取消了androidextras模块,Android相关的QAndroidJniObject、QAndroidJniEnvironment等都并入了core中,所以如果使用6.0之后版本尝试的话,在.pro文件中不需要再添加QT+=androidextras。
更新日期:2022-03-25,此外,整个过程并没有研究透,所以博文写的也不透亮,稍后会写更详细。

优博讯i6200s,安卓4.1版本

private String barcodeStr;
public static final String BROADCAST_NAME_ACTION = "urovo.rcv.message";、
byte[] barcode = intent.getByteArrayExtra("barcode");
int barocodelen = intent.getIntExtra("length", 0);
barcodeStr = new String(barcode, 0, barocodelen);

QT for android 获取PDA扫码的广播数据相关推荐

  1. 安卓版PDA扫码获取扫描枪数据;input获取焦点不弹出虚拟键盘;解决页面btn可操作数据的逻辑,导致DOM元素渲染,input的readonly失效

    html部分: 页面需要一个容器来接收扫描数据 注意:安卓版PDA扫描不同于win系统版本,安卓版本获取扫描数据时并不是keyCode按键依次获取,而是一次性给出扫描的数据 <!--扫描枪数据接 ...

  2. 家电空调手机行业序列号追溯溯源管理,汉码PDA扫码入库出库

    家电空调手机行业序列号追溯溯源管理,PDA扫码入库出库,销售售后跟踪,酒水序列号条码一物一码防伪防串货,PDA扫码入库出库仓库条码管理 在家电行业,空调行业,手机行业等,经常需要进行序列号管理,进行序 ...

  3. Qt for Android获取手机序列号/手机型号/手机制造商

    前言 Qt for Android 获取手机型号/手机制造商/手机序列号,这些是要通过 Android 原生接口才能获取到的, 那么在 Qt 项目中通过 jni 接口调用 Android 原生接口来获 ...

  4. pda通用扫描app_智能仓储盘点——PDA扫码盘点APP真正实现“轻松盘点”!

    原标题:智能仓储盘点--PDA扫码盘点APP真正实现"轻松盘点"! 又到了一年一度仓库大盘点的时期,年末盘点需要对仓库方方面面都盘点到位,要把当年的存货全部盘点清楚,想好如何处理, ...

  5. 金蝶云星空二维码整体解决方案 金蝶云星空条码管理系统 金蝶ERP移动解决方案 金蝶云星空条码扫描 金蝶云星空WMS仓库移动扫码 金蝶安卓PDA扫码方案 金蝶云星空出入库盘点出货条码扫码 提供源码

    本人在ERP实施公司做顾问四五年,参与企业实施ERP十多个项目,非常熟悉企业ERP流程,在实施过程遇到众多问题,提出了不少根据企业具体情况的解决方案.          最近定制开发了一套适合企业的条 ...

  6. 鼎捷ERP二维码整体解决方案 Tiptop GP条码管理系统 鼎捷ERP移动解决方案 鼎捷条码扫描 鼎捷WMS仓库移动扫码 鼎捷安卓PDA扫码方案 Tiptop 出入库盘点出货条码扫码

    本人在ERP实施公司做顾问四五年,参与企业实施ERP十多个项目,非常熟悉企业ERP流程,在实施过程遇到众多问题,提出了不少根据企业具体情况的解决方案. 最近定制开发了一套适合企业的条码扫码平台,基于鼎 ...

  7. Android 接入微信扫码库,实现堪比微信的扫码效果

    对于Android的扫码库,我们平时都会使用ZXing或者ZBar来实现. 但是实际情况是,对于一些环境恶劣的情况下,比如 眩光.昏暗.有污渍等情况下,很难被识别. 即使是在普通情况下,扫码的识别速度 ...

  8. PDA扫码设备放置一会就休眠的解决办法

    在使用pda扫码设备的时候,会发现 放置一会就回出现自动断网,需要他十几秒自动连回网来才能继续使用,这时候就需要我们使用app永久活跃的代码控制,下面是使用的插件,控制代码如下: hgService. ...

  9. 服装鞋帽吊牌条码如果用吉度PDA扫码出入库盘点

    服装行业使用管理软件时候,遇到条码吊牌比较多,比较杂,怎么办呢?很多用户遇到这种情况,直接不管理算了,还是只能人工去清点记录 为什么会遇到这种情况呢? 对一般商户来说,采购进货可能会有10家和几十家供 ...

最新文章

  1. 什么是机器人底盘 答案在这里!
  2. 可视化工具第一篇(百度Echarts)
  3. 目标检测近5年发展历程概述(转)
  4. 数据结构之堆:堆的排序,Python代码实现——13
  5. C#LeetCode刷题之#709-转换成小写字母(To Lower Case)
  6. db2插入的时候怎么自增_3篇长文讲“自增ID”,大部分人仍然搞错了!?
  7. C# .NET 中实现类似于化学表达式的,平方等的上下标的实现方法
  8. 社区发现算法之——Louvain
  9. java获取微信用户信息(UnionID)
  10. 小米 Notebook Air 2016 13.3黑苹果efi引导文件
  11. 指派问题程序c语言,指派问题lingo程序样例
  12. arduino——ATtiny85 SSD1306 + DHT
  13. 拼刀刀店铺后台的参数anti-content逆向分析
  14. Java实验-宠物商店(链表与接口的使用)
  15. Mysql增删改查(CURD)
  16. Matlab影像处理二
  17. 4G蓝牙信号(广播包)采集器
  18. 自动化操作桌面之根据图片移动鼠标
  19. linux 下动态链接库的创建与使用——dlopen,dlsym
  20. PDF格式分析(五十九) Color Spaces 颜色空间

热门文章

  1. ToneLab for Mac(ps人像修图插件)支持ps2021
  2. [架构之路-39]:目标系统 - 系统软件 - Linux OS内核进程/线程调度的基本原理
  3. 根据字段值查询其所在的表、字段
  4. 信用卡的账单日和还款日的区别
  5. 网易游戏TTT面试总结
  6. RK61 Keyboard Use
  7. 文案怎么写,为什么写不出好的文案
  8. 加强赛(二)B - Rotten Ropes POJ - 2291
  9. 恋爱话术库.免费版专为直们准备的恋聊天神器不知道怎么聊天的看过来
  10. 一、全Flash网站和单个Flash作品制作的区别