android软件的自动提示更新功能可以使用第三方的SDK,这样可以大大的提高开发效率。但是作为一名好奇心强的程序员,必须能自己写出这样的一个功能。话不多述,正文开始:
- 首先,应当知晓自动提示更新的一个流程:
- 开发前的准备工作,首先我们应当准备好一个远程的服务器用于获取版本信息,我这里使用的PHP的appache服务器,并且使用的一个静态页面,返回json格式的数据:
- 准备工作做好后 ,就可以写代码了。首先我们在android studio 中新建一个项目AutoUpdateDemo,然后在java文件夹中新建一个类UpdateManager:
package com.sun.tvm.autoupdate; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.ProgressBar; import android.widget.Toast; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.Volley; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; /** * Created by Dean on 2016/8/25. */ public class UpdateManager { private static final String VERSION_PATH = "http://192.168.11.140:8088/version/version.html"; private static final int DOWNLOAD_ING = 1; private static final int DOWNLOAD_OVER = 2; private String version_code; private String version_name; private String version_desc; private String version_path; private Context mContext; private String mSavePath; private ProgressBar mProgress; private int progress; private Dialog downDialog; private Boolean isCancle = false; public UpdateManager(Context context){ mContext = context; } private Handler versionHandler = new Handler(){ @Override public void handleMessage(Message msg) { JSONObject jsonObject = (JSONObject) msg.obj; try { version_code = jsonObject.getString("version_code"); version_name = jsonObject.getString("version_name"); version_desc = jsonObject.getString("version_desc"); version_path = jsonObject.getString("version_path"); if (isUpdate()){ Toast.makeText(mContext, "需要更新", Toast.LENGTH_SHORT).show(); // 显示提示更新对话框 showNoticeDialog(); } else{ Toast.makeText(mContext, "已是最新版本", Toast.LENGTH_SHORT).show(); } } catch (JSONException e) { e.printStackTrace(); } } }; private Handler progressHandler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case DOWNLOAD_ING: mProgress.setProgress(progress); break; case DOWNLOAD_OVER: downDialog.dismiss(); installAPK(); break; } } }; /** *检测软件是否需要更新 * */ public void checkUpdate() { //1.开启新的线程网络请求 // new Thread(new Runnable() { // @Override // public void run() { // // try { // URL url = new URL(VERSION_PATH); // HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // String json = ""; // StringBuilder sb = new StringBuilder(); // BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); // while ((json = br.readLine()) != null){ // sb.append(json); // } // br.close(); // JSONObject jsonObject = new JSONObject(sb.toString()); // Message msg = Message.obtain(); // msg.obj = jsonObject; // versionHandler.sendMessage(msg); // } catch (Exception e) { // e.printStackTrace(); // } // // } // }).start(); //2。调用Volley网络请求框架 //定义一个请求队列 RequestQueue requestQueue = Volley.newRequestQueue(mContext); JsonObjectRequest request = new JsonObjectRequest(VERSION_PATH, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject jsonObject) { Message msg = Message.obtain(); msg.obj = jsonObject; versionHandler.sendMessage(msg); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError arg0) { System.out.println(arg0.toString()); } }); //添加到请求队列中 requestQueue.add(request); } /** * 是否需要更新 * @return */ protected boolean isUpdate() { int serverVersion = Integer.parseInt(version_code); int localVersion = 1; try { localVersion = mContext.getPackageManager().getPackageInfo("com.sun.tvm.autoupdate",0).versionCode; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } if(serverVersion > localVersion){ return true; } return false; } /* * 有更新时显示提示对话框 */ protected void showNoticeDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(mContext); builder.setTitle("发现新版本"); builder.setMessage("需要升级吗? \n" + version_desc); builder.setPositiveButton("更新", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //取消对话框 dialog.dismiss(); //下载文件 showDownloadDialog(); } }); builder.setNegativeButton("下次再说", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //取消对话框 dialog.dismiss(); } }); builder.create().show(); } /* * 显示正在下载对话框 */ protected void showDownloadDialog() { View view = LayoutInflater.from(mContext).inflate(R.layout.down_progress,null); mProgress = (ProgressBar) view.findViewById(R.id.id_Progress); AlertDialog.Builder builder = new AlertDialog.Builder(mContext); builder.setTitle("正在下载"); builder.setView(view); builder.setNegativeButton("取消下载", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { isCancle = true; } }); downDialog = builder.create(); downDialog.show(); downloadAPK(); } /* * 开启新线程下载文件 */ private void downloadAPK() { System.out.println(version_path); new Thread(new Runnable() { @Override public void run() { try { if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ String sdPath = Environment.getExternalStorageDirectory() + "/"; mSavePath = sdPath +"deanDownload"; File file = new File(mSavePath); if(!file.exists()){ file.mkdir(); } URL url = new URL(version_path); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.connect(); InputStream is = connection.getInputStream(); int len = connection.getContentLength(); File apkFile = new File(mSavePath, version_name); FileOutputStream fos = new FileOutputStream(apkFile); int count = 0; byte[] buffer = new byte[1024]; while(!isCancle){ int numread = is.read(buffer); count += numread; // 计算进度条的当前位置 progress = (int) (((float)count/len) * 100); // 更新进度条 progressHandler.sendEmptyMessage(DOWNLOAD_ING); // 下载完成 if (numread < 0){ progressHandler.sendEmptyMessage(DOWNLOAD_OVER); break; } fos.write(buffer, 0, numread); } }else{ System.out.println("00000000000000000000000000000"); } } catch (Exception e) { e.printStackTrace(); } } }).start(); } /* * 下载到本地后执行安装 */ protected void installAPK() { File apkFile = new File(mSavePath, version_name); if (!apkFile.exists()) return; Intent intent = new Intent(Intent.ACTION_VIEW); Uri uri = Uri.parse("file://" + apkFile.toString()); intent.setDataAndType(uri, "application/vnd.android.package-archive"); mContext.startActivity(intent); } }
-
然后我们就可以在主activity中调用这个java类:
public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new UpdateManager(this).checkUpdate(); } }
-
最后别忘了在androidManafiest文件中添加上网络请求的权限(最好在是在需要用到网络的时候就添加上相应的权限)
到这里就可以将项目运行到Genymotion模拟器上进行测试!
总结:整个项目用到的知识点:
- AlertDialog的使用
- 网络请求
- UI的更新(使用Handler)
- 调用系统Activity安装APK (Intent)
- 获取Sd路径,Environment.getExternalStorageDirectory()