phonegap 自动更新 updateapp android,phonegap 开发的app自动升级

原理相当简单,检查更新的时候,通过指定的URL获取服务器端版本信息。比较版本,如果更新,访问服务器端返回的apk的URL地址,下载,安装。各种 Makert 也是通过类似的机制实现的。原理搞清楚了,代码就相当简单了。

获取apk的VesionName,即AndroidManifest.xml中定义的android:versionName

public String getVesionName(Context context) {

String versionName = null;

try {

versionName = context.getPackageManager().getPackageInfo("net.vpntunnel", 0).versionName;

} catch (NameNotFoundException e) {

Log.e(TAG, e.getMessage());

}

return versionName;

}

更新以及安装程序需要的权限,在AndroidManifest.xml中添加

获取apk的versionCode,即AndroidManifest.xml中定义的android:versionCode

public int getVersionCode(Context context) {

int versionCode = 0;

try {

versionCode = context.getPackageManager().getPackageInfo("net.vpntunnel", 0).versionCode;

} catch (NameNotFoundException e) {

Log.e(TAG, e.getMessage());

}

return versionCode;

}

服务器端version.JSON,包含apk路径以及版本信息

{

"ApkName":"NAME",

"ApkFullName":"NAME_1.0.5.apk",

"VersionName":"1.0.5",

"VersionCode":3

}

获取远程服务器的版本信息

private void getRemoteJSON(string host) throws ClientProtocolException, IOException, JSONException {

String url = String.format("http://%s/%s", host, VER_JSON);

StringBuilder sb = new StringBuilder();

HttpClient client = new DefaultHttpClient();

HttpParams httpParams = client.getParams();

HttpConnectionParams.setConnectionTimeout(httpParams, 3000);

HttpConnectionParams.setSoTimeout(httpParams, 5000);

HttpResponse response = client.execute(new HttpGet(url));

HttpEntity entity = response.getEntity();

if (entity != null) {

BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"), 8192);

String line = null;

while ((line = reader.readLine()) != null) {

sb.append(line + "\n");

}

reader.close();

}

JSONObject object = (JSONObject) new JSONTokener(sb.toString()).nextValue();

this.apkFullName = object.getString("ApkFullName");

this.versionName = object.getString("VersionName");

this.versionCode = Integer.valueOf(object.getInt("VersionCode"));

}

发现更新的提醒窗口,通过AlertDialog实现

private void shoVersionUpdate(String newVersion, final String updateURL) {

String message = String.format("%s: %s, %s", mContext.getString(R.string.found_newversion), newVersion, mContext.getString(R.string.need_update));

AlertDialog dialog = new AlertDialog.Builder(mContext).setTitle(mContext.getString(R.string.alertdialog_title)).setMessage(message)

// update

.setPositiveButton(mContext.getString(R.string.alertdialog_update_button), new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

pBar = new ProgressDialog(mContext);

pBar.setTitle(mContext.getString(R.string.progressdialog_title));

pBar.setMessage(mContext.getString(R.string.progressdialog_message));

pBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);

dialog.dismiss();

downFile(updateURL);

}

// cancel

}).setNegativeButton(mContext.getString(R.string.alertdialog_cancel_button), new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int whichButton) {

dialog.dismiss();

}

}).create();

dialog.show();

}

下载新版的apk文件,存放地址可以放到SD卡中。通过Environment.getExternalStorageDirectory()获取SD卡中的路径

private void downFile(final String url) {

pBar.show();

new Thread() {

public void run() {

HttpClient client = new DefaultHttpClient();

HttpGet get = new HttpGet(url);

HttpResponse response;

try {

response = client.execute(get);

HttpEntity entity = response.getEntity();

long length = entity.getContentLength();

InputStream is = entity.getContent();

FileOutputStream fileOutputStream = null;

if (is != null) {

File f = new File(UPDATE_DIR);

if (!f.exists()) {

f.mkdirs();

}

fileOutputStream = new FileOutputStream(new File(UPDATE_DIR, updateFileName));

byte[] buf = new byte[1024];

int ch = -1;

int count = 0;

while ((ch = is.read(buf)) != -1) {

fileOutputStream.write(buf, 0, ch);

count += ch;

Log.d(TAG, String.valueOf(count));

if (length > 0) {

}

}

}

fileOutputStream.flush();

if (fileOutputStream != null) {

fileOutputStream.close();

}

handler.post(new Runnable() {

public void run() {

pBar.cancel();

installUpdate();

}

});

} catch (Exception e) {

pBar.cancel();

Log.e(TAG, e.getMessage());

}

}

}.start();

}

安装更新

private void installUpdate() {

Intent intent = new Intent(Intent.ACTION_VIEW);

intent.setDataAndType(Uri.fromFile(new File(UPDATE_DIR, updateFileName)), "application/vnd.android.package-archive");

mContext.startActivity(intent);

}

至此更新需要函数就完成了,根据自己的业务逻辑组合一下,更新功能就搞定了。也可以稍微封装下,写成一个通用类,下次就可以直接用了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
框架内部支持中/英文(其他语言只需要在对应的string.xml中取相同的名字即可)内部对话框背景图片、按钮支持自定义了查看版本中的Log只需要过滤AppUpdate开头的Tag重点: 如果没有设置downloadPath则默认为getExternalCacheDir()目录,同时不会申请[存储]权限!目录编译问题效果图功能介绍DownloadManagerUpdateConfiguration使用步骤Demo下载体验版本更新记录结语编译问题因为适配了Android O的通知栏,所以依赖的v7包版本比较高appcompat-v7:26.1.0使用的gradle版本为gradle-4.1-all,所以建议使用Android Studio 3.0及以上的版本打开此项目效果图     功能介绍 支持断点下载 支持后台下载 支持自定义下载过程 支持 设备 >= Android M 动态权限的申请 支持通知栏进度条展示(或者自定义显示进度) 支持Android N 支持Android O 支持中/英文双语 支持自定内置对话框的样式 使用HttpURLConnection下载,未集成其他第三方框架更加详细的文档参阅此处《AppUpdate API文档》DownloadManager:配置文档初始化使用DownloadManager.getInstance(this)属性描述默认值是否必须设置context上下文nulltrueapkUrlapk的下载地址nulltrueapkNameapk下载好的名字nulltruedownloadPathapk下载的位置getExternalCacheDir()falseshowNewerToast是否提示用户 "当前已是最新版本"falsefalsesmallIcon通知栏的图标(资源id)-1trueconfiguration这个库的额外配置nullfalseapkVersionCode更新apk的versionCode (如果设置了那么库中将会进行版本判断下面的属性也就需要设置了)1falseapkVersionName更新apk的versionNamenullfalseapkDescription更新描述nullfalseapkSize新版本的安装包大小(单位M)nullfalseauthorities兼容Android N uri授权应用包名falseUpdateConfiguration:配置文档属性描述默认值notifyId通知栏消息id1011notificationChannel适配Android O的渠道通知详情查阅源码httpManager设置自己的下载过程nullbreakpointDownload是否需要支持断点下载trueenableLog是否需要日志输出trueonDownloadListener下载过程的回调nulljumpInstallPage下载完成是否自动弹出安装页面trueshowNotification是否显示通知栏进度(后台下载提示)trueforcedUpgrade是否强制升级falseonButtonClickListener按钮点击事件回调nulldialogImage对话框背景图片资源(图片规范参考demo)-1dialogButtonColor对话框按钮的颜色-1dialogButtonTextColor对话框按钮的文字颜色-1所有版本:点击查看使用步骤第一步: app/build.gradle进行依赖implementation 'com.azhon:appupdate:1.7.3'第二步:创建DownloadManager,更多用法请查看这里示例代码DownloadManager manager = DownloadManager.getInstance(this); manager.setApkName("appupdate.apk")         .setApkUrl("https://raw.githubusercontent.com/azhon/AppUpdate/master/apk/appupdate.apk")         .setSmallIcon(R.mipmap.ic_launcher)         //可设置,可不设置         .setConfiguration(configuration)         .download();第三步:兼容Android N 及以上版本,在你应用的Manifest.xml添加如下代码<--! android:authorities="${applicationId}"  这个值必须与DownloadManager中的authorities一致(不设置则为应用包名)--> <provider     android:name="android.support.v4.content.FileProvider"     android:authorities="${applicationId}"     android:exported="false"     android:grantUriPermissions="true">     <meta-data         android:name="android.support.FILE_PROVIDER_PATHS"         android:resource="@xml/file_paths_public" /> </provider>第四步:资源文件res/xml/file_paths_public.xml内容<?xml version="1.0" encoding="utf-8"?> <paths>     <external-path         name="app_update_external"         path="/" />     <external-cache-path         name="app_update_cache"         path="/" /> </paths>兼容Android O及以上版本,需要设置NotificationChannel(通知渠道);库中已经写好可以前往查阅NotificationUtil.java温馨提示:升级对话框中的内容是可以上下滑动的哦!如果需要实现自己一套下载过程,只需要继承BaseHttpDownloadManager 并使用listener更新进度public class MyDownload extends BaseHttpDownloadManager {}
非常威猛的官方固件UPDATE.APP解包打包工具(转自XDA论坛) Huawei Update Extractor After messing around a bit with the perl tools available for extracting Huawei update.app files, i got the idea to create an own (windows) tool. Requirements .Net Framework 3.5 Install Extract the content of the zip to a folder somewhere on your system. Execute HuaweiUpdateExtractor.exe I'm planning to create an installer sometime. Usage Press the browse (...) button and select an update.app file. Select a device or unknown and press on the open button. You'll see the content of the update.app file in the listview. Select one or more files and right click. Choose Extract selected from the context menu. Choose the ouput folder and press ok. Or just right click on the list and select Extract all, choose the output folder again and press ok. Press close on the extract window. You can sort the list on sequence, filename and size. Just press on the desired column header. Command line: HuaweiUpdateExtractor extract input output [profile] HuaweiUpdateExtractor repack input output profile Profile The profiles.xml file is used to identify the files in the update.app file. Every file in the update.app has a sequence or type, which is also shown in the list. Those sequences or types are used to identify the file/device partition. Example: system.img recovery.img baseband.img version.txt splash.raw565 boot.img cust.img userdata.img signature crc system.img cache.img cust.img userdata.img modemimage.img boot.img recovery.img signature crc - Root tag of the xml file. - Identifies a device - attribute name: name of the device - attribute author: author of the device - File root tag - Identifies a file - attribute sequence: sequence of the file in update.app - attribute type: type of the file in the update.app - attribute partition: destination partition on the device - attribute signature: used to identify the signature file - attribute checksum: used to identify the checksum file - value: file name You can add or edit devices. If you want them to integrate in newer version, pm 'em to me. I'm gonna make some auto update for the device file somewhere in the future Roadmap - You tell me ... Credits ZeBadger (zebadger@hotmail.com) for figuring out the file headers S34Qu4K3 for the P6 partition layout ngamyarthar for adding ALOT of devices! Changelog

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值