新的需求出来啦,需要自动更新功能,不怕程序升级了。

自动更新,QML不好写,需要c++来辅助,这里就涉及QML中调用c++功能(这里就不写了,百度一下,很多)。

思路:获取版本》下载程序》安装程序

第一步,获取版本信息,可以通过XMLHttpRequest获取最新版本。

第二步,下载程序,通过Qt c++的QtNetwork:

头文件:

 #ifndef ZRDOWNLOAD_H
#define ZRDOWNLOAD_H #include <QObject>
#include <QtNetwork/QNetworkAccessManager>
#include <QFile>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include <QIODevice> class ZRDownload : public QObject
{
Q_OBJECT
Q_PROPERTY(QString url READ GetUrl WRITE SetUrl)
Q_PROPERTY(QString fileName READ GetFileName WRITE SetFileName)
public:
explicit ZRDownload(QObject *parent = );
~ZRDownload(); QString GetUrl();
void SetUrl(QString u);
QString GetFileName();
void SetFileName(QString fn);
private:
QString url;
QString fileName;
QFile *file;
QNetworkAccessManager *accessManager;
QNetworkRequest request;
QNetworkReply *reply; signals:
void progressPosition(double pre); //更新进度条信号
void downloadFinished(); //结束信号 protected slots:
void httpDownload();
void replyFinished(QNetworkReply*reply);
void onDownloadProgress(qint64 bytesSent,qint64 bytesTotal);
void onReadyRead();
}; #endif // ZRDOWNLOAD_H

CPP文件:

#include "zrdownload.h"
#include <QDebug> ZRDownload::ZRDownload(QObject *parent) : QObject(parent)
{
accessManager = NULL;
reply = NULL;
}
ZRDownload::~ZRDownload()
{
} QString ZRDownload::GetUrl()
{
return url;
} void ZRDownload::SetUrl(QString u)
{
url = u;
} QString ZRDownload::GetFileName()
{
return fileName;
} void ZRDownload::SetFileName(QString fn)
{
fileName = fn;
} void ZRDownload::httpDownload(){ file=new QFile(fileName);
bool suc = file->open(QIODevice::WriteOnly);//只读方式打开文件 accessManager=new QNetworkAccessManager(this); request.setUrl(url); /******************设置http的header***********************/
// request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data");
// request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");
// request.setRawHeader("Content-Disposition","form-data;name='doc';filename='a.txt'");
//request.setHeader(QNetworkRequest::ContentLengthHeader,post_data.length()); reply=accessManager->get(request);//通过发送数据,返回值保存在reply指针里.
connect(accessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));//finish为manager自带的信号,replyFinished是自定义的
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT( onDownloadProgress(qint64 ,qint64 )));//download文件时进度
connect((QObject *)reply, SIGNAL(readyRead()),this, SLOT(onReadyRead())); }
/***************响应结束**************************/
void ZRDownload::replyFinished(QNetworkReply *reply){
//获取响应的信息,状态码为200表示正常
QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QByteArray bytes = reply->readAll(); //获取字节
QString result(bytes); //转化为字符串 //无错误返回
if(reply->error() == QNetworkReply::NoError)
{
QByteArray bytes = reply->readAll(); //获取字节
QString result(bytes); //转化为字符串 file->flush();
file->close();
delete file;
file=NULL;
}
else
{
//处理错误
} reply->deleteLater();//要删除reply,但是不能在repyfinished里直接delete,要调用deletelater;
reply=NULL; accessManager->deleteLater();
accessManager=NULL; downloadFinished();
} /***********更新进度条*************/
void ZRDownload::onDownloadProgress(qint64 bytesSent, qint64 bytesTotal){ double pre = double(bytesSent)/bytesTotal; progressPosition(pre);
} void ZRDownload::onReadyRead(){ file->write(reply->readAll());
}

上面的代码也是修改网上的代码,增加了QML调用的信息。

注意:项目文件pro中需要添加 QT += network

main.cpp:

添加 qmlRegisterType<ZRDownload>("xxx.xxx.ZRDownload", 1, 0, "ZRDownload");

QML调用:

 ZRDownload{
id:download
url:"http://xxx.xxx.com/xx.apk"
fileName:""
onProgressPosition:progressBar.update(pre) //自定义更新进度条函数
onDownloadFinished: {
//下载完成
}
} //启动下载
download.fileName=getAppPath();//设置保存目录,pc和安卓不同
download.httpDownload();

第三步,安装程序:

不同平台,安装程序的代码也不同,PC平台使用QProcess启动安装程序,安卓平台通过QAndroidJniObject调用Activity实现。下面是代码:

 #ifndef ZRINSTALL_H
#define ZRINSTALL_H #include <QObject>
#include <QString> class ZRInstall : public QObject
{
Q_OBJECT
Q_PROPERTY(QString fileName WRITE SetFileName)
public:
explicit ZRInstall(QObject *parent = ); void SetFileName(QString fn);
signals: public slots:
void install();
private:
QString m_FileName;
}; #endif // ZRINSTALL_H

头文件

 #include "zrinstall.h"
#include <QDebug>
#if defined(Q_OS_ANDROID)
#include <QtAndroid>
#else
#include <QProcess>
#endif ZRInstall::ZRInstall(QObject *parent) : QObject(parent)
{ } void ZRInstall::SetFileName(QString fn)
{
m_FileName = fn;
} void ZRInstall::install()
{
#if defined(Q_OS_ANDROID)
//安装apk
QAndroidJniObject path = QAndroidJniObject::fromString("file://"+m_FileName);
QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", path.object<jstring>());
QAndroidJniObject param = QAndroidJniObject::getStaticObjectField<jstring>("android/content/Intent", "ACTION_VIEW");
QAndroidJniObject intent("android/content/Intent","(Ljava/lang/String;)V",param.object<jstring>());
QAndroidJniObject type = QAndroidJniObject::fromString("application/vnd.android.package-archive");
QAndroidJniObject result = intent.callObjectMethod("setDataAndTypeAndNormalize", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/content/Intent;", uri.object<jobject>(), type.object<jstring>());
QtAndroid::startActivity(intent, , );
#else
//qDebug()<<m_FileName;
QProcess * proc = new QProcess();
proc->startDetached(m_FileName,QStringList());
delete proc;
#endif
}

CPP文件

 android{
QT += androidextras
}

项目文件pro

调用就不写了,可以参考上面download。

这样整个版本自动更新就写好了,有一些细节自己需要注意,如下载安装文件不同,安装目录不同。

QML 从无到有 3 (自动更新)的更多相关文章

  1. 解析大型.NET ERP系统 自动更新

    C/S架构的应用程序需要支持自动更新功能,当新版本程序发布后,正在运行的客户端能检测到新版本的程序,通知用户是否下载更新.工作以来参与过几个自动更新模块的设计与维护,撰文总结自动更新模块设计与实现. ...

  2. 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常

    在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件.但对于数据绑定bindingList而言,没法响应 ...

  3. 分析nuget源码,用nuget + nuget.server实现winform程序的自动更新

    源起 (个人理解)包管理最开始应该是从java平台下的maven开始吧,因为java的开发大多数是基于开源组件开发的,一个开源包在使用时很可能要去依赖其他的开源包,而且必须是特定的版本才可以.以往在找 ...

  4. ClickOnce部署(2):自动更新

    上次我们说了如何用最基本的方式用ClickOnce技术部署应用程序项目,本篇我们来认识一下如何让应用程序具备自动更新的功能. 我们依然通过实例来学习. 第一步,随便建一个应用程序项目,至于是控制台.W ...

  5. Android接入百度自动更新SDK

    一:前言 公司的app,上传到百度应用市场,然后说必须要接入百度的自动更新sdk才能上架,于是从百度官网上去下载jar包,下载的时候必须要带上数据统计,如果使用自动的jar包,还需要带上广告联盟,坑爹 ...

  6. C#之tcp自动更新程序

    .NETTCP自动更新程序有如下几步骤: 第一步:服务端开启监听 ServiceHost host; private void button1_Click(object sender, EventAr ...

  7. 使用 SVN Hook 实现服务器端代码自动更新

    之前的做法是客户端提交代码之后,再去服务器端项目中 svn up 一下来更新代码,让服务器端的项目更新到最新版本.可以编写一个 post-commit 钩子脚本来实现服务器端代码的自动更新,它在 SV ...

  8. git 远程版本库,github提供服务原理,git自动更新发送邮件

    1.安装好Linux,安装好Git(192.168.1.239) 2.创建一个用户zph(让此用户提供git on server),密码设置为12345678 # useradd zph # pass ...

  9. 【原创】我所理解的自动更新-APP发布与后台发布

    发布后台 创建渠道:添加新的渠道,设置渠道名称,自动生成渠道id.    查看渠道:查看渠道基本信息,渠道app版本号,资源版本号,是否开启更新.    创建/更新APP:选择打包ios,androi ...

随机推荐

  1. JQuery(2)

    JQuery下拉框操作: 取值赋值操作 body代码: <select id="sel"> <option value="北京">北京& ...

  2. bzoj1079--记忆化搜索

    题目大意:有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得 ...

  3. springmvc+bootstrap+jquerymobile完整搭建案例(提供下载地址)

    用一张简单的截图说明下,然后提供一个下载地址. bootstrap的大部分样式官方都是写好的,所以只需要class="官方样式即可",具体可以看官方的案例,下面来个地址 http: ...

  4. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  5. MySQL+Amoeba实现数据库主从复制和读写分离

    MySQL读写分离是在主从复制的基础上进一步通过在master上执行写操作,在slave上执行读操作来实现的.通过主从复制,master上的数据改动能够同步到slave上,从而保持了数据的一致性.实现 ...

  6. 分布式唯一ID生成服务

    SNService是一款基于分布式的唯一ID生成服务,主要用于提供大数量业务数据建立唯一ID的需要;服务提供最低10K/s的唯一ID请求处理.如果你部署服务的CPU资源达到4核的情况下那该服务最低可以 ...

  7. Web 项目杂记(一)

    1.Tomcat 多实例部署 在Tomcat下多实例部署后,发现如下问题,采用etc/init.d/tomcat start方式无法启动,而需要采用startup.sh.查找原因发现,是因为多实例部署 ...

  8. Fedora 21 安装 Nvidia 驱动以及失败后的补救方法

    在 Linux 桌面系统下玩了这么久,大部分时间都是使用 Ubuntu,偶尔使用一下 Fedora.我的电脑中安装有多个 Linux 发行版,见这里<在同一个硬盘上安装多个Linux发行版及Fe ...

  9. 清除Android工程中没用到的资源

    项目需求一改再改,UI一调再调,结果就是项目中一堆已经用不到但却没有清理的垃圾资源,不说工程大小问题,对新进入项目的人或看其他模块的代码的人来说,这些没清理的资源可能也可能会带来困扰,所以最好还是清理 ...

  10. 用VB脚本批到导入字段到PowerDesigner

    在PowerDesigner使用脚本批量导入excel中记录的表结构信息,由于需要通过powerdesigner逆向工程创建一些sybase IQ的表,由于是接口数据,只有excel表,手动导入太耗时 ...