"Side do project side learn Android" mobile Security Defender 03: Get updated server configuration, Show update dialog box

Source: Internet
Author: User

Configure the application to display the name and icon-androidmanifest.xml on the phone desktop:
<?xml version= "1.0" encoding= "Utf-8"? ><manifest xmlns:android= "http://schemas.android.com/apk/res/        Android "package=" Com.liuhao.mobilesafe "android:versioncode=" 1 "android:versionname=" 1.0 "> <uses-sdk android:minsdkversion= "8" android:targetsdkversion= "/> <application android:allowbackup=" True "android:icon=" @drawable/ic_launcher "<span style=" color: #FF0000; "        > "icons displayed in the Program management list" ①</span> android:label= "@string/app_name" android:theme= "@style/apptheme" > <activity android:icon= "@drawable/icon5" <span style= "color: #FF0000;" > "icon5 icon on desktop display for yourself" ②</span> android:name= "com.liuhao.mobilesafe.ui.SplashActivity" Andro Id:label= "@string/app_name" ><span style= "color: #FF0000;" > App_name named for itself ②</span> <intent-filter> <action android:name= "Android.int Ent.action.MAIN "/> <categoryAndroid:name= "Android.intent.category.LAUNCHER"/> </intent-filter> </activity> </a  Pplication></manifest>
When configured, displays

①②

Get the updated server configuration process:

Server configuration:

With Tomcat as the server, create a new Update.xml file in the Tomcat_home/root directory and add the relevant information to the newer version;

<?xml version= "1.0" encoding= "Utf-8"?><info>    <version>2.0</version>    < Description> Pro, latest version, speed to download! </description>    <apkurl>http://localhost:18081/newapk.apk</apkurl></info>
Access in Browser: Http://localhost:18081/update.xml

Obtaining and parsing of XML configuration files

Then our application starts by trying to get the new version of the information at the above address while parsing the XML configuration file.

So how does the application get to the address of the above version information? Typically stored as a configuration file in a resource file.
Config.xml<?xml version= "1.0" encoding= "Utf-8"?><resources>    <string name= "UpdateUrl" >http:/ /192.168.1.123:18081/update.xml</string></resources>
Here to establish the Update.xml file corresponding entity class-updateinfo.java:
Package com.liuhao.mobilesafe.domain;/*** @author liuhao* upgrade Information */public class UpdateInfo {    String version;    String description;    String Apkurl;    Public String getversion () {        return version;    }    public void Setversion (String version) {        this.version = version;    }    Public String getdescription () {        return description;    }    public void SetDescription (String description) {        this.description = description;    }    Public String Getapkurl () {        return apkurl;    }    public void Setapkurl (String apkurl) {        this.apkurl = Apkurl;    }}

How do I get the file contents (i.e., http://192.168.1.123:18081/update.xml) for this URL in config.

New update Information Service class: Updateinfoservice.java:

Package Com.liuhao.mobilesafe.engine;import Java.io.inputstream;import Java.net.httpurlconnection;import Java.net.url;import Android.content.context;import Com.liuhao.mobilesafe.domain.updateinfo;public Class Updateinfoservice {    private context context;//contextual information for the application environment Public    Updateinfoservice (context context) {        This.context = context;    }    /**     * @param urlId     *            The ID of the server resource path *     @return update information     * @throws     Exception    */Public UpdateInfo getupdateinfo (int urlId) throws Exception {        String path = Context.getresources (). getString (urlId);// Gets the content        url url = new URL (path) in the resource file according to Urlid;               HttpURLConnection conn = (httpurlconnection) url.openconnection ();        Conn.setreadtimeout (+);        Conn.setrequestmethod ("GET");               InputStream is = Conn.getinputstream (); Get the URL corresponding to the file stream, should be the XML file stream, need to parse it               return Updateinfoparser.getupdateinfo (IS);}    }

    • Knowledge points: Why not catch exceptions in the business class, but throw them directly?

Propagate outward to higher-level processing so that the error cause of the exception is not lost, making it easier to troubleshoot errors or capture processing. For exception handling, should be from the design, needs, maintenance and other aspects of the comprehensive consideration, there is a general rule: do not catch the exception of everything is not dry, so that once there is an exception, you can not be based on the exception information to the wrong.

See: Java EE system exception handling guidelines

Parse the XML file:

After getting to the XML file stream, to parse it, use xmlpullparser:

Xmlpullparser decomposition of XML into different event types (eventtype)

Commonly used are:
Xmlpullparser.end_document: End of document
Xmlpullparser.start_document: The beginning of the document
Xmlpullparser.start_tag: The beginning of the label
Xmlpullparser.end_tag: End of label
Xmlpullparser.text: Content

And the methods in this class are primarily used to get eventtype content, and to jump between EventType.

To create a tool service class that resolves update information updateinfoparser:

Package Com.liuhao.mobilesafe.engine;import Java.io.inputstream;import Org.xmlpull.v1.xmlpullparser;import Android.util.xml;import Com.liuhao.mobilesafe.domain.updateinfo;public class Updateinfoparser {/** * @param is XML        Format file input stream * @return parsed UpdateInfo */public static UpdateInfo Getupdateinfo (InputStream is) throws exception{        Xmlpullparser parser = Xml.newpullparser ();               UpdateInfo info = new UpdateInfo (); Initializes the parser parser, setting which input stream is ready for parsing//This method resets the parser, and the event type is positioned to the initial position of the document (Start_document) Parser.seti               Nput (IS, "utf-8"); int type = Parser.geteventtype ();            Gets the current EventType while (type! = xmlpullparser.end_document) {switch (type) {///to handle the label type therein Case XmlPullParser.START_TAG:if ("Version". Equals (Parser.getname ())) {String V                    Ersion = Parser.nexttext ();                Info.setversion (version); } else if ("description". Equals (Parser.getname ())) {String description = Parser.nexttext ();                Info.setdescription (description);                    } else if ("Apkurl". Equals (Parser.getname ())) {String Apkurl = Parser.nexttext ();                Info.setapkurl (Apkurl);            } break;        } type = Parser.next ();    } return info;  }   }

Test does not know how to test Android?

1. Create a new Android test project and put our project in the test.

2, the test project in the Androidmanifest.xml <uses-library android:name= "Android.test.runner"/> Content and <instrumentation Copy the contents of the > node into the androidmanifest.xml of the project, paying attention to the corresponding nodes.

After that, the test project can be temporarily unused.

3. Create a test class

Package Com.liuhao.mobilesafe.test;import Junit.framework.assert;import Com.liuhao.mobilesafe.r;import Com.liuhao.mobilesafe.domain.updateinfo;import Com.liuhao.mobilesafe.engine.updateinfoservice;import Android.test.androidtestcase;public class Testgetupdateinfo extends Androidtestcase {public    void Testgetinfo () Throws exception{        Updateinfoservice service = new Updateinfoservice (GetContext ());        UpdateInfo info = service.getupdateinfo (r.string.updateurl);               Assert.assertequals ("2.0", Info.getversion ());    }   

4, the configuration file that obtains the update information from the server, needs the program to have the permission to access the Internet:

Save, then.

5. Run the test code:

The exception is present!!! Connect failed:econnrefused (Connection refused)

Exception Handling: Java.net.ConnectException

The following exception occurred when Android read files from Tomcat:

08-10 14:53:09.118:w/system.err (12527): java.net.ConnectException:failed to connect to localhost/127.0.0.1 (port 8080) : Connect failed:econnrefused (Connection refused)

Workaround:

String url = "Http://localhost:18081/update.xml"; Modify to String url = "Http://192.168.1.123:18081/update.xml";

Host IP cannot use localhost or 127.0.0.1, use native real IP address. Using the ipconfig command, you can view:

After exception handling, run successfully!

Use of business in activity

All the business code has been completed, back to splash activity using the business!

Package Com.liuhao.mobilesafe.ui;import Com.liuhao.mobilesafe.r;import Com.liuhao.mobilesafe.domain.UpdateInfo; Import Com.liuhao.mobilesafe.engine.updateinfoservice;import Android.os.bundle;import Android.app.Activity;import Android.app.alertdialog;import Android.app.alertdialog.builder;import Android.content.dialoginterface;import Android.content.dialoginterface.onclicklistener;import Android.content.pm.packageinfo;import Android.content.pm.packagemanager;import Android.util.log;import Android.view.menu;import Android.view.Window; Import Android.view.windowmanager;import Android.view.animation.alphaanimation;import Android.widget.LinearLayout Import Android.widget.textview;import Android.widget.toast;public class Splashactivity extends Activity {private Static final String TAG = "splashactivity";p rivate TextView tv_splash_version;private linearlayout ll_splash_main;    Private UpdateInfo info; @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (SavediNstancestate);                Remove title bar requestwindowfeature (Window.feature_no_title);                Setcontentview (R.layout.splash);        Tv_splash_version = (TextView) This.findviewbyid (r.id.tv_splash_version);                Ll_splash_main = (linearlayout) This.findviewbyid (R.id.ll_splash_main);        String Versiontext = GetVersion ();                Tv_splash_version.settext (Versiontext);        if (Isneedupdate (Versiontext)) {log.i (TAG, "popup Upgrade Dialog");        Showupdatedialog (); }/* Alphaanimation class: Transparency Change Animation class * Alphaanimation class is an animation class for transparency changes in Android systems that controls the transparency of a View object, which inherits from the animation         Class.         * Many methods in the Alphaanimation class are consistent with the animation class, and the most common method in this class is the Alphaanimation construction method. * Public alphaanimation (float fromalpha, float toalpha) parameter description Fromalpha: Transparency at start time, value range 0~1.         Toalpha: The transparency of the end time, the value range 0~1.        */alphaanimation AA = new Alphaanimation (0.0f, 1.0f); Aa.setduration (2000); Animation class method, set duration Ll_splash_main.startaNimation (AA); Set the animation//complete full-screen display of the form GetWindow (). SetFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WINDOWMANAGER.L    Ayoutparams.flag_fullscreen); private void <span style= "color: #FF6666;" >showUpdateDialog</span> () {//Popup a message box <span style= "color: #FF0000;" >alertdialog.builder builder = new Builder (this);</span> Builder.seticon (R.DRAWABLE.ICON5); Set the caption icon for the message box Builder.settitle ("Upgrade reminder"); Sets the title of the message box Builder.setmessage (Info.getdescription ()); Sets the content to display builder.setcancelable (false); Let the user not press the back key to cancel Builder.<span style= "color: #FF6666;" >setPositiveButton</span> ("OK", new Onclicklistener () {//Set the key action when the user chooses ok @overridepublic void OnClick (        Dialoginterface dialog, int which) {log.i (TAG, "Download Pak file:" + Info.getapkurl ());}); Builder.setnegativebutton ("Cancel", new Onclicklistener () {@Overridepublic void OnClick (dialoginterface dialog, int which)        {LOG.I (TAG, "User cancels upgrade, enters program main interface");});    Builder.create (). Show (); }/**    * * @param versiontext version information for current client * @return need to update */private Boolean isneedupdate (String versiontext)    {Updateinfoservice service = new Updateinfoservice (this); try {info = service.getupdateinfo (r.string.updateurl); String Version = Info.getversion (), if (Versiontext.equals (version)) {LOG.I (TAG, "version number is the same, no upgrade required, go to main interface"); return false;} ELSE{LOG.I (TAG, "version number is different, need to upgrade"); return true;}} catch (Exception e) {e.printstacktrace ();/** * Toast Usage scenario * 1, need to prompt the user, but do not need the user to click the "OK" or "Cancel" button. * 2, does not affect the existing activity running simple hints.    */toast.maketext (This, "Get update Information exception", 2). Show ()//Popup text and keep 2 seconds log.i (TAG, "Get update information exception, go to Main interface"); return false;} } @Override Public boolean Oncreateoptionsmenu (Menu menu) {//Inflate the menu, this adds items to the action Ba        R if it is present.        Getmenuinflater (). Inflate (R.menu.splash, menu);    return true;     }/** * Gets the version number of the current program * @return */private String getversion () {//Gets an instance of Packagemanager so that the global package information can be obtained Packagemanager Manager = GetpackAgemanager (); try {//Retrieve overall information about a application package, that's installed on the system. PackageInfo info = manager.getpackageinfo (getpackagename (), 0);//The version name of this package, as specified by the &L t;manifest> tag ' s versionname attribute.return info.versionname;}        catch (Exception e) {e.printstacktrace (); return "version number Unknown";} }    }

    • isneedupdate () method: Call Updateinfoservice's Getupdateinfo () method to obtain the update information. Also compare the server-side version number to the current client's version number and make any actions that allow the user to upgrade. If two version numbers are found to be inconsistent, you should be reminded to upgrade:
    • Here called the Showupdatedialog () method, in this method, the setting interface pops up a message box, which has two buttons: "OK" "Cancel", the user clicks the different buttons corresponding to different actions.
Exception Handling android.os.networkonmainthreadexception--Multithreading problems

Everything settled, thought peace of mind, the result is still a problem!

Log start error, get update information exception!!! Debug, Find Exception:android.os.NetworkOnMainThreadException.

This exception probably means an exception when the main thread accesses the network. Android's version prior to 4.0 supported access to the network in the main thread, but after 4.0 it was optimized for this part of the program, meaning that the code to access the network could not be written in the main thread.

Treatment method: http://blog.csdn.net/bruce_6/article/details/39640587

"Side do project side learn Android" mobile Security Defender 03: Get updated server configuration, Show update dialog box

Related Article

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.