Android Learning Series (2)-download in the notification bar of APP auto update

Source: Internet
Author: User

I have witnessed many upgrades in the blog Park. You also want to notify users of new features by updating your software. Yes.
This articleArticleIt is a must-have knowledge for Android Developers. It is not perfect but useful for everyone.

1. design concept. versioncode is used to define version upgrade parameters.
Android provides two attributes for our defined version:

 
<Manifest package = "com. cnblogs. Tianxia. Subway" Android: versioncode = "1" <! -- Integer type, which is not displayed to users --> Android: versionname = "1.0" <! -- String type, the system displays the user -- >></manifest>

Google recommends that we use versioncode auto-increment to indicate version upgrades, whether large changes or small changes, and versionname is used as a display of the Software Version viewed by users. So we chose versioncode as the parameter for defining version upgrade.

2. project directory
In order to provide practical guidance for real projects or enterprise applications, I simulate an independent project. The project directory settings are reasonable and rigorous, rather than just a demo.
Assume that we use Shanghai Metro as the project and name it "Subway". The project structure is as follows,

3. Compare version initialization with version number.
First, define the variables localversion and serverversion in the Global File global. Java to store the local version and server version respectively.

Public class global {// version information public static int localversion = 0; public static int serverversion = 0; public static string downloaddir = "app/download /";}

Because this article only focuses on upgrading and updating, to prevent too many others from being irrelevantCodeIn redundancy, I define the initglobal () method directly in subwayapplication.

 
/*** Initialize the global variable ** in actual work, serverversion is obtained from the server. It is best to execute */Public void initglobal () {try {Global in the activity of the startup screen. localversion = getpackagemanager (). getpackageinfo (getpackagename (), 0 ). versioncode; // set the local version global. serverversion = 1; // assume that the server version is 2 and the local version is 1} catch (exception ex) {ex. printstacktrace ();}}

If the new version is detected, the system prompts you whether to update the version. In subwayactivity, The checkversion () method is defined:

/*** Check the updated version */Public void checkversion () {If (Global. localversion <global. serverversion) {// when a new version is found, the user is prompted to update alertdialog. builder Alert = new alertdialog. builder (this); alert. settitle ("software upgrade "). setmessage ("A new version is found. We recommend that you update it now. "). setpositivebutton ("Update", new dialoginterface. onclicklistener () {public void onclick (dialoginterface Diener, int which) {// enable the Update Service UpdateService // to better modularize update, you can upload UpdateService dependent values // such as layout ID, resource ID, and dynamically obtained title. Here we use app_name as an example: intent updateintent = new intent (subwayactivity. this, UpdateService. class); updateintent. putextra ("titleid", R. string. app_name); startservice (updateintent );}}). setnegativebutton ("cancel", new dialoginterface. onclicklistener () {public void onclick (dialoginterface diich, int which) {dialog. dismiss () ;}}); alert. create (). show ();} else {// cleanup, skip // cheanupdatefile (), and I will attach the code later }}

For example:

Okay. Now let's string these things:
Step 1Run initglobal () in the oncreate () method of subwayapplication to initialize the version variable..

 
Public void oncreate () {super. oncreate (); initglobal ();}

Step 2The oncreate () method of subwayactivity detects version update checkversion ().

 
Public void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. Main); checkversion ();}

Now that the entry has been opened, we can see in the 18th line code of the checkversion method that when you click Update, we enable the Update Service and download the latest version from the server.

4. Use the service to download data from the server in the background. After the download is completed, the system prompts the user to complete the download and closes the service.
Define a service UpdateService. java. First, define the variables related to downloads and notifications:

// Title private int titleid = 0; // file storage private file updatedir = NULL; private file updatefile = NULL; // notification bar private icationicationmanager updatenotificationmanager = NULL; private notification updatenotification = NULL; // jump to intent private intent updateintent = NULL in the notification bar; private pendingintent updatependingintent = NULL;

Prepare the download tasks in the onstartcommand () method:

@ Override public int onstartcommand (intent, int flags, int startid) {// get the passed value titleid = intent. getintextra ("titleid", 0); // create a file if (Android. OS. environment. media_mounted.equals (Android. OS. environment. getexternalstoragestate () {updatedir = new file (environment. getexternalstoragedirectory (), Global. downloaddir); updatefile = new file (updatedir. getpath (), getresources (). getstring (titleid) + ". APK ");} This. updatenotificationmanager = (icationicationmanager) getsystemservice (notification_service); this. updatenotification = new notification (); // sets the download process. Click the notification bar and return to the main interface, updateintent = new intent (this, subwayactivity. class); updatependingintent = pendingintent. getactivity (this, 0, updateintent, 0); // sets the content updatenotification in the notification bar. icon = R. drawable. arrow_down_float; updatenotification. tickertext = "Start download"; updatenotification. setlatesteventinfo (this, "Shanghai Metro", "0%", updatependingintent); // send a notification to updatenotificationmanager. Y (0, updatenotification); // enable a new thread for downloading. If you use the service for Synchronous downloading, this will cause ANR problems, the Service itself also blocks new thread (New updaterunnable ()). start (); // This is the focus of the download, and is the return Super. onstartcommand (intent, flags, startid );}

The above are all preparations,

It can be seen from the code that the updaterunnable class is the real download class. For the sake of user experience, this class is executed by a separate thread in the background.
The download process involves two tasks: 1. Downloading data from the server; 2. notifying the user of the download progress.
Thread notification. First, we define an empty updatehandler.

 
Private handler updatehandler = new handler () {@ override public void handlemessage (Message MSG ){}};

Then create the real implementation of the updaterunnable class:

Class updaterunnable implements runnable {message = updatehandler. obtainmessage (); Public void run () {message. What = download_complete; try {// Add permission; If (! Updatedir. exists () {updatedir. mkdirs ();} If (! Updatefile. exists () {updatefile. createnewfile ();} // download function, take QQ as an example // Add permission; long downloadsize = downloadupdatefile ("http://softfile.3g.qq.com: 8080/msoft/179/1105/10753/mobileqq1.0(android1__build0198.apk ", updatefile); If (downloadsize> 0) {// the download is successful. updatehandler. sendmessage (Message) ;}} catch (exception ex) {ex. printstacktrace (); message. what = download_fail; // download failed updatehandler. sendmessage (Message );}}}

there are many implementation methods for downloading functions. I will post the code here, and we will notify the user of the download progress when downloading:

Public long downloadupdatefile (string DownLoadURL, file SaveFile) throws exception {// there are a lot of download code. I will not overwrite the description int downloadcount = 0; int currentsize = 0; long totalsize = 0; int updatetotalsize = 0; httpurlconnection httpconnection = NULL; inputstream is = NULL; fileoutputstream Fos = NULL; try {URL url = new URL (DownLoadURL ); httpconnection = (httpurlconnection) URL. openconnection (); httpconnection. s Etrequestproperty ("User-Agent", "pacifichttpclient"); If (currentsize> 0) {httpconnection. setrequestproperty ("range", "bytes =" + currentsize + "-");} httpconnection. setconnecttimeout (10000); httpconnection. setreadtimeout (20000); updatetotalsize = httpconnection. getcontentlength (); If (httpconnection. getresponsecode () = 404) {Throw new exception ("fail! ");} Is = httpconnection. getinputstream (); Fos = new fileoutputstream (SaveFile, false); byte buffer [] = new byte [4096]; int readsize = 0; while (readsize = is. read (buffer)> 0) {FOS. write (buffer, 0, readsize); totalsize + = readsize; // to Prevent the application from being tightened due to frequent notifications, if (downloadcount = 0) is notified only once when the percentage increases by 10) | (INT) (totalsize * 100/updatetotalsize)-10> downloadcount) {downloadcount + = 10; updatenotification. setlatesteven Tinfo (UpdateService. this, "downloading", (INT) totalsize * 100/updatetotalsize + "%", updatependingintent); updatenotificationmanager. Y (0, updatenotification) ;}} finally {If (httpconnection! = NULL) {httpconnection. Disconnect ();} If (is! = NULL) {is. Close () ;}if (FOS! = NULL) {FOS. Close () ;}return totalsize ;}

Display download progress,

After the download is complete, we will prompt you That the download is complete and you can click "Install" to complete the preceding handler.
Define two constants in UpdateService. Java to indicate the download status:

 
// Download Status private final static int download_complete = 0; private final static int download_fail = 1;

Main thread processing based on download status:

Private handler updatehandler = new handler () {@ override public void handlemessage (Message MSG) {Switch (MSG. what) {Case download_complete: // click to install pendingintent uri = Uri. fromfile (updatefile); intent installintent = new intent (intent. action_view); installintent. setdataandtype (Uri, "application/vnd. android. package-Archive "); updatependingintent = pendingintent. getactivity (UpdateService. this, 0, I Nstallintent, 0); updatenotification. defaults = notification. default_sound; // ringtone notification updatenotification. setlatesteventinfo (UpdateService. This, "Shanghai Metro", "Download complete, click to install. ", Updatependingintent); updatenotificationmanager. Y (0, updatenotification); // stop the service stopself (); break; Case download_fail: // download failed updatenotification. setlatesteventinfo (UpdateService. this, "Shanghai Metro", "Download complete, click to install. ", Updatependingintent); updatenotificationmanager. Y (0, updatenotification); break; default: stopself ();}}};

Download complete,

At this point, the file is downloaded and the progress is notified in the notification bar.
I found that I spoke a lot of nonsense. In fact, I have written so many things back and forth, so I am so embarrassed. I will try my best to streamline my post.
PS: attachedCheanupdatefile () Code

 
File updatefile = new file (Global. downloaddir, getresources (). getstring (R. string. app_name) + ". APK "); If (updatefile. exists () {// when not needed, clear the previous downloaded file to avoid wasting user space updatefile. delete ();}

Thank you !!!!

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.