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

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

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

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

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

头文件:

cdec0645add3fc3c328197dda5c76203.png

81178cc93a2a3bb5048d90d76e7ec935.png

1 #ifndef ZRDOWNLOAD_H2 #define ZRDOWNLOAD_H

3

4 #include

5 #include

6 #include

7 #include

8 #include

9 #include

10

11 class ZRDownload : publicQObject12 {13 Q_OBJECT14 Q_PROPERTY(QString url READ GetUrl WRITE SetUrl)15 Q_PROPERTY(QString fileName READ GetFileName WRITE SetFileName)16 public:17 explicit ZRDownload(QObject *parent = 0);18 ~ZRDownload();19

20 QString GetUrl();21 voidSetUrl(QString u);22 QString GetFileName();23 voidSetFileName(QString fn);24 private:25 QString url;26 QString fileName;27 QFile *file;28 QNetworkAccessManager *accessManager;29 QNetworkRequest request;30 QNetworkReply *reply;31

32 signals:33 void progressPosition(double pre); //更新进度条信号

34 void downloadFinished(); //结束信号

35

36 protectedslots:37 voidhttpDownload();38 void replyFinished(QNetworkReply*reply);39 voidonDownloadProgress(qint64 bytesSent,qint64 bytesTotal);40 voidonReadyRead();41 };42

43 #endif //ZRDOWNLOAD_H

View Code

CPP文件:

cdec0645add3fc3c328197dda5c76203.png

81178cc93a2a3bb5048d90d76e7ec935.png

#include "zrdownload.h"#includeZRDownload::ZRDownload(QObject*parent) : QObject(parent)

{

accessManager=NULL;

reply=NULL;

}

ZRDownload::~ZRDownload()

{

}

QString ZRDownload::GetUrl()

{returnurl;

}voidZRDownload::SetUrl(QString u)

{

url=u;

}

QString ZRDownload::GetFileName()

{returnfileName;

}voidZRDownload::SetFileName(QString fn)

{

fileName=fn;

}voidZRDownload::httpDownload(){

file=newQFile(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();deletefile;

file=NULL;

}else{//处理错误

}

reply->deleteLater();//要删除reply,但是不能在repyfinished里直接delete,要调用deletelater;

reply=NULL;

accessManager->deleteLater();

accessManager=NULL;

downloadFinished();

}/***********更新进度条*************/

voidZRDownload::onDownloadProgress(qint64 bytesSent, qint64 bytesTotal){double pre = double(bytesSent)/bytesTotal;

progressPosition(pre);

}voidZRDownload::onReadyRead(){

file->write(reply->readAll());

}

View Code

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

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

main.cpp:

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

QML调用:

1 ZRDownload{2 id:download3 url:"http://xxx.xxx.com/xx.apk"

4 fileName:""

5 onProgressPosition:progressBar.update(pre) //自定义更新进度条函数

6 onDownloadFinished: {7 //下载完成

8 }9 }10

11 //启动下载

12 download.fileName=getAppPath();//设置保存目录,pc和安卓不同

13 download.httpDownload();

第三步,安装程序:

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

cdec0645add3fc3c328197dda5c76203.png

81178cc93a2a3bb5048d90d76e7ec935.png

1 #ifndef ZRINSTALL_H2 #define ZRINSTALL_H

3

4 #include

5 #include

6

7 class ZRInstall : publicQObject8 {9 Q_OBJECT10 Q_PROPERTY(QString fileName WRITE SetFileName)11 public:12 explicit ZRInstall(QObject *parent = 0);13

14 voidSetFileName(QString fn);15 signals:16

17 publicslots:18 voidinstall();19 private:20 QString m_FileName;21 };22

23 #endif //ZRINSTALL_H

头文件

cdec0645add3fc3c328197dda5c76203.png

81178cc93a2a3bb5048d90d76e7ec935.png

1 #include "zrinstall.h"

2 #include

3 #if defined(Q_OS_ANDROID)

4 #include

5 #else

6 #include

7 #endif

8

9 ZRInstall::ZRInstall(QObject *parent) : QObject(parent)10 {11

12 }13

14 voidZRInstall::SetFileName(QString fn)15 {16 m_FileName =fn;17 }18

19 voidZRInstall::install()20 {21 #if defined(Q_OS_ANDROID)

22 //安装apk

23 QAndroidJniObject path = QAndroidJniObject::fromString("file://"+m_FileName);24 QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", path.object());25 QAndroidJniObject param = QAndroidJniObject::getStaticObjectField("android/content/Intent", "ACTION_VIEW");26 QAndroidJniObject intent("android/content/Intent","(Ljava/lang/String;)V",param.object());27 QAndroidJniObject type = QAndroidJniObject::fromString("application/vnd.android.package-archive");28 QAndroidJniObject result = intent.callObjectMethod("setDataAndTypeAndNormalize", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/content/Intent;", uri.object(), type.object());29 QtAndroid::startActivity(intent, 1001, 0);30 #else

31 //qDebug()<

32 QProcess * proc = newQProcess();33 proc->startDetached(m_FileName,QStringList());34 deleteproc;35 #endif

36 }

CPP文件

cdec0645add3fc3c328197dda5c76203.png

81178cc93a2a3bb5048d90d76e7ec935.png

1 android{2 QT +=androidextras3 }

项目文件pro

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

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

原文:http://www.cnblogs.com/SamFang/p/5996056.html

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐