zoukankan      html  css  js  c++  java
  • 自己主动更新--下载apk以及提示对话框的实现(3)

    下载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

  • 相关阅读:
    Docker-CentOS系统安装Docker
    Docker-准备Docker环境
    Docker系列-文章汇总
    商品订单库存一致性问题的思考
    java模板、工厂设计模式在项目中的重构
    2018Java年底总结
    java的AQS中enp没有同步代码块为啥是原子操作
    java使用awt包在生产环境docker部署时出现中文乱码的处理
    初探装饰器模式
    开灯问题
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5268360.html
Copyright © 2011-2022 走看看