下载apk以及提示对话框的实现

一、步骤:

1. 确定有能够更新的版本号,对话框提醒用户是否进行更新。

2. 选择更新的话,显示下载对话框而且进行下载。否则关闭提示更新对话框。

3. Apk下载完毕后。安装apk。

二、详细细节:

1. 提示用户更新的时候,实现必须更新的方法例如以下:显示的对话框仅仅显示更新button。也就是仅仅能选择更新。

2. 下载的时候,下载对话框的页面显示一个进度条来显示下载进度。

3. 下载的时候,启动一个子线程来进行下载。

4. 下载的时候须要来源路径和下载后保存的路径。

5. 下载对话框有取消下载button,当点击取消下载的时候,直接结束下载线程中读取数据的内容就可以。

6. 下载对话框的进度条是实时更新的,所以须要主线程和子线程之间进行通信,通信使用Handler类来实现。

7. 通信的时候当发送来下载结束的信号的时候,进行安装apk操作。

8. 安装操作使用intent实现。

三、代码例如以下:

1. 主要代码

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 net.aufo.apps.certclient.R;
import android.app.Activity;
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.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar; public class UpdateManager
{
/* 下载中 */
private static final int DOWNLOAD = 1;
/* 下载结束 */
private static final int DOWNLOAD_FINISH = 2; private String downloadUrl; /* 下载保存路径 */
private String localSavePath; /* 记录进度条数量 */
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;
default:
break;
}
};
}; public UpdateManager(Context context)
{
this.mContext = context;
} /**
* 显示软件更新对话框
*/
public void showNoticeDialog(boolean forceUpdate, String updatedDetail, String downloadUrl, String localSavePath)
{
this.downloadUrl = downloadUrl;
this.localSavePath = localSavePath; // 构造对话框
AlertDialog.Builder builder = new Builder(mContext);
builder.setTitle("软件更新");
builder.setMessage(updatedDetail); // 更新
builder.setPositiveButton("更新", new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
// 显示下载对话框
showDownloadDialog();
}
}); if(forceUpdate == false){
// 稍后更新
builder.setNegativeButton("稍后更新", new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss(); /*dialog.dismiss();
((Activity)mContext).finish();
System.exit(0); */
}
});
} Dialog noticeDialog = builder.create();
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.progress, null);
mProgress = (ProgressBar) v.findViewById(R.id.progress);
builder.setView(v);
// 取消更新
builder.setNegativeButton("取消", new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
// 设置取消状态
cancelUpdate = true;
}
});
mDownloadDialog = builder.create();
mDownloadDialog.show(); // 启动新线程下载软件
new downloadApkThread().start();
} /**
* 下载文件线程
*/
private class downloadApkThread extends Thread
{
@Override
public void run()
{
try
{
// 推断SD卡是否存在。而且是否具有读写权限
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
URL url = new URL(downloadUrl);
// 创建连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
// 获取文件大小
int length = conn.getContentLength();
// 创建输入流
InputStream is = conn.getInputStream(); File file = new File(localSavePath);
// 推断文件文件夹是否存在
if (!file.exists())
{
file.mkdirs();
}
File apkFile = new File(localSavePath, "update.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();
}
} catch (MalformedURLException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
// 取消下载对话框显示
mDownloadDialog.dismiss();
}
}; /**
* 安装APK文件
*/
private void installApk()
{
File apkfile = new File(localSavePath, "update.apk");
if (!apkfile.exists())
{
return;
}
// 通过Intent安装APK文件
Intent i = new Intent(Intent.ACTION_VIEW);
i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
mContext.startActivity(i);
}
}

2. 下载对话框界面代码progress.xml

<?xml version="1.0" encoding="utf-8"?

>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" > <ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content" /> </LinearLayout>

3. 调用代码

UpdateManager update = new UpdateManager(this);
update.showNoticeDialog(false, "检測到新版本号,马上更新吗?", "http://saifusuozheng.dbankcloud.com/AppGenXin/CertClient.apk",getFilesDir().getPath());

四、參考站点:

1. 更新步骤

http://www.iteye.com/problems/55470

2. xml解析和生成

http://developer.51cto.com/art/200903/117512.htm

3. 从网络上获取文件http://blog.csdn.net/blueman2012/article/details/6450895

4. Android自己主动更新程序

4.1 http://www.cnblogs.com/wainiwann/archive/2012/03/12/2391810.html

4.2  http://www.cnblogs.com/coolszy/archive/2012/04/27/2474279.html

自己主动更新--下载apk以及提示对话框的实现(3)的更多相关文章

  1. 微信扫码下载APK遮罩提示示例

    由于微信的限制,应用文件在内置浏览器中下载全部被屏蔽掉,造成很多人用微信扫描二维码下载时,界面显示一片空白,容易误导以为在下载呢.按照当前主流习惯,做一个提示用户在浏览器中打开下载的遮罩.网上很多现成 ...

  2. Android 自己实现更新下载自动安装

    1.一些公司开发完一款App之后可能并不会去上架App商店,但事后期也需要定时进行维护更新,所以会选择把打包好的apk 发布到自己的服务器,然后在数据库建一个版本号的表,然后剩下的就交给你androi ...

  3. 【转】tomcat搭建本地服务器 实现apk更新下载

    转自:http://www.kankanews.com/ICkengine/archives/121748.shtml 做apk的更新下载功能,测试的时候需要个服务器. 所以就选用 Apache To ...

  4. quick cocos2dx lua 网络图片 下载 自己主动更新

    转载请注明,原文地址:http://blog.csdn.net/dd135373/article/details/46468505 quick coocs2d-x 网络图片下载,自己主动更新纹理,保存 ...

  5. 【Android】Android程序自己主动更新

    App自己主动更新的步骤可分为三步: 检查更新(假设有更新进行第2步,否则返回) 下载新版的APK安装包 安装APK 以下对这三步进行解释.当中会穿插相应代码.App自己主动更新的这三步所有被封装到了 ...

  6. Android项目实战(三十一):异步下载apk文件并安装(非静默安装)

    前言: 实现异步下载apk文件 并 安装.(进度条对话框显示下载进度的展现方式) 涉及技术点: 1.ProgressDialog   进度条对话框  用于显示下载进度 2.AsyncTask     ...

  7. [Phonegap+Sencha Touch] 移动开发77 Cordova Hot Code Push插件实现自己主动更新App的Web内容

    原文地址:http://blog.csdn.net/lovelyelfpop/article/details/50848524 插件地址:https://github.com/nordnet/cord ...

  8. ionic 通过下载apk升级App

    上篇通过更新文件升级APP,如果遇到了比如更新插件之类的问题,上篇是无法解决的,所以为了解决这个问题,需要下载apk文件升级APP.   1.配置文件如下:{'appVersion':'1.0.0', ...

  9. 更新下载库update绝对详解

    下载更新apk,基本上每个app都需要的功能,来看看吧,肯定有你想要的,以前都是自己写,近期想借助第三方的一个库来做,功能齐全,感觉不错,记录使用过程,虽然官方也有使用教程,不过毕竟粗略,网上也能搜到 ...

随机推荐

  1. 【N年前的文章脑补:HttpHandler HttpModule入门篇】

    HttpHandler HttpModule入门篇 ASP.Net处理Http Request时,使用Pipeline(管道)方式,由各个HttpModule对请求进行处理,然后到达 HttpHand ...

  2. Inno Setup 打包工具总结(转)

    最近打包用到了Inno setup,在这个过程中容易犯一些低级错误,特别写出来已提醒自己 1.打包文件夹 打包文件按照向导来一般没什么问题,但文件夹就不一样了.向导生成的打包文件夹的代码如下: Sou ...

  3. EasyUI Combotree 只允许选择 叶子节点

    $("#SDID").combotree({ url: '/Ajax/GetDeptTree.aspx?level=4&pid=-1', onSelect: functio ...

  4. linux分区,文件系统,目录结构概述

    1.Linux中如何表示硬盘,分区 Linux内核读取光驱,硬盘等资源时均通过“设备文件”的形式进行,因此在linux系统中,将硬 盘和分区表示为不同的文件.具体表述形式如下: 硬盘:对于IDE接口的 ...

  5. C app

    1,C 输入输出字符串

  6. system函数遇到的问题 - 程序死掉

    system函数遇到的问题 解决方案见最下边 http://blog.csdn.net/yangzhenzhen/article/details/51505176 这几天调程序(嵌入式linux),发 ...

  7. 【设计模式】学习笔记13:组合模式(Composite)

    本文出自   http://blog.csdn.net/shuangde800 认识组合模式 上一篇中,我们可以用迭代器来实现遍历一个集合(数组,ArrayList, Vector, HashTabl ...

  8. mongodb 学习笔记 04 -- 游标、索引

    游标 var cursor = db.collectionName.find() 创建游标 cursor.hasNext() 是否有下一个元素 cursor.next() 取出下一个元素 比如 whi ...

  9. oracle子查询

    子查询:在一个查询的内部包含另外一个查询. 普通子查询 -- 查询出比7654工资还高的所有雇员的信息 select * from emp e where e.sal > (select sal ...

  10. Oracle游标cursor1基础和隐式游标

    --指向表行的指针,一次一行,一般向前移动 Resultset --游标永远代代表的是一行数据. /* 使用步骤 第一步:声明游标,就像是声明一个变量样. 游标的关键字就是cursor. Declar ...