转载文章请注明出处: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. android 访问web端与解析json,模拟用户登录
  3. Android用户体验毁在框架设计?
  4. 2020版本Android 开发者学习路线(热门技术+学习方法+书籍+必须知
  5. 技术转载:Android对话框大合集
  6. Android O/P/Q 版本如何预装 APK
  7. Android 在应用中使用用户凭证(PIN码、密码)
  8. android multi user中MTP 多用户的处理

随机推荐

  1. Android关于后台下载前台通知更新进度条
  2. android Bitmap Drawable bitByte[] 互相
  3. Android View的生命周期
  4. Android Notification.setLatestEventInf
  5. Android中读取properties文件2
  6. Volley String cannot be converted to J
  7. textView 密码问题
  8. android intent使用总结
  9. android中DisplayMetrics类的作用
  10. Java(Android)数据结构汇总(二)-- Set(上)