1. This time, the server uses HTTP Servlet to return json data
First, build a Java Web project and create a Servlet class. The code is implemented in doGet
Put the XML file in the WebContent directory and define the structure by yourself. For example, my version.xml is as follows:/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub // response.getWriter().append("Served at: // ").append(request.getContextPath()); HttpSession session = request.getSession(); String str = request.getParameter("function"); if (str == null) { str = "main"; } // Judge whether the session is newly created to reduce the frequency of reading xml if (session.isNew()) { //System.out.println("session created successfully, session id is:" + session.getId()); } else { //System.out.println("the server already has the session, and the session id is:" + session.getId()); String function = session.getAttribute("function").toString(); //Judge whether the functions are consistent if (function.equals(str)) { String data = session.getAttribute("data").toString(); response.setCharacterEncoding("utf-8"); response.getWriter().append(data); return; } } session.setAttribute("function", str.toString()); if (str != null && str.equals("Your APP alias")) {//function represents your APP, supports multiple APP version updates, and puts them in different xml DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = null; try { db = dbf.newDocumentBuilder(); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } String path = this.getServletContext().getRealPath("version2.xml"); File file = new File(path); InputStream is = new FileInputStream(file); org.w3c.dom.Document doc = null; try { doc = db.parse(is); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } Element elem = ((org.w3c.dom.Document) doc).getDocumentElement(); JSONObject jsonObjectRoot = new JSONObject(); NodeList appversion = elem.getChildNodes(); if (appversion != null) { JSONObject jsonObjectUpdate = new JSONObject(); int n = 0;// Update entries for (int i = 0; i < appversion.getLength(); i++) { Node app = appversion.item(i); for (Node node = app.getFirstChild(); node != null; node = node.getNextSibling()) { if (app.getNodeName().equals("version")) { String ver = app.getFirstChild().getNodeValue(); jsonObjectRoot.put("version", ver); } if (app.getNodeName().equals("date")) { String da = app.getFirstChild().getNodeValue(); jsonObjectRoot.put("date", da); } if (app.getNodeName().equals("update")) { n++; String ud = app.getFirstChild().getNodeValue(); jsonObjectUpdate.put(n + "", ud); } if (app.getNodeName().equals("address")) { String addr = app.getFirstChild().getNodeValue(); jsonObjectRoot.put("address", addr); } } } jsonObjectRoot.put("update", jsonObjectUpdate); } response.setCharacterEncoding("utf-8"); response.getWriter().append(jsonObjectRoot.toString()); session.setAttribute("data", jsonObjectRoot.toString()); } else { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = null; try { db = dbf.newDocumentBuilder(); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } String path = this.getServletContext().getRealPath("version.xml"); File file = new File(path); InputStream is = new FileInputStream(file); org.w3c.dom.Document doc = null; try { doc = db.parse(is); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } Element elem = ((org.w3c.dom.Document) doc).getDocumentElement(); JSONObject jsonObjectRoot = new JSONObject(); NodeList appversion = elem.getChildNodes(); if (appversion != null) { JSONObject jsonObjectUpdate = new JSONObject(); int n = 0;// Update entries for (int i = 0; i < appversion.getLength(); i++) { Node app = appversion.item(i); for (Node node = app.getFirstChild(); node != null; node = node.getNextSibling()) { if (app.getNodeName().equals("version")) { String ver = app.getFirstChild().getNodeValue(); jsonObjectRoot.put("version", ver); } if (app.getNodeName().equals("date")) { String da = app.getFirstChild().getNodeValue(); jsonObjectRoot.put("date", da); } if (app.getNodeName().equals("update")) { n++; String ud = app.getFirstChild().getNodeValue(); jsonObjectUpdate.put(n + "", ud); } if (app.getNodeName().equals("address")) { String addr = app.getFirstChild().getNodeValue(); jsonObjectRoot.put("address", addr); } } } jsonObjectRoot.put("update", jsonObjectUpdate); } response.setCharacterEncoding("utf-8"); response.getWriter().append(jsonObjectRoot.toString()); session.setAttribute("data", jsonObjectRoot.toString()); } }
You can put the APP download address in a virtual download directory of tamcat server, search tomcat to build a file download server, which is very simple to configure.<?xml version="1.0" encoding="UTF-8"?> <appupdate> <title>XX system</title> <version>1.1.0</version> <date>2018.02.04</date> <update>1:XXX optimization</update> <update>2:XXX modify</update> <update>3:XXX increase</update> <update>4:XXX Other</update> <address>http://1.1.1.1: 8888 / download / yourapp. APK < / address > <! -- download address of your updated APP -- > </appupdate>
In this way, you can access the address http://1.1.1.1:8888/YourWebName/YourServletName?function = your APP alias to get a json string, for example, my following:
{"version":"1.1.0","date":"2018.02.04","address":"http://1.1.1.1:8888/download/YourApp.apk","update":{"1":"1:XXX optimization", "2":"2:XXX modification", "3":"3:XXX increase", "4":"4:XXX others"}}}}
Now that the web server has been completed, write android
Two. Call in the onCreate method of MainActivity.public class AppVersion extends AsyncTask<String, integer, StringBuffer> { private Handler handle; public String getVersion() { return version; } private String version = ""; public String getUpdate() { return update; } private String update = ""; private String updateURL = ""; static private String updateAPKname = ""; static public String getAPKname() { return updateAPKname; } private boolean bAuto = true; public AppVersion(Handler handle, boolean bAuto/*Automatically check for updates, manually check for updates*/) { this.handle = handle; this.bAuto = bAuto; } @Override protected StringBuffer doInBackground(String... params) { String html = ""; try { //HTTP GET request URL url = null; url = new URL(params[0]); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(2000); conn.setReadTimeout(1000); InputStream inStream = conn.getInputStream(); byte[] data = readInputStream(inStream); html = new String(data, "utf-8"); } catch (Exception e) { e.printStackTrace(); } return new StringBuffer(html); } public static byte[] readInputStream(InputStream inStream) throws Exception { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, len); } inStream.close(); return outStream.toByteArray(); } @Override protected void onPostExecute(StringBuffer result) { String Html = new String(result); if (!Html.equals("")) { try { JSONObject jsonObjectRoot = new JSONObject(Html); version = jsonObjectRoot.getString("version"); JSONObject jsonObjectUpdate = jsonObjectRoot.getJSONObject("update"); Iterator<String> keys = jsonObjectUpdate.keys(); while (keys.hasNext()) { String key = (String) keys.next(); update = update + jsonObjectUpdate.getString(key) + "\r\n\r\n"; } updateURL = jsonObjectRoot.getString("address"); updateAPKname = updateURL.substring(updateURL.lastIndexOf("/") + 1); } catch (JSONException e) { e.printStackTrace(); } handle.sendEmptyMessage(4); } else { if (!bAuto) Toast.makeText(SearchApplication.getInstance(), "Unable to get update, please check whether the network is unblocked", Toast.LENGTH_LONG).show(); } super.onPostExecute(result); } public String getUpdateURL() { return updateURL; } public boolean isbAuto() { return bAuto; } public void setbAuto(boolean bAuto) { this.bAuto = bAuto; } }
private String path = "http://1.1.1.1:8888/YourWebName/YourServletName?function = your APP alias "; private AppVersion appVersion private MyHandler myHandler;
appVersion = new AppVersion(myHandler, true); appVersion.execute(path);
public class MyHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case 4://Query update return try { if (compareVersion(appVersion.getVersion(), getVersion()) > 0) { //After obtaining the last version, if the server version > the current version, the update content will only be prompted once, and then it will be displayed in the menu once String csTipUpdate = sp.getString(Constant.csTipUpdate, "0");//Get whether prompted //Display update pop-up if not prompted or manually updated if (csTipUpdate.equals("0") || !appVersion.isbAuto()) { showUpdateDialog(true);//Show updated pop ups sp.edit().putString(Constant.csTipUpdate, "1").apply(); } bUpdate = true;//Menu flag bit btnDowloadMap.setImageResource(R.mipmap.set1); } else { Log.d("version:", "No updated version!"); sp.edit().putString(Constant.csTipUpdate, "0").apply(); //After obtaining the last version, if it is inconsistent with the current version, the updated content will be displayed String csVersion = sp.getString(Constant.csVersion, ""); if (csVersion.equals("") || !csVersion.equals(appVersion.getVersion())) { showUpdateDialog(false);//show contents } sp.edit().putString(Constant.csVersion, appVersion.getVersion()).apply(); if (!appVersion.isbAuto()) Toast.makeText(MainActivity.this, "No updates available", Toast.LENGTH_LONG).show(); } } catch (Exception e) { e.printStackTrace(); } break; case 8://Download progress double percent = queryDownloadStatus(); if (progressBar_download != null) progressBar_download.setProgress((int) percent); if (percent >= 100) progressBar_download.setVisibility(View.INVISIBLE); break; } } }
/** * Compare the size of version number. If the former is large, it will return a positive number; if the latter is large, it will return a negative number; if it is equal, it will return 0 * * @param version1 * @param version2 */ public static int compareVersion(String version1, String version2) throws Exception { if (version1 == null || version2 == null) { throw new Exception("compareVersion error:illegal params."); } String[] versionArray1 = version1.split("\\.");//Note that this is a regular match and cannot be used; String[] versionArray2 = version2.split("\\."); int idx = 0; int minLength = Math.min(versionArray1.length, versionArray2.length);//Take the minimum length value int diff = 0; while (idx < minLength && (diff = versionArray1[idx].length() - versionArray2[idx].length()) == 0//Compare length first && (diff = versionArray1[idx].compareTo(versionArray2[idx])) == 0) {//Compare characters again ++idx; } //If the size has been allocated, it will be returned directly. If the size has not been allocated, then the number of digits will be compared again. If there is a sub version, it will be larger; diff = (diff != 0) ? diff : versionArray1.length - versionArray2.length; return diff; }
/** * Author: * CreateTime: 2017/11/15 11:09 * Comment: Get software version number * Param: */ public String getVersion() { try { PackageManager manager = this.getPackageManager(); PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0); String version = info.versionName; return version; } catch (Exception e) { String s = e.toString(); e.printStackTrace(); return ""; } }
3, android download APK installation
private DownloadManager downloadManager;//Download management class private long lastDownloadId;
/** * Author: * CreateTime: 2018/1/3 15:39 * Comment: update windows * Param: */ private void showUpdateDialog(boolean b) { if (b) { LayoutInflater inflater = LayoutInflater.from(this); View layout = inflater.inflate(R.layout.pop_needupdate, null);//Resource file is not posted final Dialog dialog = new Dialog(MainActivity.this, R.style.dialogstyle); TextView tv = (TextView) layout.findViewById(R.id.tvupdate);//File controls for displaying content final TextView tvdownload = (TextView) layout.findViewById(R.id.btn_download);//Download button TextView tvclose = (TextView) layout.findViewById(R.id.btn_close);//Pop up close button tvclose.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); } }); tvdownload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); Uri uri = Uri.parse(appVersion.getUpdateURL());//Update the APK URL obtained by the class DownloadManager.Request request = new DownloadManager.Request(uri); request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI); request.setVisibleInDownloadsUi(false); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN); File rootFile = new File(Environment.getExternalStorageDirectory().getPath() + "/YourAPP/download/");//Create a download directory if (!rootFile.exists()) { rootFile.mkdirs(); } request.setDestinationInExternalPublicDir("/YourAPP/download/", getAPKname());//Set download path lastDownloadId = downloadManager.enqueue(request); app.setLastDownloadId(lastDownloadId); progressBar_download.setVisibility(View.VISIBLE);//Download progress bar on pop-up window tvdownload.setText("Downloading"); tvdownload.setClickable(false); final Timer timer = new Timer(); TimerTask task = new TimerTask() { @Override public void run() { double percent = queryDownloadStatus(); myHandler.sendEmptyMessage(8); if (percent >= 100) { timer.cancel(); } } }; timer.schedule(task, 100, 500); } }); progressBar_download = (CustomLoading) layout.findViewById(R.id.progressBar_download); String update = appVersion.getUpdate(); tv.setText(update); dialog.setCancelable(false); dialog.setContentView(layout); dialog.show(); Window window = dialog.getWindow(); WindowManager manager = window.getWindowManager(); Display d = manager.getDefaultDisplay(); WindowManager.LayoutParams params = window.getAttributes(); params.width = (int) (d.getWidth() * 0.4); params.height = LinearLayout.LayoutParams.WRAP_CONTENT; dialog.getWindow().setAttributes(params); } else { LayoutInflater inflater = LayoutInflater.from(this); View layout = inflater.inflate(R.layout.pop_update, null);//After the update, the software enters the pop-up window to display the updated content for the first time final Dialog dialog = new Dialog(MainActivity.this, R.style.dialogstyle); TextView tv = (TextView) layout.findViewById(R.id.tvupdate); String update = appVersion.getUpdate(); tv.setText(update); dialog.setCancelable(true); dialog.setContentView(layout); dialog.show(); Window window = dialog.getWindow(); WindowManager manager = window.getWindowManager(); Display d = manager.getDefaultDisplay(); WindowManager.LayoutParams params = window.getAttributes(); params.width = (int) (d.getWidth() * 0.4); params.height = LinearLayout.LayoutParams.WRAP_CONTENT; dialog.getWindow().setAttributes(params); } }
//Add code to your Application public static YourApplication app; private long lastDownloadId; public static YourApplication getInstance() { return app; } public long getLastDownloadId() { return lastDownloadId; } public void setLastDownloadId(long lastDownloadId) { this.lastDownloadId = lastDownloadId; }
4, Join a broadcast and install it after downloading//Query download progress private int queryDownloadStatus() { DownloadManager.Query query = new DownloadManager.Query(); query.setFilterById(lastDownloadId); Cursor c = downloadManager.query(query); if (c != null && c.moveToFirst()) { int fileSizeIdx = c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES); int bytesDLIdx = c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR); int fileSize = c.getInt(fileSizeIdx); int bytesDL = c.getInt(bytesDLIdx); double percent = bytesDL * 100.0 / fileSize; return (int) percent; } return 0; }
Add the following code to Android manifest.xml
<! -- other network permissions will not be posted if they are not displayed in the notice bar when downloading updates -- > <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" /> </application> <receiver android:name=".BroadcastReceiver.CompleteReceiver"> <intent-filter> <action android:name="android.intent.action.DOWNLOAD_COMPLETE" /> </intent-filter> </receiver> </application>
OK, it's over here. I've been learning Android for several months. Sorry for any mistakes!public class CompleteReceiver extends BroadcastReceiver { private DownloadManager downloadManager; private long downloadId; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) { downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); installApk(context, downloadId); } } private void installApk(Context context, long downloadId) { DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); if (app.getLastDownloadId() == downloadId) { Uri downloadFileUri = downloadManager.getUriForDownloadedFile(downloadId); if (getAPKname() != null && !getAPKname().equals("")) { try { if (downloadFileUri != null) { Intent install = new Intent(Intent.ACTION_VIEW); install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive"); install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(install); } } catch (Exception e) { Toast.makeText(context, "install APP Problems arise", Toast.LENGTH_LONG).show(); } } else { Toast.makeText(context, "install APP Problems arise", Toast.LENGTH_LONG).show(); } } } }