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 ...
随机推荐
- Codeforces787D(SummerTrainingDay06-D 线段树+最短路)
D. Legacy time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- 《JavaScript DOM 编程艺术》读书笔记
<JS DOM 编程艺术>笔记 一. 三种节点 元素节点.文本节点.属性节点 二. 获取元素 1.document.getElementById 2.(element)document.g ...
- MySQL的事务的处理
步骤: 1.开启事务 start transaction 当我们开启一个事务的时候,我们对sql的操作都发生在内存中,但是没有真正的反馈到数据库磁盘的文件中! 2.回滚 rollback 回滚,就是恢 ...
- WebSerivce与WebAPI的区别
一.什么是Web Service Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的.专门的第三方软件或硬件, 就可相互交换数据或集成.依据Web Service规范实施的应 ...
- JavaScript小细节点罗列(2)
break 语句和 continue 语句 break语句和continue语句都具有跳转作用,可以让代码不按既有的顺序执行. break语句用于跳出代码块或循环. var i = 0; while( ...
- [基础架构]PeopleSoft Tuxedo 重要文件说明
我们都知道PeopleSoft是由几个不同的服务组成的,他们在PeopleSoft体系结构中扮演着自己的角色.这些服务具有不同的文件结构并包含重要的可执行文件和配置文件. 以下是Peoplesoft体 ...
- 企业BI系统应用的切入点及五大策略
从技术的角度来看,BI的技术正在走向成熟,处于一个发展的阶段,但它促使了BI的应用在成本方面开始逐步的降低,越来越多的企业在BI应用方面取得了成功.从实施的角度来出发,实施商业智能系统是一项复杂的系统 ...
- Linux nohup命令应用简介--让Linux的进程不受终端影响
nohup命令应用简介--让Linux的进程不受终端影响 by:授客 QQ:1033553122 #开启ping进程 [root@localhost ~]# ping localhost & ...
- RecyclerView--添加头部和底部
1.先构建WrapRecyclerAdapter /** * Description: 可以添加头部和底部的Adapter */ public class WrapRecyclerAdapter ex ...
- 第 13 章 文件输入/输出 (标准I/O)
/*-------------------------- count.c -- 使用标准 I/O --------------------------*/ #include <stdio.h&g ...