Android 一个相对完整的自动升级功能实现代码
由于项目的需要最近做了一个关于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 一个相对完整的自动升级功能实现代码的更多相关文章
- Android 一s个相对完整的自动升级功能实现代码
由于项目的需要最近做了一个关于Android自动升级的功能,下面将贴出Android手机客户端的完整代码.这段代码参考别的代码居多,由于不满足需求,所以自己仅仅改了一些需要变动的内容,其他功能都是按照 ...
- NSIS:应用软件自动升级功能的探索与实践
原文 NSIS:应用软件自动升级功能的探索与实践 记得以前轻狂曾分享过使用第三方软件实现应用软件自动升级功能 (详细http://www.flighty.cn/html/soft/20110106_1 ...
- 分享一个客户端程序(winform)自动升级程序,思路+说明+源码
做winform的程序,不管用没用过自动更新,至少都想过自动更新是怎么实现的. 我这里共享一个自动更新的一套版本,给还没下手开始写的人一些帮助,也希望有大神来到,给指点优化意见. 本初我是通过sock ...
- Java 从零开始实现一个画图板、以及图像处理功能,代码可复现
Java 从零开始实现一个画图板.以及图像处理功能,代码可复现 这是一个学习分享博客,带你从零开始实现一个画图板.图像处理的小项目,为了降低阅读难度,本博客将画图板的一步步迭代优化过程展示给读者,篇幅 ...
- 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多安卓软件市场.为 ...
随机推荐
- IO流作业
IO流作业 一. 填空题 Java IO流可以分为 字节流 和处理流两大类,其中前者处于IO操作的第一线,所有操作必须通过他们进行. 输入流的唯一目的是提供通往数据的通道 ...
- Linux 操作方法(一)
cd +地址 ->可进入地址 cd .. ->返回上级 ll ->显示当前目录下的所有文件(显示所有文件,包括隐藏,还有显示文件信息) ls ->显示当前目录下的所有文件 su ...
- atitit.网络文件访问协议.unc smb nfs ftp http的区别
atitit.网络文件访问协议.unc smb nfs ftp http的区别 1. 网络文件访问协议1 2. NETBios协议 2 3. SMB(Server Message Block)2 3 ...
- 解决webview调用 goBack() 返回上一页自动刷新闪白的情况
问题是:重写了onKeyDown()方法使其goBack(),但是遇到的问题是,每次进入webview再次返回原始页面的时候,中间会有一个闪白的出现. 试了好多网上的方法,发现都是扯淡. 后来意识到, ...
- 如何将同一云服务下的虚拟机从经典部署模型迁移到 Azure Resource Manager
适用场景 用户希望将特定云服务下的所有虚拟机从经典部署模型(以下简称:ASM)迁移到 Azure Resource Manager(以下简称:ARM). Note 如果云服务下使用 VNET 也希望将 ...
- poj_3253 Fence Repair
Fence Repair Description Farmer John wants to repair a small length of the fence around the pasture. ...
- SQL Server 合并复制的Article可以指定单个对象的更新方向
如下所示,这是SQL Server中一个合并复制发布端的Article: 我们可以在Article中选择一个对象,比如这里我们选择MD.Car表,点击鼠标右键,选择"Set Properti ...
- 分享一个基于小米 soar 的开源 sql 分析与优化的 WEB 图形化工具
soar-web 基于小米 soar 的开源 sql 分析与优化的 WEB 图形化工具,支持 soar 配置的添加.修改.复制,多配置切换,配置的导出.导入与导入功能. 环境需求 python3.xF ...
- python基础学习9----深浅拷贝
数据类型有可变类型和不可变类型 不可变类型:整型,长整型,浮点数,复数,布尔,字符串,元组 可变类型:列表,字典 浅拷贝 简单说只对第一层进行拷贝,如下对于列表中的列表的数据进行改变,list1和li ...
- Linux 配置 hosts
1. hosts 是什么 维基百科对 hosts 的介绍如下: hosts文件(域名解析文件)是一个用于储存计算机网络中各节点信息的计算机文件. 这个文件负责将主机名称映射到相应的IP地址. host ...