安卓 软件更新程序

首先,在manifest.xml配置文件中,会有当前安卓软件的版本号。

1 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2     package="com.cn.gordon.exhibition.walk.activity"
3     android:versionCode="1"
4     android:versionName="1.0.1" >

简单的思路就是把自己的版本号通过参数,传递给后台,由后台来判断是否要检测更新。(这里是把后台中最新的版本获取到,和本地的做对比。)

通过方法来获取本地的版本号:

 1 public static String getVersionName(Context context) {
 2         String verName = "";
 3         try {
 4             verName = context.getPackageManager().getPackageInfo(PACKAGE_NAME,
 5                     0).versionName;
 6         } catch (NameNotFoundException e) {
 7             e.printStackTrace();
 8         }
 9         return verName;
10     }

获取网络的版本号:

 1 protected void getVersionFromNet(final View view) {
 2         Map<String, String> postvalues = new HashMap<String, String>();
 3         postvalues.put("", "");
 4         
 5         new NetUtils(new NetCallBack(){
 6             @Override
 7             public void getNet(NetCallBack_State arg0, String arg1) {
 8                 switch (arg0) {
 9                 case error:
10                     Toast.makeText(getActivity(), "网络资源错误", Toast.LENGTH_SHORT).show();
11                     break;
12                 case noNet:
13                     Toast.makeText(getActivity(), "网络未开启", Toast.LENGTH_SHORT).show();
14                     break;
15                 case wrong:
16                     Toast.makeText(getActivity(), "网络数据错误"+arg1, Toast.LENGTH_SHORT).show();
17                     break;
18                 case ok:
19                     processUpdate(view,arg1);
20                     break;
21                 default:
22                     break;
23                 }
24             }
25         }).read(getActivity(), false, Utils.GETAPKVERSIONCODE_URL, null, null, false, postvalues, "GBK", true, true);
26         
27     }

返回的json在arg1中,解析json:

 1 protected void processUpdate(View view ,String arg1) {
 2         try {
 3             JSONObject jo = new JSONObject(arg1);
 4             if (jo.optString("version").equals(Utils.getVersionName(getActivity()))) {
 5                 Toast.makeText(getActivity(), "当前软件已经是最新版本~", Toast.LENGTH_SHORT).show();
 6             }else {
 7                 String apkUrl = Utils.PICIP + "/iot-hmi-web/iot/" + jo.optString("url").replace("\", "/");
 8                 System.out.println("apkUrl = "+apkUrl);
 9                 String apkName = jo.optString("name");
10                 String versionName = jo.optString("version");
11                 
12                 global.setApkName(apkName);
13                 global.setApkUrl(apkUrl);
14                 PromptDialogPopupWindow pDialog = new PromptDialogPopupWindow(getActivity(), 4, "LoginActivity", 检测到新版本,
最新版本:V"+versionName+"
当前版本:V"+Utils.getVersionName(getActivity())+"
是否现在更新?");
15                 pDialog.showPopupWindow(view);
16             }
17         } catch (JSONException e) {
18             e.printStackTrace();
19             return;
20         }
21         
22         
23     }

解析完成后,弹出一个popupwindow来提示用户是否真的要更新?

  1 package com.cn.gordon.exhibition.walk.popup;
  2 
  3 import com.cn.gordon.exhibition.walk.activity.CreateBusinesscardActivity;
  4 import com.cn.gordon.exhibition.walk.activity.DownApkActivity;
  5 import com.cn.gordon.exhibition.walk.activity.LoginActivity;
  6 import com.cn.gordon.exhibition.walk.activity.R;
  7 import com.cn.gordon.exhibition.walk.application.GlobalVaries;
  8 import android.annotation.TargetApi;
  9 import android.app.Activity;
 10 import android.bluetooth.BluetoothAdapter;
 11 import android.bluetooth.BluetoothManager;
 12 import android.content.Context;
 13 import android.content.Intent;
 14 import android.graphics.drawable.BitmapDrawable;
 15 import android.os.Bundle;
 16 import android.view.Gravity;
 17 import android.view.LayoutInflater;
 18 import android.view.View;
 19 import android.view.View.OnClickListener;
 20 import android.widget.Button;
 21 import android.widget.PopupWindow;
 22 import android.widget.RelativeLayout.LayoutParams;
 23 import android.widget.TextView;
 24 
 25 public class PromptDialogPopupWindow {
 26     private Activity context;
 27     private Button btnOK,btnCancel;
 28     private TextView txtContent;
 29     private PopupWindow popWindow ;
 30     private GlobalVaries global;
 31     private String promptContent,activityName;
 32     private int goingFlag;//1:登录2:完善信息
 33     private int okCancel = 0;//init-->0,ok-->1,cancel-->2
 34     
 35     
 36     
 37     public PromptDialogPopupWindow(Activity context,int goingFlag,String activityName,String promptContent){
 38         this.context = context;
 39         this.promptContent = promptContent;
 40         this.activityName = activityName;
 41         this.goingFlag = goingFlag;
 42         init();
 43     }
 44         @SuppressWarnings("deprecation")
 45         private void init() {
 46             
 47             global = (GlobalVaries) context.getApplication();
 48             
 49             LayoutInflater inflater = LayoutInflater.from(context); 
 50              // 引入窗口配置文件 
 51             View viewPop = inflater.inflate(R.layout.popup_promptdialog, null); 
 52             txtContent = (TextView)viewPop.findViewById(R.id.promptcontent);
 53             btnOK = (Button)viewPop.findViewById(R.id.btn_ok);
 54             btnCancel = (Button)viewPop.findViewById(R.id.btn_cancel);
 55             // 创建PopupWindow对象 
 56             popWindow = new PopupWindow(viewPop, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, false); 
 57             // 需要设置一下此参数,点击外边可消失 
 58             popWindow.setBackgroundDrawable(new BitmapDrawable()); 
 59             //设置点击窗口外边窗口消失 
 60             popWindow.setOutsideTouchable(false); 
 61             // 设置此参数获得焦点,否则无法点击 
 62             popWindow.setFocusable(false); 
 63             
 64             txtContent.setText(promptContent);
 65             popWindow.update();
 66             
 67             btnOK.setOnClickListener(new OnClickListener() {
 68                 
 69                 @TargetApi(18)
 70                 @Override
 71                 public void onClick(View v) {
 72                     if (goingFlag==1) {//用户还没有登录
 73                         Intent in = new Intent(context,LoginActivity.class);
 74                         Bundle bundle = new Bundle();
 75                         bundle.putString("from", activityName);
 76                         in.putExtras(bundle);
 77                         context.startActivity(in);
 78                     }
 79                                                             if (goingFlag==4) {
 80                         //更新软件
 81                         String apkName = global.getApkName();
 82                         String apkUrl = global.getApkUrl();
 83                         Intent in = new Intent(context, DownApkActivity.class);
 84                         Bundle bundle = new Bundle();
 85                         bundle.putString("apkName", apkName);
 86                         bundle.putString("apkUrl", apkUrl);
 87                         in.putExtras(bundle);
 88                         context.startActivity(in);
 89                     }
 90                     okCancel = 1;
 91                     popWindow.dismiss(); 
 92                 }
 93             });
 94             
 95             btnCancel.setOnClickListener(new OnClickListener() {
 96                 @Override
 97                 public void onClick(View v) {
 98                     okCancel = 2;
 99                     popWindow.dismiss(); 
100                 }
101             });
102             
103             
104             
105     }
106         
107     public int getClickState(){
108         return okCancel;
109     }
110         
111     public boolean isShowing(){
112         if (!popWindow.isShowing()) {
113             return false;
114         }else {
115             return true;
116         }
117     }
118     
119     public int showPopupWindow(View parent) {  
120         if (!popWindow.isShowing()) {  
121             // 以下拉方式显示popupwindow  //Gravity.CENTER_HORIZONTAL|Gravity.CENTER_VERTICAL
122             popWindow.showAtLocation(parent,Gravity.CENTER,0, 0);  
123         } else {  
124             popWindow.dismiss();  
125         }  
126         return okCancel ;
127     }  
128 }

点击提示框中的确定之后,页面跳转到下载的Activity页面:

  1 package com.cn.gordon.exhibition.walk.activity;
  2 
  3 import java.io.File;
  4 import java.io.FileOutputStream;
  5 import java.io.InputStream;
  6 import java.io.OutputStream;
  7 import java.net.URL;
  8 import java.net.URLConnection;
  9 
 10 import com.cn.gordon.exhibition.walk.utils.Utils;
 11 
 12 import android.annotation.SuppressLint;
 13 import android.app.Activity;
 14 import android.content.Intent;
 15 import android.graphics.Color;
 16 import android.net.Uri;
 17 import android.os.Bundle;
 18 import android.os.Handler;
 19 import android.os.Message;
 20 import android.view.View;
 21 import android.view.View.OnClickListener;
 22 import android.widget.Button;
 23 import android.widget.ProgressBar;
 24 import android.widget.TextView;
 25 import android.widget.Toast;
 26 
 27 public class DownApkActivity extends Activity {
 28 
 29     private Button btnOK,btnCancel;
 30     private TextView tvComplete;
 31     private static final String APK_PATH = Utils.getSDPath()+ java.io.File.separator +  "exhibition_walk"; // 存放各个下载器 27
 32 
 33     private Handler mHandler;
 34     private ProgressBar bar;
 35     private Bundle bundle;
 36     private String apkName,apkUrl;
 37     @Override
 38     protected void onCreate(Bundle savedInstanceState) {
 39         super.onCreate(savedInstanceState);
 40         setContentView(R.layout.downloadapk);
 41         bundle = getIntent().getExtras();
 42         if (bundle!=null) {
 43             apkName = bundle.getString("apkName");
 44             apkUrl = bundle.getString("apkUrl");
 45         }
 46         init();
 47         setAction();
 48         if (apkName!=null&&apkUrl!=null&&!"".equals(apkName)&&!"".equals(apkUrl)) {
 49             downloadFile(apkUrl,apkName);
 50         }
 51     }
 52     @SuppressLint("HandlerLeak")
 53     private void init() {
 54         btnOK = (Button) findViewById(R.id.oksure);
 55         btnCancel = (Button) findViewById(R.id.nocancel);
 56         btnOK.setVisibility(View.INVISIBLE);
 57         btnCancel.setVisibility(View.INVISIBLE);
 58         tvComplete = (TextView) findViewById(R.id.tv_complete);
 59         bar = (ProgressBar) findViewById(R.id.progress_horizontal);
 60         mHandler = new Handler() {
 61             public void handleMessage(Message msg) {
 62                 if (msg.what == 1) {
 63 //                    String url = (String) msg.obj;
 64                     int length = msg.arg1;
 65                     int totalSize = msg.arg2;
 66                     int percent = 0;
 67                     if (totalSize!=0) {
 68                         percent = (100*length)/totalSize;
 69                     }
 70                     tvComplete.setText("下载进度:"+percent+"%");
 71                     if (bar != null) {// 设置进度条按读取的length长度更新  
 72                         bar.setProgress(length);
 73                         bar.setMax(totalSize);
 74                         if (length >= totalSize) {
 75                             Toast.makeText(DownApkActivity.this, "下载完成!", Toast.LENGTH_SHORT).show(); 
 76                              // 下载完成后清除进度条并将map中的数据清空 45                         
 77 //                            LinearLayout layout = (LinearLayout) bar.getParent();//FIXME
 78 //                            layout.removeView(bar);
 79 //                            ProgressBars.remove(url);
 80 //                            downloaders.get(url).delete(url);
 81 //                            downloaders.get(url).reset();
 82 //                            downloaders.remove(url);
 83                             installApk(APK_PATH,apkName);
 84                         }
 85                      } 
 86                 }
 87         } 
 88     };
 89     }
 90     private void setAction() {
 91         btnOK.setOnClickListener(new OnClickListener() {
 92             @Override
 93             public void onClick(View v) {
 94                 // TODO Auto-generated method stub
 95                 
 96             }
 97         });
 98         btnCancel.setOnClickListener(new OnClickListener() {
 99             @Override
100             public void onClick(View v) {
101                 // TODO Auto-generated method stub
102                 
103             }
104         });
105         
106     }
107     
108     private void downloadFile(final String fileUrl,final String fileName){
109         //准备拼接新的文件名(保存在存储卡后的文件名)
110 //        String newFilename = _urlStr.substring(_urlStr.lastIndexOf("/")+1);
111 //        newFilename = _dirName + newFilename;
112         new Thread(new Runnable() {
113             
114             @Override
115             public void run() {
116                 File file = new File(fileName);
117                 //如果目标文件已经存在,则删除。产生覆盖旧文件的效果
118                 if(file.exists())
119                 {
120                     file.delete();
121                 }
122                 try {
123                          // 构造URL   
124                          URL url = new URL(fileUrl);
125                          // 打开连接   
126                          URLConnection con = url.openConnection();
127                          //获得文件的长度
128                          int contentLength = con.getContentLength();
129                          System.out.println("长度 :"+contentLength);
130                          // 输入流   
131                          InputStream is = con.getInputStream();
132                          // 64K的数据缓冲   
133                          byte[] bs = new byte[1024*8];
134                          // 读取到的数据长度   
135                          int len;
136                          //downloadSize
137                          int downloadSize = 0;
138                         
139 //                         Bundle bund = new Bundle();
140                          // 输出的文件流   
141                          OutputStream os = new FileOutputStream(APK_PATH+java.io.File.separator+fileName);
142                          // 开始读取   
143                          while ((len = is.read(bs)) != -1) {   
144                              downloadSize+=len;
145                              os.write(bs, 0, len);
146                              Message message = new Message();
147                              message.arg1 = downloadSize;
148                              message.arg2 = contentLength;
149                              message.what = 1;
150                              mHandler.sendMessage(message);
151                          }  
152                          // 完毕,关闭所有链接   
153                          os.close();  
154                          is.close();
155                             
156                 } catch (Exception e) {
157                         e.printStackTrace();
158                         Toast.makeText(DownApkActivity.this, "下载失败", Toast.LENGTH_SHORT).show();
159 //                        finish();
160                         tvComplete.setTextColor(Color.YELLOW);
161                         return;
162                 }
163                 
164             }
165         }).start();
166         
167     }
168     
169     
170     /**
171      * 安装APK文件
172      */
173     private void installApk(String filePath,String fileName)//TODO   search method parameters
174     {
175         File apkfile = new File(filePath,fileName);
176         if (!apkfile.exists())
177         {
178             return;
179         }
180         // 通过Intent安装APK文件
181         Intent i = new Intent(Intent.ACTION_VIEW);
182         i.setDataAndType(Uri.parse("file://" + APK_PATH + java.io.File.separator +fileName), "application/vnd.android.package-archive");
183         DownApkActivity.this.startActivity(i);
184     }
185     
186 }

下载完成后,便开始启动安装软件。

原文地址:https://www.cnblogs.com/SeawinLong/p/4142115.html