Android program version detection and update

Android program version detection and update

Be an Android client of a website, and the user installs it on his mobile phone. What if I release a new version? There must be a version update function.

Originally, version detection is best done automatically. But if you start the program every time, you must first check it, which is a waste. After all, version updates are a small probability thing. Maybe you can judge the time when the program is started. It will be tested on a single day, but not tested on two days, or randomly, to reduce the frequency of testing?

The approach I took is to put the detection function on the menu, and if the user needs it, he can manually open it for himself. Anyway, we are a website client, and there is a version update, just post a notice on the website.

There are several key steps for version detection and update:

1. Check whether there is a new version

2. Download the new version

3. Install and replace the new version

The solution I deal with is

1. Add a new file in the assets folder: ver.cfg, record version information, in plain text format, with only one sentence:

Version=1.0Copy code


This will be installed and packaged on the user's mobile phone

Then in the website, set up an XML file ver_apk.xml, the content is only this:

<?xml version="1.0" encoding="utf-8" ?> < string > 1.0 </string > Copy code


When detecting, first visit the XML of the website to get the latest version number, and then compare it with the record in the ver.cfg file on the phone. If it is different, it can be considered that there is a new version and prompt to update.

2. When downloading, it is downloaded directly, I still don t know how to make a breakpoint to resume the upload

3. The key to installation and replacement is the signature. That is, the signature of each version must be consistent. Otherwise, the new one cannot replace the old one, and the installation is not completed.

------------------- The weather is too cold, giggle ------------------------- -----------

This function is done on the menu, and the trigger code is as follows:

//=============================================== ========================== //Menu //=============================================================================================================================================================================================================================================================================== ================================================== ===== private static final String urlApk = "http://3g.***.com/tool/***.apk" ; private static final String urlVer = "http://3g.***. com/tool/ver_apk.xml" ; @Override public boolean onCreateOptionsMenu (Menu menu) { menu.add(Menu.NONE, Menu.FIRST + 1 , 5 , "Detect Update" ).setIcon( android.R.drawable.ic_menu_upload); menu.add(Menu.NONE,Menu.FIRST+ 2 , 4 , "Exit" ).setIcon(android.R.drawable.ic_lock_power_off); return true ; } @Override public boolean onOptionsItemSelected (MenuItem item) { switch (item.getItemId()) { case Menu.FIRST + 1 : Toast.makeText( this , "Detecting version" , Toast.LENGTH_LONG).show(); UpdateVer uv = new UpdateVer(urlApk,urlVer,MainActivity. this ); uv.checkVer(); break ; case Menu.FIRST + 2 : confirmExit(); break ; } return false ; } Copy code


Detect and update because there are more codes, written as a class to encapsulate

UpdateVer.java

package android.***; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.util.Log; import android.webkit.URLUtil; import android.widget.Toast; import java.io.File; import java.io.FileNotFoundException; import java .io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.Properties; import org.xml.sax.InputSource; import java.text.SimpleDateFormat ; import java.util.Date; public class UpdateVer extends Activity { private static final String TAG = "DOWNLOADAPK" ; private String PastVersion; private String NowVersion; public ProgressDialog pBar; private String currentFilePath = "" ; private String fileEx = "" ; private String fileNa= "" ; private String strURL= "" ; private String VersionUri = "" ; privateContext mContext; private final String fileVer = "ver.cfg" ; public UpdateVer (String urlapk,String urlver, final Context context) { SimpleDateFormat df = new SimpleDateFormat( "yyyyMMddHHmmss" ); String ver = "?ver=" + df.format( new Date()); //Mainly to avoid the phone's cache strURL = urlapk + ver; VersionUri = urlver + ver; mContext = context; } public void checkVer () { //parse the Version webpage to get the version number getVersionxml(VersionUri); } private void compareVer () { load(); //When the latest version is available if (PastVersion != null && !PastVersion.equals(NowVersion)){ Dialog dialog = new AlertDialog.Builder(mContext).setTitle( "System Update" ) .setMessage(String.format( "Found a new version %s, the current version is %s, please update!" ,NowVersion,PastVersion)) //Set the content //Set the OK button.setPositiveButton( "OK" , new DialogInterface.OnClickListener () { @Override public void onClick (DialogInterface dialog, int which) { pBar = new ProgressDialog(mContext); pBar.setTitle( "Downloading" ); pBar.setMessage( "Please wait..." ); pBar.setProgressStyle(ProgressDialog.STYLE_SPINNER); fileEx = strURL.substring(strURL.lastIndexOf( "." ) + 1 ,strURL.length()).toLowerCase(); fileEx = fileEx.substring( 0 ,fileEx.lastIndexOf( "?" )); fileNa = strURL.substring(strURL.lastIndexOf( "/" ) + 1 ,strURL.lastIndexOf( "." )); getFile(strURL); } }).setNegativeButton( "Cancel" , new DialogInterface.OnClickListener() { @Override public void onClick (DialogInterface dialog, int whichButton) { //Click the "Cancel" button to exit the program } }).create(); //Create //Show dialog dialog.show(); } else { Toast.makeText(mContext, String.format( "Currently is the latest version %s" ,PastVersion), Toast.LENGTH_LONG).show(); } } private void getFile ( final String strPath) { pBar.show(); try { if (strPath.equals(currentFilePath) ){ getDataSource(strPath); } currentFilePath = strPath; Runnable r = new Runnable(){ @Override public void run () { try { getDataSource(strPath); } catch (Exception e){ Log.e(TAG, e.getMessage(), e); } } }; new Thread(r).start(); } catch (Exception e){ e.printStackTrace(); } } /*Get remote files*/ private void getDataSource (String strPath) throws Exception { if (!URLUtil.isNetworkUrl(strPath)) { Log.d( "Tag" , "error" ); } else { /*Get URL*/ URL myURL = new URL(strPath); /*Establish connection*/ URLConnection conn = myURL.openConnection(); conn.connect(); /*InputStream download file*/ InputStream is = conn.getInputStream(); if (is == null ) { Log.d( "tag" , "error" ); throw new RuntimeException( "The content of the file was not read" ); } /*Create a temporary file*/ File myTempFile = File.createTempFile(fileNa, "." + fileEx); myTempFile.getAbsolutePath(); /*Write the file to the temporary disk*/ FileOutputStream fos = new FileOutputStream(myTempFile); byte buf[] = new byte [ 128 ]; do { int numread = is.read(buf); if (numread <= 0 ) { break ; } fos.write(buf, 0 , numread); } while ( true ); /*Open the file for installation*/ openFile(myTempFile); try { is.close(); } catch (Exception ex){ Log.d( "Tag" , "error" ); Log.e(TAG, "error: " + ex.getMessage(), ex); } } } /* Open the file on the phone*/ private void openFile (File f) { pBar.cancel(); Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(android.content.Intent.ACTION_VIEW); /* Call getMIMEType() to get MimeType */ String type = getMIMEType(f); /* Set the file and MimeType of the intent */ intent.setDataAndType(Uri.fromFile(f),type); mContext.startActivity(intent); } /* The method of judging the file MimeType */ private String getMIMEType (File f) { String type = "" ; String fName = f.getName(); /* Get the extension*/ String end = fName.substring(fName.lastIndexOf( "." )+ 1 ,fName.length()).toLowerCase(); /* Determine MimeType according to the type of extension */ if (end.equals( "m4a" ) || end.equals( "mp3" ) || end.equals( "mid" ) || end.equals( "xmf" ) || end.equals( "ogg" ) || end.equals( "wav" )){ type = "audio" ; } else if (end.equals( "3gp" ) || end.equals( "mp4" )){ type = "video" ; } else if (end.equals( "jpg" ) || end.equals( "gif" ) || end.equals( "png" ) || end.equals( "jpeg" ) || end.equals( "bmp" )){ type = "image" ; } else if (end.equals( "apk" )){ /* android.permission.INSTALL_PACKAGES */ type = "application/vnd.android.package-archive" ; } else { type = "*" ; } /*If you can t open it directly, just jump out of the software list for the user to choose*/ if (!end.equals( "apk" )){ type += "/*" ; } return type; } private void getVersionxml (String resourceUrl) { GetVer gv = new GetVer(); gv.execute(resourceUrl); } private boolean load () { Properties properties = new Properties(); try { InputStream stream = mContext.getAssets().open(fileVer); //FileInputStream stream = mContext.openFileInput(fileVer); //Read file content properties.load(stream); } catch (FileNotFoundException e){ return false ; } catch (IOException e){ return false ; } catch (Exception e){ return false ; } PastVersion = String.valueOf(properties.get( "Version" ).toString()); return true ; } //=============================================== ========================== //GetVer //=================== ================================================== ===== class GetVer extends AsyncTask < String , Integer , String > { @Override protected String doInBackground (String... urlVer) { String db = null ; URL url = null ; try { url = new URL(urlVer[ 0 ]); } catch (MalformedURLException e) { e.printStackTrace(); } InputSource is = null ; try { is = new InputSource(url.openStream()); is.setEncoding( "UTF-8" ); db = SAXGetVersionService.readRssXml(is); } catch (Exception e) { e.printStackTrace(); } return db; } @Override protected void onCancelled () { super .onCancelled(); } @Override protected void onPostExecute (String result) { NowVersion = result; compareVer(); } } } Copy code

\

AndroidManifest.xml to add a few sentences

< uses-permission android:name = "android.permission.INTERNET"/> < uses-permission android:name = "android.permission.INSTALL_PACKAGES"/> < uses-permission android:name = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> < uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"/> < uses-permission android:name = "android.permission.RESTART_PACKAGES"/> < uses-permission android:name = "android.permission.READ_PHONE_STATE"/> < uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE"/> < uses-permission android:name = "android.permission.ACCESS_COARSE_LOCATION"/> < uses-permission android:name = "android.permission.ACCESS_WIFI_STATE"/> Copy code


Reference article:

\

download.csdn.net/detail/xtlv...

\

\

\

\

\

\