转载文章请注明出处:http://blog.csdn.net/dangxw_/article/details/17957541

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

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

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

private void isHaveUpdate(){new Thread(){@Overridepublic void run(){URL url;try {Log.d("!!!!!","want get version");url = new URL("http://fd.alga7.com/Version.aspx");HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();urlConn.setConnectTimeout(5*1000);InputStreamReader in = new InputStreamReader(urlConn.getInputStream());BufferedReader buffer = new BufferedReader(in);String update = buffer.readLine();Log.d("!!!!!!",getVersionName());Log.d("!!!!!!",update);if(!getVersionName().equals(update)){handle.sendEmptyMessage(0x1111);}Log.d("!!!!!",update);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();Log.d("!!!!!","no get version");}}}.start();}
这里用的是http通信,getVersionName()是自己所写的一个方法,用来检测本软件版本,原理是读取androidManifest里的versionName

下面是详细代码:

private String getVersionName() throws Exception{PackageManager packageManager = getPackageManager();PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);    return packInfo.versionName;}

读取完成之后,如果检测到版本发生变化之后,开始提示下载apk,也就是

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

protected void showUpdataDialog() {      AlertDialog.Builder builer = new Builder(this) ;       builer.setTitle("版本升级");      builer.setMessage("已发布新的版本,是否要下载升级包?");      //当点确定按钮时从服务器上下载 新的apk 然后安装       builer.setPositiveButton("下次再说", new DialogInterface.OnClickListener() {  @Overridepublic void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stub}         });          builer.setNegativeButton("立即更新",new DialogInterface.OnClickListener() {  @Overridepublic void onClick(DialogInterface arg0, int arg1) {// TODO Auto-generated method stubdownLoadApk();}      });      AlertDialog dialog = builer.create();      dialog.show();} 
当用户点击”立即更新“之后,会儿显示进度条对话框,也就是执行downloadApk()方法。需要动态显示下载进度。

protected void downLoadApk() {           pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);      pd.setMessage("正在下载更新");      pd.setCanceledOnTouchOutside(false);    pd.show();      isDownLoad = true;    new Thread(){          @Override          public void run() {          if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){                  URL url;try {url = new URL(UrlAdress.ADDRESS_UPDATEAPK);Log.d("!!!!!!",UrlAdress.ADDRESS_UPDATEAPK);HttpURLConnection conn =  (HttpURLConnection) url.openConnection();                  conn.setConnectTimeout(5000);                  //获取到文件的大小                   pd.setMax(conn.getContentLength());                  InputStream is = conn.getInputStream();                  Log.d("!!!!!!",UrlAdress.ADDRESS_UPDATEAPK);                                File updatefile = new File(Environment.getExternalStorageDirectory()+"/Sexy.apk");                Log.d("!!!!!",updatefile.getPath());                if(updatefile.exists())                {                updatefile.delete();                updatefile.createNewFile();                }                updatefile.createNewFile();                FileOutputStream fos = new FileOutputStream(updatefile);                  BufferedInputStream bis = new BufferedInputStream(is);                  byte[] buffer = new byte[1024];                  int len ;                  total=0;                  while((len =bis.read(buffer))!=-1&&isDownLoad){                      fos.write(buffer, 0, len);                      total+= len;                      Log.d("!!!!!",String.valueOf(total));                    //获取当前下载量                      handle.sendEmptyMessage(0x2222);                  }                  fos.close();                  bis.close();                  is.close();                  installApk();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();handle.sendEmptyMessage(0x3333);}                                          }}}.start();  }  

handle发送0x2222消息也就是在动态显示进度条,而0x3333消息是在异常处理,提示用户网络出错。

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

protected void installApk() {      Intent intent = new Intent();      //执行动作      intent.setAction(Intent.ACTION_VIEW);      //执行的数据类型      intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory()+"/Sexy.apk")),    "application/vnd.android.package-archive");      startActivity(intent);  }

另外在下载apk的过程中,用户可以退出下载,方式是用户点击了返回按钮,所以要监听返回按钮:

public boolean onKeyDown(int keyCode, KeyEvent event) {    if(keyCode == KeyEvent.KEYCODE_BACK&&isDownLoad) //监控/拦截/屏蔽返回键    {    showCancelDialog();    return true;    }          return super.onKeyDown(keyCode, event);}
如果正在下载apk的时候按下了返回键,就会让用户确认退出,即是调用showCancelDialog()方法:

private void showCancelDialog(){AlertDialog.Builder builer = new Builder(this) ;       builer.setTitle("确认退出");         builer.setMessage("是否要放弃下载?");      //当点确定按钮时从服务器上下载 新的apk 然后安装       builer.setPositiveButton("退出", new DialogInterface.OnClickListener() {  @Overridepublic void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stubisDownLoad = false;pd.cancel();}         });      //当点取消按钮时进行登录      builer.setNegativeButton("继续",new DialogInterface.OnClickListener() {  @Overridepublic void onClick(DialogInterface arg0, int arg1) {// TODO Auto-generated method stub}      });      AlertDialog dialog = builer.create();      dialog.show();}


另外要给出相应的权限。除此dialog.setCanceledOnTouchOutside(false);可以使对话框在用户点击对话框之外是不消失,但是在用户点击按钮的时候还是会立马消失,在某些登陆对话框想要在用户登陆成功后手动调用对话框消失,所以就要用到欺骗android系统使对话框不消失的方法。

static public void dialogClose(boolean isclose){ try           {               java.lang.reflect.Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");               field.setAccessible(true);                //设置mShowing值,欺骗android系统                field.set(dialog, isclose);  //需要关闭的时候 将这个参数设置为true 他就会自动关闭了         }catch(Exception e) {               e.printStackTrace();         }  }



更多相关文章

  1. android“设置”里的版本号
  2. 使用NetBeans搭建Android开发环境
  3. android studio Could not find com.android.support.constraint
  4. Android(安卓)version and Linux Kernel version
  5. opengrok setup on ubuntu for android source code browser
  6. Andorid Dialog 示例【慢慢更新】
  7. android源码下载方式
  8. Android——开发环境
  9. android通过ksoap2对webservice的解析

随机推荐

  1. App ReLoad:用Android(安卓)来控制单反相
  2. android使用.9,png图片作为背景的问题
  3. 【特效】3D旋转环形菜单
  4. Android改变图片颜色的自定义控件(十)
  5. Android界面组件Activity解析
  6. android升级ADT22没有R文件
  7. Android(安卓)主题资源风格定制
  8. Android创建Menu菜单实例
  9. Android使用okHttp(get方式)登录
  10. Android开发相关工具等资源快速查找地址