Android 一s个相对完整的自动升级功能实现代码
由于项目的需要最近做了一个关于Android自动升级的功能,下面将贴出Android手机客户端的完整代码。这段代码参考别的代码居多,由于不满足需求,所以自己仅仅改了一些需要变动的内容,其他功能都是按照原作者的代码来写的。希望能够给大家提供帮助。
package com.example.myapi;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List; import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast; public class UpdateManager
{
/* 下载中 */
private static final int DOWNLOAD = 1;
/* 下载结束 */
private static final int DOWNLOAD_FINISH = 2;
/* 下载保存路径 */
private String mSavePath;
/* 记录进度条数量 */
private int progress;
/* 是否取消更新 */
private boolean cancelUpdate = false; private Context mContext;
/* 更新进度条 */
private ProgressBar mProgress;
private Dialog mDownloadDialog; private Handler mHandler = new Handler()
{
public void handleMessage(Message msg)
{
switch (msg.what)
{
// 正在下载
case DOWNLOAD:
// 设置进度条位置
mProgress.setProgress(progress);
break;
case DOWNLOAD_FINISH:
// 安装文件
installApk();
break;
case 200://服务端信息
//如果有新版本
checkUpdate();//更新信息
break;
case 101:
Toast.makeText(mContext, "手机中没有内存卡,无法安装!", Toast.LENGTH_LONG).show();
break;
default:
break;
}
};
}; public UpdateManager(Context context)
{
this.mContext = context;
/**
* 此段代码是用于检测版本是否有升级
* 如果有升级则向handler发送200
*/
mHandler.sendEmptyMessage(200);
} /**
* 检测软件更新
*/
public void checkUpdate()
{
showNoticeDialog();
} /**
* 检查软件是否有更新版本
*
* @return
*/
private boolean isUpdate(){ return false;
} /**
* 获取软件版本号
*
* @param context
* @return
*/
private int getVersionCode(Context context)
{
int versionCode = 0;
try
{
// 获取软件版本号,对应AndroidManifest.xml下android:versionCode
versionCode = context.getPackageManager().getPackageInfo("com.szy.update", 0).versionCode;
} catch (NameNotFoundException e)
{
e.printStackTrace();
}
return versionCode;
} /**
* 显示软件更新对话框
*/
private void showNoticeDialog()
{
// 构造对话框
AlertDialog.Builder builder = new Builder(mContext);
builder.setTitle("提示");
builder.setMessage("已检测到软件更新"); // 更新
builder.setPositiveButton("立即更新", new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
// 显示下载对话框
showDownloadDialog();
}
});
// 稍后更新
builder.setNegativeButton("稍后更新", new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
});
Dialog noticeDialog = builder.create();
noticeDialog.setCanceledOnTouchOutside(false);
noticeDialog.show();
} /**
* 显示软件下载对话框
*/
private void showDownloadDialog()
{
// 构造软件下载对话框
AlertDialog.Builder builder = new Builder(mContext);
builder.setTitle("提示");
// 给下载对话框增加进度条
final LayoutInflater inflater = LayoutInflater.from(mContext);
View v = inflater.inflate(R.layout.softupdate_progress, null);
mProgress = (ProgressBar) v.findViewById(R.id.update_progress);
builder.setView(v);
// 取消更新
builder.setNegativeButton("取消", new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
// 设置取消状态
cancelUpdate = true;
}
});
mDownloadDialog = builder.create();
mDownloadDialog.setCanceledOnTouchOutside(false);
mDownloadDialog.show();
// 现在文件
downloadApk();
} /**
* 下载apk文件
*/
private void downloadApk()
{
// 启动新线程下载软件
new downloadApkThread().start();
} /**
* 下载文件线程
*
*
*/
private class downloadApkThread extends Thread
{
@Override
public void run()
{
try
{
// 判断SD卡是否存在,并且是否具有读写权限
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
// 获得存储卡的路径
String sdpath = Environment.getExternalStorageDirectory() + "/";
mSavePath = sdpath + "fortrundownload";
URL url = new URL(/*此处填写下载文件的路径*/"");
// 创建连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
// 获取文件大小
int length = conn.getContentLength();
// 创建输入流
InputStream is = conn.getInputStream(); File file = new File(mSavePath);
// 判断文件目录是否存在
if (!file.exists())
{
file.mkdir();
}
File apkFile = new File(mSavePath, "此处填写文件的名称(apk名称)");
FileOutputStream fos = new FileOutputStream(apkFile);
int count = 0;
// 缓存
byte buf[] = new byte[1024];
// 写入到文件中
do
{
int numread = is.read(buf);
count += numread;
// 计算进度条位置
progress = (int) (((float) count / length) * 100);
// 更新进度
mHandler.sendEmptyMessage(DOWNLOAD);
if (numread <= 0)
{
// 下载完成
mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
break;
}
// 写入文件
fos.write(buf, 0, numread);
} while (!cancelUpdate);// 点击取消就停止下载.
fos.close();
is.close();
}else{//////如果不存在内存卡,则将下载下来的apk文件存入手机内存
mSavePath = "/data/data/com.fortrun.quickrecieve/files";
File file = new File(mSavePath);
Log.e("savepath", mSavePath);
URL url = new URL("apk文件下载路径");
// 创建连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
// 获取文件大小
int length = conn.getContentLength();
Log.e("startlength", length+"");
// 创建输入流
InputStream is = conn.getInputStream(); // 判断文件目录是否存在
if(file.exists()){
file.delete();
}
if (!file.exists())
{
boolean flag = file.mkdir();
Log.e("flag", flag+""); }
/* // 设置权限
String command = "chmod 666" + file.getAbsolutePath();;
Runtime runtime = Runtime.getRuntime();
runtime.exec(command); // ContextWrapper cw = new ContextWrapper(mContext);
// File directory = cw.getDir("media", Context.MODE_PRIVATE);
// File apkFile = cw.getDir(mSavePath+"/"+msg9902.getFileName(), Context.MODE_PRIVATE);
File apkFile = new File(mSavePath,msg9902.getFileName());
String commandFile = "chmod 666" + apkFile.getAbsolutePath();
Log.e("apkfile", apkFile.getAbsolutePath());
Runtime runtimeFile = Runtime.getRuntime();
runtimeFile.exec(commandFile);*/
// FileOutputStream fos = new FileOutputStream(apkFile);
//644标记改程序有读、写、运行权限
/* String command = "chmod 644 " + mSavePath+"/"+msg9902.getFileName();
String command2 = "chmod 777 " + mSavePath;
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec(command2);
runtime.exec(command);
} catch (IOException e) {
e.printStackTrace();
}*/ FileOutputStream fos=(FileOutputStream)mContext.openFileOutput(
"apk文件名称", mContext.MODE_WORLD_READABLE|mContext.MODE_WORLD_WRITEABLE); int count = 0;
// 缓存
byte buf[] = new byte[1024];
// 写入到文件中
do
{
int numread = is.read(buf);
count += numread;
// 计算进度条位置
progress = (int) (((float) count / length) * 100);
// 更新进度
mHandler.sendEmptyMessage(DOWNLOAD);
if (numread <= 0)
{
// 下载完成
mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
break;
}
// 写入文件
fos.write(buf, 0, numread);
} while (!cancelUpdate);// 点击取消就停止下载.
fos.flush();
fos.close();
is.close(); }
} catch (MalformedURLException e)
{
Log.e("downloadApkThread", e.getMessage());
} catch (IOException e)
{
Log.e("downloadApkThread", e.getMessage());
}
// 取消下载对话框显示
mDownloadDialog.dismiss();
}
}; /**
* 安装APK文件
*/
private void installApk()
{
//之前是604,705/*标注拥有最高权限*/
/* String command = "chmod 644 " + mSavePath+"/"+msg9902.getFileName();
String command2 = "chmod 777 " + mSavePath;
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec(command2);
runtime.exec(command);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
File apkfile = new File(mSavePath,"apk文件名称");
if (!apkfile.exists())
{
return;
}
Intent i = new Intent(Intent.ACTION_VIEW);
/**
* i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
*这段代码在Android4.0一下的系统中没必要写,
* 但是如果是在Android4.0以上的系统中进行安装,就必须要写上了。因为如果你不写上就会
* 出现在安装的过程中莫名其妙的关掉,并且不会提示安装完成。
*/
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setDataAndType(Uri.fromFile(apkfile), "application/vnd.android.package-archive");
mContext.startActivity(i);
}
}
大家复制粘贴一下,然后修改下载路径后就能够直接使用了,哈哈。
Android 一s个相对完整的自动升级功能实现代码的更多相关文章
- Android 一个相对完整的自动升级功能实现代码
由于项目的需要最近做了一个关于Android自动升级的功能,下面将贴出Android手机客户端的完整代码.这段代码参考别的代码居多,由于不满足需求,所以自己仅仅改了一些需要变动的内容,其他功能都是按照 ...
- NSIS:应用软件自动升级功能的探索与实践
原文 NSIS:应用软件自动升级功能的探索与实践 记得以前轻狂曾分享过使用第三方软件实现应用软件自动升级功能 (详细http://www.flighty.cn/html/soft/20110106_1 ...
- Delphi程序的自动升级功能的实现(AutoUpdate使用指南)
在UtiMnid组件下,利用auAutoUpgrader实现自动升级(已经测试通过) 第一步:下载AutoUpgrader.Pro.v4.6.4. 第二步:打开AutoUpgrader.Pro.v4. ...
- Android应用自动更新功能的代码实现
由于Android项目开源所致,市面上出现了N多安卓软件市场.为了让我们开发的软件有更多的用户使用,我们需要向N多市场发布,软件升级后,我们也必须到安卓市场上进行更新,给我们增加了工作量.因此我们有必 ...
- Android 应用自动更新功能的代码
由于Android项目开源所致,市面上出现了N多安卓软件市场.为了让我们开发的软件有更多的用户使用,我们需要向N多市场发布,软件升级后,我们也必须到安卓市场上进行更新,给我们增加了工作量.因此我们有必 ...
- Android应用自动更新功能的代码实现(转)
由于Android项目开源所致,市面上出现了N多安卓软件市场.为了让我们开发的软件有更多的用户使用,我们需要向N多市场发布,软件升级后,我们也必须到安卓市场上进行更新,给我们增加了工作量.因此我们有必 ...
- [转]Android应用自动更新功能的代码实现
本文转自:http://www.cnblogs.com/coolszy/archive/2012/04/27/2474279.html 由于Android项目开源所致,市面上出现了N多安卓软件市场.为 ...
- Android中通过ImageSwitcher实现相册滑动查看照片功能(附代码下载)
场景 效果 注: 博客: https://blog.csdn.net/badao_liumang_qizhi关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 将需要滚动查看的照 ...
- ionic2 rc2 添加版本更新自动升级功能
不废话,直接上代码 首先安装四个必备的插件: cordova plugin add cordova-plugin-app-version //获取APP版本 cordova plugin add co ...
随机推荐
- BZOJ5322: [JXOI2018]排序问题
传送门 不难看出期望就是 \(\frac{(n+m)!}{\prod_{v=1}^{max}(cnt_v!)}\),\(cnt_v\) 表示 \(v\) 这个数出现的次数. 贪心就是直接把 \(m\) ...
- ES6中声明变量 let和const特点
在ES6中我们有两种定义变量的方式:let const let特点: 1.let定义时不会进行变量声明提升 2.变量不允许被重复定义 3.变量不可以被删除 4.在for循环当中用let定义i 循 ...
- Flask结合Redis消息队列实现电影弹幕
用到的弹幕播放器插件:dplayer.js(开源) 1.安装Redis 2.安装flask-redis包 pip install flask-redis3.下载dplayer 页面搭建 1.引入资源 ...
- 活字格Web应用平台学习笔记3-显示数据列表
活字格第二课的目标,用活字格创建一个简单的在线数据管理系统. 看下设计界面.刚开始跟着点,有点懵圈,到做完,回忆了一下,其实就是先建一张表,然后,把表和页面联系起来,即在页面中划出一些区域,和表的字段 ...
- android踩坑记录之view.setVisiblity()
问题 在某次做悬浮侧边栏的时候,遇到了一个问题:我用windowManager创建的悬浮侧边栏.点击中心view展开菜单,再次点击则隐藏菜单,如此简单的一个需求,却遇到了奇怪的问题,我没有对view的 ...
- 用VisualAssist在Visual Studio上设置快捷键快速编程
一 在Visual Studio上安装VisualAssist工具: 链接:https://pan.baidu.com/s/1uaeRFTvY4p7LNoDvQFEU5A 提取码:j1ws 安装后, ...
- LeetCode题解之Leaf-Similar Trees
1.题目描述 2.问题分析 将叶子节点的值放入vector,然后比较. 3.代码 bool leafSimilar(TreeNode* root1, TreeNode* root2) { vector ...
- SQLServer导数据到Oracle
从SQLServer导数据到Oracle大概有以下几种方法: 使用SSMS的导出数据向导,使用Microsoft ODBC for Oracle或Oracle Provider for OLE DB连 ...
- excel文件使用navicat工具导入mysql的方法
1.在excel文件的sheet上,第1行下面插入一行,对应DB里面的字段名称,方便后面导入时做字段匹配: 2.使用Navicat ,打开工具,选择表所在的数据库,然后点击数据库名字,右键Tables ...
- 【待补充】[Linux] nc
[nc 是做什么的] [nc怎么用] 查看帮助 nc -help # 查看帮助 nc -help # 监听端口 -l, --listen Bind and listen for incoming co ...