ios的软件版本更新必须要通过苹果的服务器,而android 却不需要,开发商可以在软件本身嵌套下载安装新版本的功能,对于此是否是个优点暂且不谈(个人感觉还是ios那样更负责人些,用户体验更好点),只将一下实现步骤。
android区分软件是通过包名,也就是所如果两个软件的包名完全相同,系统就会认为是同一款软件,如果已经安装了,又要安装,系统则认为是在更新版本而不是安装新软件。为了避免软件之间的包名产生冲突,android 提倡用自己公司的域名作为包名,因为域名是唯一的,所以就可以很好地区分软件了。但是如果想要安装成功的话除了包名一致外,还要求签名一致。所以在更新apk时新的版本必须要用原先版本的包名和签名打包。
首先要进行网络通信,检测是否有新版本。通信方式可以是socket也可以是http。
- private void isHaveUpdate()
- {
-
- new Thread()
- {
- @Override
- public 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 block
- e.printStackTrace();
- Log.d("!!!!!","no get version");
- }
-
- }
-
- }.start();
-
- }
下面是详细代码:
- private String getVersionName() throws Exception{
- PackageManager packageManager = getPackageManager();
- PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);
- return packInfo.versionName;
- }
handle发送0x1111消息之后会发生的事:
- protected void showUpdataDialog() {
- AlertDialog.Builder builer = new Builder(this) ;
- builer.setTitle("版本升级");
- builer.setMessage("已发布新的版本,是否要下载升级包?");
- //当点确定按钮时从服务器上下载 新的apk 然后安装
- builer.setPositiveButton("下次再说", new DialogInterface.OnClickListener() {
-
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // TODO Auto-generated method stub
-
- }
- });
-
- builer.setNegativeButton("立即更新",new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface arg0, int arg1) {
- // TODO Auto-generated method stub
- downLoadApk();
- }
- });
- AlertDialog dialog = builer.create();
- dialog.show();
- }
- 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 block
- e.printStackTrace();
- handle.sendEmptyMessage(0x3333);
- }
-
-
- }}}.start();
- }
如果下载成功,会自动安装更新版本。也就是调用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);
- }
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if(keyCode == KeyEvent.KEYCODE_BACK&&isDownLoad) //监控/拦截/屏蔽返回键
- {
- showCancelDialog();
- return true;
- }
-
- return super.onKeyDown(keyCode, event);
- }
- private void showCancelDialog()
- {
- AlertDialog.Builder builer = new Builder(this) ;
- builer.setTitle("确认退出");
-
- builer.setMessage("是否要放弃下载?");
- //当点确定按钮时从服务器上下载 新的apk 然后安装
- builer.setPositiveButton("退出", new DialogInterface.OnClickListener() {
-
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // TODO Auto-generated method stub
- isDownLoad = false;
- pd.cancel();
- }
- });
- //当点取消按钮时进行登录
- builer.setNegativeButton("继续",new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface arg0, int arg1) {
- // TODO Auto-generated method stub
-
- }
- });
- AlertDialog dialog = builer.create();
- dialog.show();
- }
- 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();
- }
- }