如何写一个Andorid下关闭软件自动更新新的插件

分享一个自己写的简单的自动更新插件 - 梦醒心晴 - 博客园
自动更新插件通常需要三部分
1.配合需要升级的程序的一个dll
2.自动升级程序
3.打包程序
第一部分 配合主程序的dll
在这个升级程序中我将配合主程序用来校验版本号的代码封装在AutoUpdateHelper中,主要包括两个函数,一个是检查版本并自动更新CheckAndUpdate,一个是用来获取当前的版本号GetVersion
第二部分 自动升级程序
升级程序主要的步骤:
1.根据本地的update.xml中的manifest文件的远程地址下载manifest文件
2.根据本地的version和远程manifest中的version校对
3.如果版本不一致,下载manifest中的webpath+版本号.zip文件
4.解压,覆盖原文件
5.根据manifest中配置的exepath,重新启动对应的主程序
第三部分 打包程序
由于自动更新程序和主程序是在同一路径下,因此发布新版本打包的时候需要把自动更新程序相关的exe,dll去掉,防止自动更新程序覆盖原文件的时候,出现文件占用的错误
因此,将项目文件过滤一下,然后执行zip打包。之后将新版本的包提交到服务器上,将服务器的manifest文件,进行相应版本的修改。
项目地址 点击下载
1.首先将AutoUpdate.exe和DotNetZip.dll(用了第三方的解压缩) & 和AutoUpdateHelper.dll(主程序调用的dll)和update.xml(本地记录版本号)
拷贝到主程序的目录下
2.在主程序中加入校验代码
if (AutoUpdateHelper.AutoUpdate.CheckAndUpdate())
Environment.Exit(0);
catch(Exception e)
MessageBoxEx.Show("网络异常~~~赶紧检查一下吧&&");
Environment.Exit(Environment.ExitCode);
3.修改update.xml
&?xml version="1.0" encoding="utf-8" ?&
&localconf&
&version&1.0&/version&
&manifest&http://www.xxx.com/mainfests.xml&/manifest&
&update&AutoUpdate.exe&/update&
&/localconf&
4.将manifests.xml修改 并且放到update.xml中manifest对应的远程地址上
&?xml version="1.0" encoding="utf-8" ?&
&manifest&
&!--版本号,无格式要求,更新时需要修改--&
&version&1.1&/version&
&description&更新说明&/description&
&!--启动程序的名称--&
&exepath&味来外卖客户端.exe&/exepath&
&webpath&http://www.xxx.com/update/&/webpath&
&/manifest&
5.将与manifests.xml中对应版本好的包上传到manifests.webpath配置的远程路径下,例如1.1.zip文件,放到&http://www.xxx.com/update/目录下
大功告成~~~
程序的部分截图
自动更新程序
阅读(...) 评论()
随笔 - 105
Powered by:
Copyright & 梦醒心晴Cordova webapp实战开发:(6)如何写一个iOS下自动更新的插件?
(window.slotbydup=window.slotbydup || []).push({
id: '2611110',
container: s,
size: '240,200',
display: 'inlay-fix'
您当前位置: &
[ 所属分类
| 时间 2015 |
作者 红领巾 ]
APP中【检查更新】显示当前版本号
插件类的编写
在上一篇介绍Andorid插件时我们贴出了很多源码,这里也直接贴出代码,首先是iOS下插件的代码。
我们在Plugins下新建两个文件,一个头文件 CDVGcapp.h,一个实现文件 CDVGcapp.m。(文件名自己取,这是我在项目中的名称)
CDVGcapp.h
#import &Foundation/Foundation.h&#import &Cordova/CDVPlugin.h&@interface CDVGcapp : CDVPlugin- (void)version:(CDVInvokedUrlCommand*)@end
CDVGcapp.m
#import "CDVGcapp.h"#import &Cordova/CDVViewController.h&#import &Cordova/CDVScreenOrientationDelegate.h&@implementation CDVGcapp- (void)version:(CDVInvokedUrlCommand*)command{
NSString* value0 = [NSString stringWithFormat:@"%@(%@)", [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleShortVersionString"] ,[[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleVersionKey]];
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:value0];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];}
如何得到插件调用后的返回结果?主要通过类似 [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; 代码返回
CDVPluginResult,失败和成功都可以触发Javascript执行对应的自定义函数
插件的配置
插件写完了,很多人遇到的下一个问题就是怎么配置才能在Javascript中调用呢?我们今天也不解析源码,为什么呢?因为我没看:)不过,我一定要给大家说清楚如何配置,否则就永远调用不了插件。
打开staging/config.xml文件,添加feature,必须匹配类名,因为源码中是通过这些去配对的。上面我们写了更新插件,现在就是要配置一下这个插件类到功能名称,我在配置文件中加入了下文粗体部分内容
&?xml version='1.0' encoding='utf-8'?&&widget id="com.glodon.gcapp" version="2.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"& &preference name="AllowInlineMediaPlayback" value="false" /& &preference name="AutoHideSplashScreen" value="true" /& &preference name="BackupWebStorage" value="cloud" /& &preference name="DisallowOverscroll" value="false" /& &preference name="EnableViewportScale" value="false" /& &preference name="FadeSplashScreen" value="true" /& &preference name="FadeSplashScreenDuration" value=".25" /& &preference name="KeyboardDisplayRequiresUserAction" value="true" /& &preference name="MediaPlaybackRequiresUserAction" value="false" /& &preference name="ShowSplashScreenSpinner" value="true" /& &preference name="SuppressesIncrementalRendering" value="false" /& &preference name="TopActivityIndicator" value="gray" /& &preference name="GapBetweenPages" value="0" /& &preference name="PageLength" value="0" /& &preference name="PaginationBreakingMode" value="page" /& &preference name="PaginationMode" value="unpaginated" /& &preference name="AutoHideSplashScreen" value="false" /& &name&zgxxj&/name& &description& 随时随地查找全国最完整最及时的信息价
&/description& &author email="" href="http://www.中国信息价.cn"&
周金根 &/author& &content src="html/scj/scj.html" /& &access origin="*" /& &feature name="Device"&
&param name="ios-package" value="CDVDevice" /& &/feature& &feature name="NetworkStatus"&
&param name="ios-package" value="CDVConnection" /& &/feature& &feature name="SplashScreen"&
&param name="ios-package" value="CDVSplashScreen" /&
&param name="onload" value="true" /& &/feature& &feature name="InAppBrowser"&
&param name="ios-package" value="CDVInAppBrowser" /& &/feature&
&feature name="Gcapp"&
&param name="ios-package" value="CDVGcapp" /& &/feature& &feature name="BarcodeScanner"&
&param name="ios-package" value="CDVBarcodeScanner" /& &/feature&&/widget&
代码贴完了,我还是要再多说一下,
CDVGcapp是插件类名
Gcapp是 feature 名称,下面大家就知道在哪里会用到了
以上文件就是告诉cordova,我们新增了一个Gcapp功能,这个功能会调用我们的原生插件Java对象,接下来就是Javascript如何能调用到这个类了,最重要的就是这个Gcapp功能名称。
我们接着就要写Javascript代码来调用这个功能了,如何写呢?继续往下看,我在assets/www/plugins/下新增目录并建立了文件gcapp.js,完整路径是assets/www/plugins/com.gldjc.guangcaiclient/www/gcapp.js,代码如下:
cordova.define('com.gldjc.guangcaiclient.gcapp', function(require, exports, module) { var exec = require("cordova/exec"); function Gcapp() {};
Gcapp.prototype.version = function (getversion) {
exec(getversion, null, 'Gcapp', 'version', []); };
var gcapp = new Gcapp(); module.exports =});
exec是cordova.js中内部的函数,当插件返回PluginResult.Status.OK 时会执行exec的成功回调函数,如果插件返回的是错误,则会执行exec的错误回调函数。这里我们解释一下
exec(getversion, null, 'Gcapp', 'version', []);
其中Gcapp就是我们在上一步骤加的feature名称,大小写匹配着写,通过这个名称,cordova才能找到调用那个java插件类,然后通过version知道调用这个插件类的哪个方法,后面[]中则是参数。因为我这个插件不需要参数,所以为空。
Javascript插件类也配对成功了,那如何调用呢?你可以直接在html中包括这个js,不过我们一般会再配置一个js,那就是assets/www/cordova_plugins.js,这样就不用对每个插件类都去写一遍了,cordova会遍历你的配置去加载它们。
cordova.define('cordova/plugin_list', function(require, exports, module) {module.exports = [ {
"file": "plugins/org.apache.cordova.device/www/device.js",
"id": "org.apache.cordova.device.device",
"clobbers": [
"file": "plugins/org.apache.cordova.networkinformation/www/network.js",
"id": "org.apache.cordova.networkinformation.network",
"clobbers": [
"navigator.connection",
"navigator.network.connection"
"file": "plugins/org.apache.cordova.networkinformation/www/Connection.js",
"id": "org.apache.cordova.networkinformation.Connection",
"clobbers": [
"Connection"
"file": "plugins/org.apache.cordova.splashscreen/www/splashscreen.js",
"id": "org.apache.cordova.splashscreen",
"clobbers": [
"navigator.splashscreen"
"file" : "plugins/org.apache.cordova.camera/www/CameraConstants.js",
"id" : "org.apache.cordova.camera.Camera",
"clobbers" : [ "Camera" ] }, {
"file" : "plugins/org.apache.cordova.camera/www/CameraPopoverOptions.js",
"id" : "org.apache.cordova.camera.CameraPopoverOptions",
"clobbers" : [ "CameraPopoverOptions" ] }, {
"file" : "plugins/org.apache.cordova.camera/www/Camera.js",
"id" : "org.apache.cordova.camera.camera",
"clobbers" : [ "navigator.camera" ] }, {
"file" : "plugins/org.apache.cordova.camera/www/CameraPopoverHandle.js",
"id" : "org.apache.cordova.camera.CameraPopoverHandle",
"clobbers" : [ "CameraPopoverHandle" ] }, {
"file" : "plugins/com.phonegap.plugins.barcodescanner/www/barcodescanner.js",
"id" : "com.phonegap.plugins.barcodescanner.barcodescanner",
"clobbers" : [ "barcodescanner" ] },
"file": "plugins/com.gldjc.guangcaiclient/www/gcapp.js",
"id": "com.gldjc.guangcaiclient.gcapp",
"clobbers": [
] }];module.exports.metadata = // TOP OF METADATA{ "org.apache.cordova.device": "0.2.13"}// BOTTOM OF METADATA});
file表示我们去哪里找脚本插件定义js,id是之前我们在gcapp.js中开头cordova.define中写的标识,cordova通过这个标志去找到我们的Javascript插件定义,而clobbers则是我们在前端通过什么对象名来调用这个插件。这里我写的是gcapp,则后面调用则只需要写成gcapp.checkUpdate 即可
插件的调用
万事俱备,只欠东风,你们可以开始看到结果了,如果从头到这里一步成功,那应该还是蛮兴奋的事情吧。
具体前端页面如何设计我就不说了,我的页面效果就如本文最前面的图片,在js中我是这些调用version的
$(document).on("PG_pageinit", function(event) {
gcapp.version(function(version){$("#version").html(version);
老规矩,点赞或回复超过20人后进行下一篇,超过请在群中 @ 我一下:)
PhoneGap App开发
本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程
转载请注明本文标题:本站链接:
分享请点击:
1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
阅读(3400)
CodeSecTeam微信公众号
你不用很厉害之后才开始,但开始后一定要变得很厉害!
手机客户端如何写一个Andorid下自动更新的插件_百度知道
如何写一个Andorid下自动更新的插件
我有更好的答案
自动更新的话,可以考虑使用由爱加密推出的爱更新服务,只要将更新包提交到爱加密的云更新上,即可以在应用运行中自动完成更新,全程无感知,而且更新过程可控。
采纳率:95%
为您推荐:
其他类似问题
您可能关注的内容
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。在 《》中我们搭建好了开发环境,也给大家布置了调用插件的预习作业,做得如何了呢?今天我们来学一下如何自己从头建立一个Andorid下的cordova插件。本次练习你能学到的学习如何实现Android下自动更新功能学习Android下插件类的编写学习Android下插件的配置学习Android下插件的调用主要内容打开APP后检查版本更新,如果有更新则弹出更新对话框APP中【检查更新】显示当前版本号,并可以点击进行版本检查更新&如何实现自动更新功能你可以自己写代码,也可以网上找代码抄一下,我之前的&&就是从网上下的一个代码片段放进我的项目中的。不过今天和大家说的不是如何编写自动更新代码,因为我们今天要做的是如何更快的用别人写好的东西来加速自己产品开发的进度和质量。自动更新这个东西也不涉及到什么技术难度,一般第三方要是提供了也不会出什么质量问题,能够拿来就用岂不是很好呢?网上找了一下,发现&&&很好,那就直接用这个吧,Andorid和iOS都可以用。如何集成到我们的产品中,看他们自己写的文档:&,我就不多说了,如果遇到问题,可以在咱们群里问问大家。插件类的编写原生Andorid中如果调用,就看上面说的他们自己写的文档。如果我们现在要在APP中【设置】中增加自动检查和显示当前版本,则需要我们开始学习如何编写cordova插件了。这里我们会编写一个插件,两个方法,一个方法用来检测更新,另一个方法用来获得当前APP的版本号。闲话不说了,直接来代码。public class GCAppPlugin extends CordovaPlugin {
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if ("version".equals(action)) {
version(callbackContext);
return true;
else if ("checkUpdate".equals(action)) {
final Context mContext = this.cordova.getActivity();
UmengUpdateAgent.setUpdateAutoPopup(false);
UmengUpdateAgent.setUpdateListener(new UmengUpdateListener() {
public void onUpdateReturned(int updateStatus, UpdateResponse updateInfo) {
switch (updateStatus) {
case UpdateStatus.Yes: // has update
UmengUpdateAgent.showUpdateDialog(mContext, updateInfo);
case UpdateStatus.No: // has no update
Toast.makeText(mContext, "现在使用的已是最新版本了", Toast.LENGTH_SHORT).show();
case UpdateStatus.NoneWifi: // none wifi
Toast.makeText(mContext, "没有wifi连接, 只在wifi下更新", Toast.LENGTH_SHORT).show();
case UpdateStatus.Timeout: // time out
Toast.makeText(mContext, "超时", Toast.LENGTH_SHORT).show();
UmengUpdateAgent.forceUpdate(mContext);
return true;
private synchronized void version(CallbackContext callbackContext) {
  PackageInfo packI
    packInfo = this.cordova.getActivity().getPackageManager().getPackageInfo(this.cordova.getActivity().getPackageName(),0);
    String version = packInfo.versionName +"("+packInfo.versionCode+")";
    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, version));
  } catch (NameNotFoundException e) {
    // TODO Auto-generated catch blocke.printStackTrace();
}Javascript如何得到插件调用后的返回结果?主要通过类似&callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, version)); 代码返回PluginResult,失败和成功都可以触发Javascript执行对应的自定义函数插件的配置插件写完了,很多人遇到的下一个问题就是怎么配置才能在Javascript中调用呢?我们今天也不解析源码,为什么呢?因为我没看:)不过,我一定要给大家说清楚如何配置,否则就永远调用不了插件。打开res/xml/config.xml文件,添加feature,必须匹配类名,因为源码中是通过这些去配对的。上面我们写了更新插件,现在就是要配置一下这个插件类到功能名称,我在配置文件中加入了下文粗体部分内容&?xml version='1.0' encoding='utf-8'?&&widget id="com.glodon.gcapp" version="2.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"&&name&掌中广材&/name&&description& 随时随地查找全国最完整最及时的信息价
&/description&&author email="" href="http://www.中国信息价.cn"&
&/author&&content src="html/scj/scj.html" /&&access origin="*" /&&access origin="tel:*" launch-external="yes"/&&access origin="geo:*" launch-external="yes"/&&access origin="mailto:*" launch-external="yes"/&&access origin="sms:*" launch-external="yes"/&&access origin="market:*" launch-external="yes"/&&preference name="SplashScreen" value="screen" /&&preference name="SplashScreenDelay" value="30000" /&&preference name="SplashMaintainAspectRatio" value="false" /&&preference name="LoadingDialog" value="正在加载中..." /&&feature name="Device"&&param name="android-package" value="org.apache.cordova.device.Device" /&&/feature&&feature name="NetworkStatus"&&param name="android-package" value="org.apache.cordova.networkinformation.NetworkManager" /&&/feature&&feature name="SplashScreen"&&param name="android-package" value="org.apache.cordova.splashscreen.SplashScreen" /&&/feature&&feature name="Camera"&&param name="android-package" value="org.apache.cordova.camera.CameraLauncher" /&&/feature&&feature name="BarcodeScanner"&&param name="android-package" value="com.phonegap.plugins.barcodescanner.BarcodeScanner" /&&/feature&
&feature name="Gcapp"&&param name="android-package" value="com.gldjc.guangcaiclient.GCAppPlugin" /&&/feature& &/widget&代码贴完了,我还是要再多说一下,com.gldjc.guangcaiclient.GCAppPlugin
是插件类的全面Gcapp是 feature 名称,下面大家就知道在哪里会用到了以上文件就是告诉cordova,我们新增了一个Gcapp功能,这个功能会调用我们的原生插件Java对象,接下来就是Javascript如何能调用到这个类了,最重要的就是这个Gcapp功能名称。我们接着就要写Javascript代码来调用这个功能了,如何写呢?继续往下看,我在assets/www/plugins/下新增目录并建立了文件gcapp.js,完整路径是&assets/www/plugins/com.gldjc.guangcaiclient/www/gcapp.js,代码如下:cordova.define('com.gldjc.guangcaiclient.gcapp', function(require, exports, module) {
var exec = require("cordova/exec");
function Gcapp() {};
Gcapp.prototype.version = function (getversion) {
exec(getversion, null, 'Gcapp', 'version', []);
   Gcapp.prototype.checkUpdate = function () {
exec(null, null, 'Gcapp', 'checkUpdate', []);
var gcapp = new Gcapp();
module.exports =
});exec是cordova.js中内部的函数,当插件返回&PluginResult.Status.OK 时会执行exec的成功回调函数,如果插件返回的是错误,则会执行exec的错误回调函数。这里我们解释一下& exec(null, null, 'Gcapp', 'checkUpdate', []);其中Gcapp就是我们在上一步骤加的feature名称,大小写匹配着写,通过这个名称,cordova才能找到调用那个java插件类,然后通过checkUpdate知道调用这个插件类的哪个方法,后面[]中则是参数。因为我这个插件不需要参数,所以为空。Javascript插件类也配对成功了,那如何调用呢?你可以直接在html中包括这个js,不过我们一般会再配置一个js,那就是assets/www/cordova_plugins.js,这样就不用对每个插件类都去写一遍了,cordova会遍历你的配置去加载它们。cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [
"file": "plugins/org.apache.cordova.device/www/device.js",
"id": "org.apache.cordova.device.device",
"clobbers": [
"file": "plugins/org.apache.cordova.networkinformation/www/network.js",
"id": "org.apache.cordova.networkinformation.network",
"clobbers": [
"navigator.connection",
"navigator.network.connection"
"file": "plugins/org.apache.cordova.networkinformation/www/Connection.js",
"id": "org.apache.cordova.networkinformation.Connection",
"clobbers": [
"Connection"
"file": "plugins/org.apache.cordova.splashscreen/www/splashscreen.js",
"id": "org.apache.cordova.splashscreen",
"clobbers": [
"navigator.splashscreen"
"file" : "plugins/org.apache.cordova.camera/www/CameraConstants.js",
"id" : "org.apache.cordova.camera.Camera",
"clobbers" : [ "Camera" ]
"file" : "plugins/org.apache.cordova.camera/www/CameraPopoverOptions.js",
"id" : "org.apache.cordova.camera.CameraPopoverOptions",
"clobbers" : [ "CameraPopoverOptions" ]
"file" : "plugins/org.apache.cordova.camera/www/Camera.js",
"id" : "org.apache.cordova.camera.camera",
"clobbers" : [ "navigator.camera" ]
"file" : "plugins/org.apache.cordova.camera/www/CameraPopoverHandle.js",
"id" : "org.apache.cordova.camera.CameraPopoverHandle",
"clobbers" : [ "CameraPopoverHandle" ]
"file" : "plugins/com.phonegap.plugins.barcodescanner/www/barcodescanner.js",
"id" : "com.phonegap.plugins.barcodescanner.barcodescanner",
"clobbers" : [ "barcodescanner" ]
"file": "plugins/com.gldjc.guangcaiclient/www/gcapp.js",
"id": "com.gldjc.guangcaiclient.gcapp",
"clobbers": [
module.exports.metadata =
// TOP OF METADATA{
"org.apache.cordova.device": "0.2.13"
// BOTTOM OF METADATA
});file表示我们去哪里找脚本插件定义js,id是之前我们在gcapp.js中开头cordova.define中写的标识,cordova通过这个标志去找到我们的Javascript插件定义,而clobbers则是我们在前端通过什么对象名来调用这个插件。这里我写的是gcapp,则后面调用则只需要写成gcapp.checkUpdate 即可插件的调用万事俱备,只欠东风,你们可以开始看到结果了,如果从头到这里一步成功,那应该还是蛮兴奋的事情吧。具体前端页面如何设计我就不说了,我的页面效果就如本文最前面的图片,在js中我是这些调用version的,至于checkUpdate就是一样了,在按钮的click事件中调用&gcapp.checkUpdate(); 即可$(document).on("PG_pageinit", function(event) {
gcapp.version(function(version){
$("#version").html(version);
阅读(...) 评论()利用 DexClassLoader 实现 Android 插件化,从而达到动态加载
点击广告支持我
我维护的 Android 经验分享的公众号
最新 Android 高薪内推
点击下面广告支持我
阿里、滴滴内推,年 40w 以上
那些著名开源库的原理分析
(157,537)(126,485)(110,588)(104,314)(102,079)(97,531)(83,782)(77,682)(76,993)(71,607)
阿里、滴滴内推,年 40w 以上
站内推荐文章

我要回帖

更多关于 关闭软件自动更新 的文章

 

随机推荐