Android关于apk版本更新方法

ios的软件版本更新必须要通过苹果的服务器,而android 却不需要,开发商可以在软件本身嵌套下载安装新版本的功能,对于此是否是个优点暂且不谈(个人感觉还是ios那样更负责人些,用户体验更好点),只将一下实现步骤。

android区分软件是通过包名,也就是所如果两个软件的包名完全相同,系统就会认为是同一款软件,如果已经安装了,又要安装,系统则认为是在更新版本而不是安装新软件。为了避免软件之间的包名产生冲突,android 提倡用自己公司的域名作为包名,因为域名是唯一的,所以就可以很好地区分软件了。但是如果想要安装成功的话除了包名一致外,还要求签名一致。所以在更新apk时新的版本必须要用原先版本的包名和签名打包。

首先要进行网络通信,检测是否有新版本。通信方式可以是socket也可以是http。

  1. private void isHaveUpdate()
  2.         {
  3.                 
  4.                 new Thread()
  5.                 {
  6.                         @Override
  7.                         public void run(){
  8.                                 URL url;
  9.                                 try {
  10.                                         Log.d("!!!!!","want get version");
  11.                                         url = new URL("http://fd.alga7.com/Version.aspx");
  12.                                         HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
  13.                                         urlConn.setConnectTimeout(5*1000);
  14.                                         InputStreamReader in = new InputStreamReader(urlConn.getInputStream());
  15.                                         BufferedReader buffer = new BufferedReader(in);
  16.                                         String update = buffer.readLine();
  17.                                         Log.d("!!!!!!",getVersionName());
  18.                                         Log.d("!!!!!!",update);
  19.                                         if(!getVersionName().equals(update))
  20.                                         {
  21.                                                 handle.sendEmptyMessage(0x1111);
  22.                                         }
  23.                                         Log.d("!!!!!",update);
  24.                                 } catch (Exception e) {
  25.                                         // TODO Auto-generated catch block
  26.                                         e.printStackTrace();
  27.                                         Log.d("!!!!!","no get version");
  28.                                 }
  29.                                 
  30.                         }
  31.                         
  32.                 }.start();
  33.                 
  34.         }
复制代码
这里用的是http通信,getVersionName()是自己所写的一个方法,用来检测本软件版本,原理是读取androidManifest里的versionName

下面是详细代码:

  1. private String getVersionName() throws Exception{
  2.                 PackageManager packageManager = getPackageManager();
  3.                 PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);
  4.             return packInfo.versionName;
  5.         }
复制代码
读取完成之后,如果检测到版本发生变化之后,开始提示下载apk,也就是

handle发送0x1111消息之后会发生的事:

  1. protected void showUpdataDialog() {  
  2.             AlertDialog.Builder builer = new Builder(this) ;   
  3.             builer.setTitle("版本升级");  
  4.             builer.setMessage("已发布新的版本,是否要下载升级包?");  
  5.             //当点确定按钮时从服务器上下载 新的apk 然后安装   
  6.             builer.setPositiveButton("下次再说", new DialogInterface.OnClickListener() {  


  7.                 @Override
  8.                 public void onClick(DialogInterface dialog, int which) {
  9.                         // TODO Auto-generated method stub
  10.                         
  11.                 }     
  12.             });  
  13.             
  14.             builer.setNegativeButton("立即更新",new DialogInterface.OnClickListener() {  
  15.                         
  16.                         @Override
  17.                         public void onClick(DialogInterface arg0, int arg1) {
  18.                                 // TODO Auto-generated method stub
  19.                                 downLoadApk();
  20.                         }  
  21.             });  
  22.             AlertDialog dialog = builer.create();  
  23.             dialog.show();
  24.         }
复制代码
当用户点击”立即更新“之后,会儿显示进度条对话框,也就是执行downloadApk()方法。需要动态显示下载进度。
  1. protected void downLoadApk() {  
  2.                 
  3.              
  4.             pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);  
  5.             pd.setMessage("正在下载更新");  
  6.             pd.setCanceledOnTouchOutside(false);
  7.             pd.show();  
  8.             isDownLoad = true;
  9.             new Thread(){  
  10.                 @Override  
  11.                 public void run() {  
  12.                         if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){  
  13.                         URL url;
  14.                                         try {
  15.                                                 url = new URL(UrlAdress.ADDRESS_UPDATEAPK);
  16.                                                 Log.d("!!!!!!",UrlAdress.ADDRESS_UPDATEAPK);
  17.                                                 HttpURLConnection conn =  (HttpURLConnection) url.openConnection();  
  18.                                 conn.setConnectTimeout(5000);  
  19.                                 //获取到文件的大小   
  20.                                 pd.setMax(conn.getContentLength());  
  21.                                 InputStream is = conn.getInputStream();  
  22.                                 Log.d("!!!!!!",UrlAdress.ADDRESS_UPDATEAPK);
  23.                                 
  24.                                 File updatefile = new File(Environment.getExternalStorageDirectory()+"/Sexy.apk");
  25.                                 Log.d("!!!!!",updatefile.getPath());
  26.                                 if(updatefile.exists())
  27.                                 {
  28.                                         updatefile.delete();
  29.                                         updatefile.createNewFile();
  30.                                 }
  31.                                 updatefile.createNewFile();
  32.                                 FileOutputStream fos = new FileOutputStream(updatefile);  
  33.                                 BufferedInputStream bis = new BufferedInputStream(is);  
  34.                                 byte[] buffer = new byte[1024];  
  35.                                 int len ;  
  36.                                 total=0;  
  37.                                 while((len =bis.read(buffer))!=-1&&isDownLoad){  
  38.                                     fos.write(buffer, 0, len);  
  39.                                     total+= len;  
  40.                                     Log.d("!!!!!",String.valueOf(total));
  41.                                     //获取当前下载量  
  42.                                     handle.sendEmptyMessage(0x2222);  
  43.                                 }  
  44.                                 fos.close();  
  45.                                 bis.close();  
  46.                                 is.close();  
  47.                                 installApk();
  48.                                         } catch (Exception e) {
  49.                                                 // TODO Auto-generated catch block
  50.                                                 e.printStackTrace();
  51.                                                 handle.sendEmptyMessage(0x3333);
  52.                                         }  
  53.                         
  54.                         
  55.                         }}}.start();  
  56.         }  
复制代码
handle发送0x2222消息也就是在动态显示进度条,而0x3333消息是在异常处理,提示用户网络出错。

如果下载成功,会自动安装更新版本。也就是调用installApk()方法:

  1. protected void installApk() {  
  2.             Intent intent = new Intent();  
  3.             //执行动作  
  4.             intent.setAction(Intent.ACTION_VIEW);  
  5.             //执行的数据类型  
  6.             intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory()+"/Sexy.apk")),
  7.                             "application/vnd.android.package-archive");  
  8.             startActivity(intent);  
  9.         }
复制代码
另外在下载apk的过程中,用户可以退出下载,方式是用户点击了返回按钮,所以要监听返回按钮:
  1. public boolean onKeyDown(int keyCode, KeyEvent event) {
  2.             if(keyCode == KeyEvent.KEYCODE_BACK&&isDownLoad) //监控/拦截/屏蔽返回键
  3.             {
  4.                     showCancelDialog();
  5.                     return true;
  6.             }
  7.               
  8.             return super.onKeyDown(keyCode, event);
  9.         }
复制代码
如果正在下载apk的时候按下了返回键,就会让用户确认退出,即是调用showCancelDialog()方法:
  1. private void showCancelDialog()
  2.         {
  3.                 AlertDialog.Builder builer = new Builder(this) ;   
  4.             builer.setTitle("确认退出");  
  5.            
  6.             builer.setMessage("是否要放弃下载?");  
  7.             //当点确定按钮时从服务器上下载 新的apk 然后安装   
  8.             builer.setPositiveButton("退出", new DialogInterface.OnClickListener() {  


  9.                 @Override
  10.                 public void onClick(DialogInterface dialog, int which) {
  11.                         // TODO Auto-generated method stub
  12.                         isDownLoad = false;
  13.                         pd.cancel();
  14.                 }     
  15.             });  
  16.             //当点取消按钮时进行登录  
  17.             builer.setNegativeButton("继续",new DialogInterface.OnClickListener() {  
  18.                         
  19.                         @Override
  20.                         public void onClick(DialogInterface arg0, int arg1) {
  21.                                 // TODO Auto-generated method stub
  22.                                 
  23.                         }  
  24.             });  
  25.             AlertDialog dialog = builer.create();  
  26.             dialog.show();
  27.         }
复制代码
另外要给出相应的权限。除此dialog.setCanceledOnTouchOutside(false);可以使对话框在用户点击对话框之外是不消失,但是在用户点击按钮的时候还是会立马消失,在某些登陆对话框想要在用户登陆成功后手动调用对话框消失,所以就要用到欺骗android系统使对话框不消失的方法。
  1. static public void dialogClose(boolean isclose)
  2.         {
  3.                  try  
  4.          {  
  5.              java.lang.reflect.Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");  
  6.              field.setAccessible(true);  
  7.               //设置mShowing值,欺骗android系统   
  8.              field.set(dialog, isclose);  //需要关闭的时候 将这个参数设置为true 他就会自动关闭了
  9.          }catch(Exception e) {  
  10.              e.printStackTrace();  
  11.        }  
  12.         }
复制代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值