"android" Android program updates automatically

Source: Internet
Author: User
<span id="Label3"></p><p><p>The steps to automatically update the app are divided into three steps:</p></p> <ol> <ol> <li>Check for updates (if There is an update for step 2nd, otherwise Return)</li> <li>Download the new APK installation package</li> <li>Install APK</li> </ol> </ol><p><p>The following three steps to explain, which will be interspersed with the corresponding code, the app automatically update the three steps are encapsulated in a separate updater class, can be directly used, I will post the article at the end of the source GitHub Address.</p></p>Updater Use Example<p><p>Through a single class <code>Updater</code> can be easily implemented to automatically check for updates, download the installation package and automatic installation, you can listen to download progress, You can customize the update prompt and so On. Save path can be written freely, if a directory does not exist in the path will be created automatically, streaming API interface easy to Use. Here is an example of using a line of code to fix automatic updates:</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs avrasm">String savePath = Environment<span class="hljs-preprocessor">.getExternalStorageDirectory</span>() <span class="hljs-string">"/whinc/download/whinc.apk"</span><span class="hljs-comment">;</span><span class="hljs-string">"http://192.168.1.168:8000/update.xml"</span><span class="hljs-comment">;</span>Updater<span class="hljs-preprocessor">.with</span>(mContext) <span class="hljs-preprocessor">.downloadListener</span>(mListener) <span class="hljs-preprocessor">.update</span>(updateUrl) <span class="hljs-preprocessor">.save</span>(savePath) <span class="hljs-preprocessor">.create</span>() <span class="hljs-preprocessor">.checkUpdate</span>()<span class="hljs-comment">;</span></code></pre></pre><p><p></p></p>First step: Check for updates<p><p>This step requires a server-side mate, which stores an xml-formatted configuration file (also available in JSON or other format) to the client for checking for updates, Update.xml in the following format:</p></p><pre class="prettyprint"><code class=" hljs xml"><span class="hljs-pi"><span class="hljs-pi"><?xml version= "1.0" encoding= "utf-8"?></span></span><span class="hljs-tag"><span class="hljs-tag"><<span class="hljs-title">info</span>></span></span> <span class="hljs-tag"><span class="hljs-tag"><<span class="hljs-title">version</span>></span></span> <span class="hljs-tag"><span class="hljs-tag"><<span class="hljs-title">code</span>></span></span>4<span class="hljs-tag"><span class="hljs-tag"></<span class="hljs-title">Code</span>></span></span> <span class="hljs-tag"><span class="hljs-tag"><<span class="hljs-title">name</span>></span></span>1.0.4<span class="hljs-tag"><span class="hljs-tag"></<span class="hljs-title">name</span>></span></span> <span class="hljs-tag"><span class="hljs-tag"></<span class="hljs-title">version</span>></span></span> <span class="hljs-tag"><span class="hljs-tag"><<span class="hljs-title">URL</span>></span></span>http://192.168.1.168:8000/test.apk<span class="hljs-tag"><span class="hljs-tag"></<span class="hljs-title">URL</span>></span></span> <span class="hljs-tag"><span class="hljs-tag"><<span class="hljs-title">description</span>></span></span>Update-bar bar, fix-bar, add-blblblb<span class="hljs-tag"><span class="hljs-tag"></<span class="hljs-title">Description</span>></span></span><span class="hljs-tag"><span class="hljs-tag"></<span class="hljs-title">Info</span>></span></span></code></pre> <ul> <ul> <li><code><version></code>The tag specifies the version number and version name of the server side, which corresponds to the and version name of the Android project configuration <code>versionCode</code> <code>versionName</code> (Eclipse ADT Project can be found in the tags in androidmanifest.xml, android The studio project is found in the defaultconfig in the Module's build.gradle).</li> <li><code><url></code>tag to specify the apk,</li> <li><code><description></code>Label to specify the update Content.</li> </ul> </ul><p><p>The client requests the Server-side Update.xml file via HTTP, and then resolves update.xml, comparing the server-side version number to the local version number, if the server-side version number is newer than the local version number description, according to Download the latest apk from the APK specified in update.xml, which will be explained in detail below.</p></p><p><p>Here's the code to check for Updates:</p></p><pre class="prettyprint"><code class=" hljs java"> <span class="hljs-javadoc"><span class="hljs-javadoc">/** * Check the APP version number * *<span class="hljs-javadoctag"> @return</span> return False if a new version returns True</span> */</span> <span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Boolean</span></span> <span class="hljs-title"><span class="hljs-title">checkversion</span></span>() {url url; HttpURLConnection Httpconn =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{url =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>URL (mcheckupdateurl); Httpconn = (httpurlconnection) url.openconnection (); Httpconn.setconnecttimeout (<span class="hljs-number"><span class="hljs-number">200000</span></span>); Httpconn.setreadtimeout (<span class="hljs-number"><span class="hljs-number">200000</span></span>); Httpconn.setusecaches (<span class="hljs-keyword"><span class="hljs-keyword">false</span></span>);<span class="hljs-comment"><span class="hljs-comment">//disable cache for current HTTP connection</span></span>Httpconn.connect ();<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(httpconn.getresponsecode () = = Httpurlconnection.http_ok) {inputstream InputStream = Httpconn.getinputstream ();<span class="hljs-comment"><span class="hljs-comment">//parse XML Data</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(!parsexml (inputstream)) {<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword">false</span></span>; }<span class="hljs-comment"><span class="hljs-comment">//compare Local version number to server version number</span></span>PackageInfo PackageInfo = Mcontext.getpackagemanager (). getpackageinfo (mcontext.getpackagename (),<span class="hljs-number"><span class="hljs-number">0</span></span>);<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(packageinfo.versioncode < Mremoteversioncode) {<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword">true</span></span>; } }<span class="hljs-keyword"><span class="hljs-keyword">Else</span></span>{<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword">false</span></span>; } }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(malformedurlexception E) {e.printstacktrace (); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(ioexception E) {e.printstacktrace (); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(packagemanager.namenotfoundexception E) {e.printstacktrace (); }<span class="hljs-keyword"><span class="hljs-keyword">finally</span></span>{httpconn.disconnect (); }<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword">false</span></span>; }</code></pre><p><p>First create the HttpURLConnection access Server-side update.xml file, and then parse the Update.xml file returned by the server, and save the version information, apk and update log, after parsing, by getting the current client version number compared to the server version number, If the Server-side version number is larger, the service side has an updated version, the Checkversion () method returns true, otherwise false is Returned.</p></p><p><p>When checking for updated code below, It is important to note that Android does not allow network requests to be initiated in the main thread (ui thread), so <code>checkVersion()</code> calls need to be placed in a non-main thread. There are many ways to implement asynchronous requests, where I use Asynctask.</p></p><pre class="prettyprint"><code class=" hljs java"> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">checkupdate</span></span>() {<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>asynctask<void, Void, boolean> () {<span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword">protected</span></span>Boolean<span class="hljs-title"><span class="hljs-title">Doinbackground</span></span>(Void ... Params) {<span class="hljs-keyword"><span class="hljs-keyword">Boolean</span></span>Hasnewversion = Checkversion ();<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>hasnewversion; }<span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword">protected</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">OnPostExecute</span></span>(Boolean Hasnewversion) {<span class="hljs-keyword"><span class="hljs-keyword">Super</span></span>. OnPostExecute (hasnewversion);<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(mcheckupdatelistener = =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>|| !mcheckupdatelistener.oncompleted (hasnewversion, mremoteversioncode, mremoteversionname, mUpdateLog , Mapkdownloadurl)) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(hasnewversion) {showupdatedialog (); }}}}.execute (); }</code></pre>Download the new APK installation package<p><p><code>showUpdateDialog()</code>After the call displays the Update prompt dialog box, in the dialog confirmation button click event, First create the Downloadmanager.request object, and then set the various properties of the object download save path, notification Bar title, etc. finally, The download request is placed in the download queue of the system service downloadmanager, which is handed to the system to process the download Logic. In order to listen to the download completion event, the code registers the broadcast <code>DownloadManager.ACTION_DOWNLOAD_COMPLETE</code> . The download progress is monitored by registering contentobserver.</p></p><pre class="prettyprint"><code class=" hljs java"> <span class="hljs-javadoc"><span class="hljs-javadoc">/** * Show update dialog box *</span> /</span> <span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Showupdatedialog</span></span>() {alertdialog.builder Builder =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Alertdialog.builder (mcontext); Builder.settitle (mtitle); Builder.setmessage (mupdatelog); Builder.setpositivebutton (mdialogokbtntxt,<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Dialoginterface.onclicklistener () {<span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">OnClick</span></span>(dialoginterface dialog,<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Which) {dialog.dismiss ();<span class="hljs-comment"><span class="hljs-comment">//background Download</span></span>Mdownloadmgr = (downloadmanager) Mcontext.getsystemservice (context.download_service); Downloadmanager.request Request =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Downloadmanager.request (uri.parse (mapkdownloadurl));<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(environment.getexternalstoragestate (). equals (ENVIRONMENT.MEDIA_MOUNTED)) {<span class="hljs-comment"><span class="hljs-comment">//if the Save path contains subdirectories, you need to first create the directory recursively</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(!createdirifabsent (msavepath)) {LOG.E (<span class="hljs-string"><span class="hljs-string">"TAG"</span></span>,<span class="hljs-string"><span class="hljs-string">"apk Save path can not be created:"</span></span>+ msavepath);<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>; } Request.setdestinationuri (uri.fromfile (<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>File (msavepath)); Request.settitle (mnotificationtitle); Request.settitle (mnotificationmessage);<span class="hljs-comment"><span class="hljs-comment">//register a broadcast, listen for download completion events</span></span>Mcontext.registerreceiver (mcompletereceiver,<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Intentfilter (downloadmanager.action_download_complete));<span class="hljs-comment"><span class="hljs-comment">//register Monitor Download Progress</span></span>Mcontext.getcontentresolver (). registercontentobserver (uri.parse (<span class="hljs-string"><span class="hljs-string">"content://downloads/my_downloads"</span></span>),<span class="hljs-keyword"><span class="hljs-keyword">true</span></span>, mcontentobserver); Mdownloadid = Mdownloadmgr.enqueue (request); }<span class="hljs-keyword"><span class="hljs-keyword">Else</span></span>{LOG.E (<span class="hljs-string"><span class="hljs-string">"TAG"</span></span>,<span class="hljs-string"><span class="hljs-string">"can not access external storage!"</span></span>);<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>; } Toast.maketext (mcontext,<span class="hljs-string"><span class="hljs-string">"downloading in the background ..."</span></span>, toast.length_short). show (); } }); Builder.setnegativebutton (mdialogcancelbtntxt,<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Dialoginterface.onclicklistener () {<span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">OnClick</span></span>(dialoginterface dialog,<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Which) {dialog.cancel (); } }); Builder.create (). Show (); }<span class="hljs-javadoc"><span class="hljs-javadoc">/** * If the directory in the path specified by the parameter path does not exist, create the specified directory, ensuring that the parent directory of the path path exists * *<span class="hljs-javadoctag"> @param</span> Path Absolute path (including the file name, for example '/sdcard/storage /download/test.apk ') *<span class="hljs-javadoctag"> @return</span> Returns True if the directory was successfully created, otherwise false</span> */</span> <span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Boolean</span></span> <span class="hljs-title"><span class="hljs-title">createdirifabsent</span></span>(String Path) {string[] array = Path.trim (). split (file.separator); list<string> dirnames = arrays.aslist (array). sublist (<span class="hljs-number"><span class="hljs-number">1</span></span>, array.length-<span class="hljs-number"><span class="hljs-number">1</span></span>); StringBuilder Pathbuilder =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>StringBuilder (file.separator);<span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>(String d:dirnames) {pathbuilder.append (d); File f =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>File (pathbuilder.tostring ());<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(!f.exists () &&!f.mkdir ()) {<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword">false</span></span>; } pathbuilder.append (file.separator); }<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword">true</span></span>; }</code></pre>Install APK<p><p>Once the APK download is complete and you receive a broadcast message, you can perform the action of installing the apk, but first determine whether the broadcast event is due to our apk download by downloading the id, because the system may have multiple download tasks at the same time, differentiated by the download ID.</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs java"> <span class="hljs-keyword">new</span> BroadcastReceiver() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span><span class="hljs-keyword">void</span><span class="hljs-title">onReceive</span>(Context context, Intent intent) { <span class="hljs-keyword">long</span> downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -<span class="hljs-number">1</span>); <span class="hljs-keyword">if</span> (downloadId == mDownloadId) { installApk(); release(); } } };</code></pre></pre><p><p>Here is the installapk () method, which first retrieves the downloaded APK storage path from the Downloadmanager by downloading the id, and then installs the downloaded apk from the intent, which is very simple. Note that the intent setting is identified as <code>Intent.FLAG_ACTIVITY_NEW_TASK</code> otherwise it will not start the Setup program properly.</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs java"> <span class="hljs-javadoc">/** * 替换安装当前App,注意:签名一致 */</span> <span class="hljs-keyword">private</span><span class="hljs-keyword">void</span><span class="hljs-title">installApk</span>() { <span class="hljs-comment">// 获取下载的 APK 地址</span> Uri apkUri = mDownloadMgr.getUriForDownloadedFile(mDownloadId); <span class="hljs-keyword">new</span> Intent(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); <span class="hljs-string">"application/vnd.android.package-archive"</span>); mContext.startActivity(intent); }</code></pre></pre>GitHub source<p><p>Whinc/android-updatemanager</p></p><p><p>Better References:</p></p><p><p>Downloadmanager | Android Developers<br>Android system Download management Downloadmanager feature introduction and use Example</p></p> <p style="font-size:12px;"><p style="font-size:12px;">Copyright Notice: This article for Bo Master original article, without Bo Master permission not Reproduced.</p></p> <p><p> Android Android program updates automatically </p> </p></span>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.