在上一篇,我们搭建了开发环境。本篇,使用C++代码真正实现功能。我们使用UDP协议从手机上指定发送的目的地、端口。效果如下图,完整工程参考https://gitcode.net/coloreaglestdio/qtcpp_demo/-/tree/master/android/sensors2pc:

移动端1 移动端2 桌面

1. 在PC端实现程序并调试

我们建立一个Qt的Widgets程序,添加 position, sensors模块。

  • 界面里支持设置目的地址、端口。
  • 界面里可以设置GPS与各个传感器的刷新速度。
  • 传感器使用Qt枚举,并创建刷新函数。

传感器的主对话框类如下:

#ifndef DLGSTP_H
#define DLGSTP_H#include <QDialog>
#include <QGeoPositionInfoSource>
#include <QStandardItemModel>
#include <QUdpSocket>
#include <QSensor>
#include <functional>
QT_BEGIN_NAMESPACE
namespace Ui { class DlgSTP; }
QT_END_NAMESPACEclass DlgSTP : public QDialog
{Q_OBJECT
public:DlgSTP(QWidget *parent = nullptr);~DlgSTP();void EnumSensors();void openGPS();
protected:void timerEvent(QTimerEvent * evt) override;
private:Ui::DlgSTP *ui;QStandardItemModel * m_pMsgMod = 0;int m_nTimer = -1;
protected://Sensors Update LambdasQList<std::function<void (void)> > m_sensorUpdaters;
protected://GPSQGeoPositionInfoSource *m_pos_source = 0;
protected://Net SendQUdpSocket * m_psock = 0;QStringList m_listInfo;
};
#endif // DLGSTP_H//cppDlgSTP::DlgSTP(QWidget *parent): QDialog(parent), ui(new Ui::DlgSTP), m_pMsgMod(new QStandardItemModel(this)), m_psock(new QUdpSocket(this))
{ui->setupUi(this);ui->listView_msg->setModel(m_pMsgMod);showMaximized();//Open GPS DeviceopenGPS();//Enum all sensorsEnumSensors();loadSettings();m_nTimer = startTimer(20);
}

1.1 枚举传感器并建立界面

通过Qt的Sensors可以枚举到传感器的取值。

void DlgSTP::EnumSensors()
{QList<QByteArray> sensors = QSensor::sensorTypes();QString strSensors = "Sensors:\n";for (QByteArray stp : sensors){QSensor * sensor = new QSensor(stp);sensor->start();//添加界面刷新QListView * lstView = new QListView(this);QStandardItemModel * m_pMod = new QStandardItemModel(this);lstView->setModel(m_pMod);QString name = stp;ui->tabWidget->addTab(lstView,name);//设置刷新函数(供定时器调用),使用Lamdba后期调用,省的建立函数了。m_sensorUpdaters<<[sensor,m_pMod,this,lstView,name](void)->void{QSensorReading *reading = sensor->reading();QString str = "SENSOR="+name + ";\n";//获取当前传感器有多少数值int n = reading->valueCount();for (int i=0;i<n;++i){QVariant vt = reading->value(i);str += QString("%1").arg(vt.toString());}//消息写入m_listInfo,后续发送m_listInfo << str;m_pMod->appendRow(new QStandardItem(str));lstView->scrollToBottom();};}
}

值得注意的是,上面的代码是在实际代码中进行了简化。实际代码里为了避免频繁刷新界面的同时,迅速吞吐传感器数据,进行了一些处理。可参考实际源码。

1.2 初始化GPS

GPS是手机的一个重要功能。通过初始化GPS,可以实时获取位置、时刻。

void DlgSTP::openGPS()
{m_pos_source = QGeoPositionInfoSource::createDefaultSource(0);if (m_pos_source){//Add TabQListView * lstView = new QListView(this);QStandardItemModel * m_pMod = new QStandardItemModel(this);lstView->setModel(m_pMod);ui->tabWidget->addTab(lstView,"GPS");//直接把GPS刷新信号绑定到Lambdaconnect (m_pos_source,&QGeoPositionInfoSource::positionUpdated,[lstView,m_pMod,this](const QGeoPositionInfo &update)->void{double lat = update.coordinate().latitude();double lon = update.coordinate().longitude();QDateTime dtm = update.timestamp();QString str = QString("SENSOR=GPS;\nGMT_TIME=%1;\nLAT=%2;\nLON=%3;\n").arg(dtm.toString("yyyy-MM-dd HH:mm:ss")).arg(lat,0,'f',7).arg(lon,0,'f',7);//消息写入m_listInfo,后续发送m_listInfo << str;m_pMod->appendRow(new QStandardItem(str));lstView->scrollToBottom();});//即使出错了,也继续开始,把出错的信息绑定到Lambdaconnect (m_pos_source,&QGeoPositionInfoSource::errorOccurred,[this](QGeoPositionInfoSource::Error pe)->void{m_pos_source->startUpdates();m_pMsgMod->appendRow(new QStandardItem(QString("GPS Err Code %1.").arg(int(pe))));});//开启GPSm_pos_source->setUpdateInterval(ui->horizontalSlider_gps->value());m_pos_source->startUpdates();}elsem_pMsgMod->appendRow(new QStandardItem("No GPS Found!"));
}

1.3 发送UDP

设置一个定时器,进行UDP发射。定时器的尺度是20ms的整数倍,可以调整。

void  DlgSTP::timerEvent(QTimerEvent * evt)
{if (evt->timerId()==m_nTimer){++m_clk;//UDP Sendconst int updateITV = ui->horizontalSlider_freq->value();const int updateGUI = (50 / (updateITV>50?50:updateITV) )* updateITV;if (m_clk % updateITV ==0 ){//调用各个Lambda刷新传感器,消息写入m_listInfoforeach(auto fn, m_sensorUpdaters)fn();//发送QHostAddress addr (ui->lineEdit_ip->text());int port = ui->spinBox_port->value();foreach(QString i, m_listInfo)m_psock->writeDatagram(i.toLocal8Bit(),addr,port);m_nTotalSent += m_listInfo.size();m_listInfo.clear();//适时更新界面if (m_clk % updateGUI==0){m_pMsgMod->appendRow(new QStandardItem(QString("%1>%2 items sent.").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")).arg(m_nTotalSent)));if (m_pMsgMod->rowCount()>MAX_ROWS_LSTV)m_pMsgMod->removeRows(0,m_pMsgMod->rowCount()-MAX_ROWS_LSTV);ui->listView_msg->scrollToBottom();}}}
}

我们在PC上可以先调试,发现PC上竟然也有很多传感器。

2 部署到Android 手机

我们在手机上打开调试模式,一般是连续击打系统版本号,即可打开。打开后,手机会提示允不允许USB调试,点击允许即可。

如果编译Debug版本,是不需要证书签名的。如果是Release,需要签名。

2.1 设置应用程序的名字和图标

在项目设置里,直接创建app的manifest

创建后,即可编辑名字、图标:

2.2 创建证书

在构建选项里,选择创建证书,输入必要信息后完成创建。注意,Release版本如果构建不成功,就要重新开启一下签名。为了安全,QtCreator会确保是你本人在烧写程序。

创建后,选择“”包签名“”即可开启签名。注意,Release版本如果构建不成功,就要重新开启一下签名。为了安全,QtCreator会确保是你本人在烧写程序,会经常清除这个选项,以便您再次输入密码。

2.3 部署并运行程序

确保在Qt的编译栏选取了适当的设备(API版本一致),且绿色按钮出现(而非红色)

3 在PC上接收数据

当计算机、手机处于一个局域网,或者是处于IP可达的网络时,在PC端就可以接收到消息了。

使用 Qt for Android 获取并利用手机传感器数据(下篇)使用C++实现功能相关推荐

  1. 使用 Qt for Android 获取并利用手机传感器数据(上篇)开发环境省心搭建

    现代手机拥有许多传感器,包括地磁.姿态.GPS.光照.温度.气压.摄像.声音.电磁等,完全就是一个高度集成的科学仪器.不夸张的说,一部手机加上一个外围的计算机和控制系统,做一个功能较强的自主移动机器人 ...

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

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

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

    QT for android 获取PDA扫码的广播数据 前记 笔者接触到的PDA扫码枪,有三种, 一种是蓝牙枪,连接到手机或者电脑上之后,可以直接把扫描到的数据传送到焦点所在的文本框中:另外两种是普通 ...

  4. STM32 BMP280模块 获取气压温度高度传感器数据 TFT显示

    STM32 BMP280模块 获取气压温度高度传感器数据 TFT显示 简介 BMP280是博世最新推出的数字气压传感器,具有卓越的性能和低廉的价格,相对精度为±0.12 hPa(相当于±1米),传感器 ...

  5. Qt for Android获取手机热点开关状态

    Qt开发android应用,从Qt端调用android原生接口获取手机热点开关状态,首先来看一下封装好的android接口类wifiHostBiz.java (以下代码来自网络) package co ...

  6. Qt for Android 程序实现对手机文件的导入打开与导出保存

    一.概述 在Qt for Android下程序要实现这样的功能:对创建的数据以txt文件格式保存导出到手机内部存储器,并且可以随时的加载,导入到手机上运行的程序中.但是在Qt for Android下 ...

  7. Qt for android不能连接华为手机

    使用Qt for android开发手机app应用,出现了几个问题: (一)不能连接华为手机的问题,调查过程如下: 1)华为mate9手机,通过USB连接电脑 2)设置了开发者选项中的[USB调试]等 ...

  8. android返回上一级代码,Android实践11 | 利用intent返回数据给上一级activity

    利用intent返回数据给上一级activity 2018-05-08_154146.jpg activity间数据传递的,不但可以把数据从一个activity传给下一个activity,也可以从下一 ...

  9. Qt for Android获取手机序列号

    在 Qt 项目中通过 jni 接口调用 Android 原生接口来获取相应的值. java文件 package com.qt.useJava;import android.os.Build; impo ...

最新文章

  1. 删除表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断,只留有rowid最小的记录...
  2. 资本主义社会是不存在人道的
  3. 如何在Github上精准地找到想要的开源项目?
  4. C++_重载new,delete
  5. 大鱼吃光小鱼,绝不可能!盘点2016存储行业发生的大事件
  6. C++ bitset的用法
  7. 进程函数一步步理解Linux进程(2)--进程编程进程函数
  8. valgrind检测内存泄露
  9. Yii 2.0 权威指南(7) 关键概念
  10. python实践gcForest模型对鸢尾花数据集iris进行分类
  11. HG255D电信原版刷机实战整理,既HG255D刷uboot、Openwrt
  12. 如何评价《Java 并发编程艺术》这本书?
  13. 四、登录注册页功能实现《iVX低代码/无代码个人博客制作》
  14. 我的第一本社会心理学(part2)--社会心理学的理论与方法
  15. 安卓 魔窗SDK 快速接入
  16. 掌握算法本质背后的计算思维,尽在吴军博士《计算之魂》这本书中
  17. 最新《Linux系统优化+Linux综合架构课程》
  18. 依靠双工福禄克测试仪进行MPO电缆认证
  19. 程序设计之学生宿舍管理系统
  20. Redis—列表(List)、集合(Set)、哈希(Hash)、有序集合 Zset

热门文章

  1. python io模块
  2. PMBOK6相关方:权利利益方格
  3. 从千牛产品策略看电商客服接待场景
  4. 简易理解设计模式之:责任链模式——OA中请假流程示例
  5. 计算机如何进行加减乘除计算—(计算机基础课十三)​​​​​​​​​​​​​​
  6. python3爬虫系列21之selenium自动化登录163邮箱并读取未读邮件内容
  7. HPRT HLP106S-UE 驱动
  8. Docker——阿里云镜像加速
  9. opencv中的人脸检测案例
  10. python halcon_HALCON高级篇:常用分类器及其特点