[Learn Android while working on a project] mobile security guard 03: gets the updated server configuration, displays the update dialog box, and learns android
Configure the name and icon of the application displayed on the mobile desktop-AndroidManifest. xml:
<? 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 = "19"/> <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; "> display the configured icon5 icon on the desktop ② </span> android: name =" com. liuhao. mobilesafe. ui. splashActivity "android: label =" @ string/app_name "> <span style =" color: # FF0000; "> app_name configured by name </span> <intent-filter> <action android: name =" android. intent. action. MAIN "/> <category android: name =" android. intent. category. LAUNCHER "/> </intent-filter> </activity> </application> </manifest>
After configuration
① ②
Obtain the updated server configuration process:
Server Configuration:
Use tomcat as the server, create an update. xml file in the TOMCAT_HOME/ROOT directory, and add information about the new version;
<? Xml version = "1.0" encoding = "UTF-8"?> <Info> <version> 2.0 </version> <description> click it to download the latest version! </Description> <apkurl> http: // local host: 18081/newapk.apk </apkurl> </info>
Access: http: // localhost: 18081/update. xml in the browser
Xml configuration file acquisition and parsing
When our application starts, we need to get the information of the new version from the above address and parse the xml configuration file.
Then how does the application obtain the address of the above version information? It is generally 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>
Next we will create the object class-UpdateInfo. java for the update. xml file:
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.apk url = apkurl ;}}
How can I get the file content (http: // 192.168.1.123: 18081/update. xml) corresponding to the url in config. xml )?
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; // Context information of the application environment public UpdateInfoService (context Context) {this. context = context;}/*** @ param urlId * id of the server resource path * @ return update information * @ throws Exception */public UpdateInfo getUpdateInfo (int urlId) throws Exception {String path = context. getResources (). getString (urlId); // obtain the URL of the resource file based on the urlId. url = new URL (path); HttpURLConnection conn = (HttpURLConnection) url. openConnection (); conn. setreadtimeouts (2000); conn. setRequestMethod ("GET"); InputStream is = conn. getInputStream (); // get the file stream corresponding to the url, which should be an xml file stream and need to be parsed return UpdateInfoParser. getUpdateInfo (is );}}
- Knowledge Point: Why is exceptions not captured in the business class, but thrown directly?
It is propagated to the higher level for handling, so that the cause of the error is not lost, so as to facilitate troubleshooting or capturing and processing. For Exception Handling, a general principle should be taken into account from the perspectives of design, needs, and maintenance. Do not catch exceptions and do nothing. Once an exception occurs, you cannot troubleshoot exceptions based on the exception information.
See: how to handle exceptions in the J2EE system
Parse xml files:
After obtaining the xml file stream, parse it and use XmlPullParser:
XmlPullParser splits xml into different event types (EventType)
Commonly used:
XmlPullParser. END_DOCUMENT: End of the document
XmlPullParser. START_DOCUMENT: the beginning of the document.
XmlPullParser. START_TAG: Start of the tag
XmlPullParser. END_TAG: End of the tag
XmlPullParser. TEXT: Content
The methods in this class are mainly used to obtain the content of EventType and redirect between eventtypes.
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 an xml file input stream * @ return resolved UpdateInfo */public static UpdateInfo getUpdateInfo (InputStream is) throws Exception {XmlPullParser parser = Xml. newPullParser (); UpdateInfo info = new Upd AteInfo (); // initialize the parser and set which input stream to be parsed. // This method resets the parser and event type) go to the initial position of the document (START_DOCUMENT) parser. setInput (is, "UTF-8"); int type = parser. getEventType (); // get the current EventType while (type! = XmlPullParser. END_DOCUMENT) {switch (type) {// process the tag type. case XmlPullParser. START_TAG: if ("version ". equals (parser. getName () {String version = 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 ;}}
I don't know how to test Android?
1. Create an Android Test Project and place the Project in the Test Project.
2. Set AndroidManifest in the test project. <uses-library android: name = "android. test. the runner "/> content and content under the <instrumentation> node are copied to the AndroidManifest of the project. in xml, pay attention to the corresponding node.
Then, the test project can be used for the moment.
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. To obtain the configuration file for updating information from the server, the program must have the permission to access the Internet:
Save.
5. Run the test code:
An exception occurred !!! Connect failed: ECONNREFUSED (Connection refused)
Exception Handling: java.net. ConnectException
When android reads a file from tomcat, the following exception occurs:
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)
Solution:
String url = "http: // localhost: 18081/update. xml"; modify it to String url = "http: // 192.168.1.123: 18081/update. xml ";
The Host ip address cannot use localhost or 127.0.0.1. Use the real ip address of the local machine. Use the ipconfig command to view the following information:
After exception handling, the operation is successful!
Use business in activity
All the Business Code has been completed. Return to the activity of splash to use 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. cont Ent. 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 = "SplashActi Outputs "; private TextView TV _splash_version; private LinearLayout ll_splash_main; private UpdateInfo info; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); // cancel the 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, "pop-up upgrade dialog box"); showUpdateDialog ();}/* AlphaAnimation class: the transparency change animation class * AlphaAnimation class is the transparency change animation class in the Android system, controls the transparency changes of View objects. This class inherits from the Animation class. * Many methods in the AlphaAnimation class are consistent with the Animation class. The most common method in this class is the AlphaAnimation constructor. ** Public AlphaAnimation (float fromAlpha, float toAlpha) parameter description fromAlpha: transparency at the start time. value range: 0 ~ 1. ToAlpha: transparency of the end time. value range: 0 ~ 1. */AlphaAnimation aa = new AlphaAnimation (0.0f, 1.0f); aa. setDuration (2000); // method of the Animation class, set the duration ll_splash_main.startAnimation (aa); // set the Animation // complete the full screen display of the form getWindow (). setFlags (WindowManager. layoutParams. FLAG_FULLSCREEN, WindowManager. layoutParams. FLAG_FULLSCREEN);} private void <span style = "color: # FF6666;"> showUpdateDialog </span> () {// a message box <span style = "color: # FF0000; "> AlertDialog. builder build Er = new Builder (this); </span> builder. setIcon (R. drawable. icon5); // set the title icon builder of the message box. setTitle ("upgrade reminder"); // set the title builder of the message box. setMessage (info. getDescription (); // set the builder of the content to be displayed. setCancelable (false); // prevents the user from pressing the back key to cancel builder. <span style = "color: # FF6666;"> setPositiveButton </span> ("OK", new OnClickListener () {// set the key operation @ Overridepublic void onClick (DialogInterface dialog, int which) {Log. I (TAG, "Bottom Load the pak file: "+ info. getApkurl () ;}}); builder. setNegativeButton ("cancel", new OnClickListener () {@ Overridepublic void onClick (DialogInterface dialog, int which) {Log. I (TAG, "the user cancels the upgrade and enters the main interface of the program") ;}}); builder. create (). show ();}/***** @ param versiontext current client version information * @ return whether 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, "same version number, no Upgrade required, go to the main interface"); return false;} else {Log. I (TAG, "different versions, upgrade required"); return true ;}} catch (Exception e) {e. printStackTrace ();/*** Toast usage scenario ** 1. You need to prompt the user, but you do not need to click "OK" or "cancel. * 2. Simple prompts that do not affect the running of existing activities. */Toast. makeText (this, "An error occurred while obtaining the update information", 2 ). show (); // pop up the text and keep the Log for 2 seconds. I (TAG, "An error occurred while obtaining the update information. Go to the main interface"); return false ;}@ Override public boolean onCreateOptionsMenu (Menu menu) {// Inflate the menu; this adds items to the action bar if it is present. getMenuInflater (). inflate (R. menu. splash, menu); return true;}/*** get the current program version * @ return */private String getVersion () {// get an instance of PackageManager, to obtain the global package information PackageManager manager = getPackageManager (); try {// Retrieve overall information about an application package that is installed on the system. packageInfo info = manager. getPackageInfo (getPackageName (), 0); // The version name of this package, as specified by the <manifest> tag's versionName attribute. return info. versionName;} catch (Exception e) {e. printStackTrace (); return "unknown version number ";}}}
- IsNeedUpdate () method: Call the getUpdateInfo () method of UpdateInfoService to obtain the update information. At the same time, compare the server version with the current client version and determine whether to allow the user to upgrade. If the two versions are inconsistent, remind the user to perform the upgrade:
- The showUpdateDialog () method is called here. In this method, a message box is displayed on the setting interface, with two buttons: "OK" and "cancel ", you can click different buttons to perform different operations.
Exception Handling android. OS. NetworkOnMainThreadException -- Multithreading
Everything is done, so you can rest assured that there is still a problem!
An error occurred while obtaining the update information !!! Debug and find Exception: android. OS. NetworkOnMainThreadException
This exception probably means an exception occurs when the main thread accesses the network. Android versions earlier than Android 4.0 support network access in the main thread, but later than Android 4.0 optimized this part of the program. That is to say, the code for network access cannot be written in the main thread.
Processing Method: http://blog.csdn.net/bruce_6/article/details/39640587
Why does the 360 security guard (Android) on the mobile phone prompt that there is an updated version but that version is not available on various software websites?
Maybe it's a test version. We suggest you do not update it first, maybe it's unstable.
(* ^__ ^ *) Xi ...... Hope to adopt it
How can the anti-eavesdropping function of 360 mobile guard be implemented? Android mobile phone 360 security guard has just been updated, and then calls the phone to display the anti-eavesdropping Prompt window
360 the anti-eavesdropping function of mobile guard is mainly to prevent the mobile phone from being implanted with the eavesdropping trojan virus. During calls, it monitors whether there are background programs listening for calls. The above is an official statement, and it cannot be determined whether it is valid or not.