首页 > 代码库 > QML 从无到有 3 (自动更新)
QML 从无到有 3 (自动更新)
新的需求出来啦,需要自动更新功能,不怕程序升级了。
自动更新,QML不好写,需要c++来辅助,这里就涉及QML中调用c++功能(这里就不写了,百度一下,很多)。
思路:获取版本》下载程序》安装程序
第一步,获取版本信息,可以通过XMLHttpRequest获取最新版本。
第二步,下载程序,通过Qt c++的QtNetwork:
头文件:
1 #ifndef ZRDOWNLOAD_H 2 #define ZRDOWNLOAD_H 3 4 #include <QObject> 5 #include <QtNetwork/QNetworkAccessManager> 6 #include <QFile> 7 #include <QtNetwork/QNetworkReply> 8 #include <QtNetwork/QNetworkRequest> 9 #include <QIODevice>10 11 class ZRDownload : public QObject12 {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 void SetUrl(QString u);22 QString GetFileName();23 void SetFileName(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 protected slots:37 void httpDownload();38 void replyFinished(QNetworkReply*reply);39 void onDownloadProgress(qint64 bytesSent,qint64 bytesTotal);40 void onReadyRead();41 };42 43 #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调用:
1 ZRDownload{ 2 id:download 3 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实现。下面是代码:
1 #ifndef ZRINSTALL_H 2 #define ZRINSTALL_H 3 4 #include <QObject> 5 #include <QString> 6 7 class ZRInstall : public QObject 8 { 9 Q_OBJECT10 Q_PROPERTY(QString fileName WRITE SetFileName)11 public:12 explicit ZRInstall(QObject *parent = 0);13 14 void SetFileName(QString fn);15 signals:16 17 public slots:18 void install();19 private:20 QString m_FileName;21 };22 23 #endif // ZRINSTALL_H
1 #include "zrinstall.h" 2 #include <QDebug> 3 #if defined(Q_OS_ANDROID) 4 #include <QtAndroid> 5 #else 6 #include <QProcess> 7 #endif 8 9 ZRInstall::ZRInstall(QObject *parent) : QObject(parent)10 {11 12 }13 14 void ZRInstall::SetFileName(QString fn)15 {16 m_FileName = fn;17 }18 19 void ZRInstall::install()20 {21 #if defined(Q_OS_ANDROID)22 //安装apk23 QAndroidJniObject path = QAndroidJniObject::fromString("file://"+m_FileName);24 QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", path.object<jstring>());25 QAndroidJniObject param = QAndroidJniObject::getStaticObjectField<jstring>("android/content/Intent", "ACTION_VIEW");26 QAndroidJniObject intent("android/content/Intent","(Ljava/lang/String;)V",param.object<jstring>());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<jobject>(), type.object<jstring>());29 QtAndroid::startActivity(intent, 1001, 0);30 #else31 //qDebug()<<m_FileName;32 QProcess * proc = new QProcess();33 proc->startDetached(m_FileName,QStringList());34 delete proc;35 #endif36 }
1 android{2 QT += androidextras3 }
调用就不写了,可以参考上面download。
这样整个版本自动更新就写好了,有一些细节自己需要注意,如下载安装文件不同,安装目录不同。
QML 从无到有 3 (自动更新)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。