The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.


Tutorial #16 - Updating the Book

The app is designed to ship a copy of the book’s chapters as assets, so a user can just download one thing and get everything they need: book and reader.

However, sometimes books get updated. This is a bit less likely with the material being used in this tutorial, as it is rather unlikely that H. G. Wells will rise from the grave to amend The War of the Worlds. However, other books, such as Android developer guides written by balding guys, might be updated more frequently.

Most likely, the way you would get those updates is by updating the entire app, so you get improvements to the reader as well. However, another approach would be to be able to download an update to the book as a separate ZIP file. The reader would use the contents of that ZIP file if one has been downloaded, otherwise it will “fall back” to the copy in assets. That is the approach that we will take in this tutorial, to experiment a bit with Internet access and services. Along the way, we will use Retrofit to call a Web service (of sorts) to find out if an update is available.

This is a continuation of the work we did in the previous tutorial.

You can find the results of the previous tutorial and the results of this tutorial in the book’s GitHub repository:

Step #1: Adding a Stub DownloadCheckService

There are a few pieces to our download-the-book-update puzzle:

To address the first puzzle piece — determining if there is an update available — we can use an IntentService. That makes it easy for us to do the work not only in the background from a threading standpoint, but also be able to use it either from the UI or from some sort of background-work scheduler. So, let’s add a DownloadCheckService to our project.

Right-click over the com.commonsware.empublite package in your java/ directory and choose New > Service > “Service (IntentService)” from the context menu. Fill in DownloadCheckService as the class name and uncheck the “helper methods” checkbox. Click Finish to generate the DownloadCheckService class and add an entry for you to the manifest.

Then, replace the generated implementation of DownloadCheckService with:


package com.commonsware.empublite;

import android.app.IntentService;
import android.content.Intent;

public class DownloadCheckService extends IntentService {
  public DownloadCheckService() {
    super("DownloadCheckService");
  }

  @Override
  protected void onHandleIntent(Intent intent) {
  }
}

Step #2: Tying the Service Into the Action Bar

To allow the user to manually request that we update the book (if an update is available), we should add a new action bar item to EmPubLiteActivity.

Right-click over the res/ directory and choose New > Vector Asset from the context menu. Click the Icon button and choose the “Refresh” icon:

Asset Studio Icon Picker, with Refresh Icon Selected
Figure 324: Asset Studio Icon Picker, with Refresh Icon Selected

Click OK to close the icon picker. Change the resource name to ic_refresh_white_24dp. Then click Next and Finish to save this drawable resource.

Once again, this icon will render in black, when we need it to render in white given our theme. Open res/drawable/ic_refresh_white_24dp.xml and change the android:fillColor in the <path> element to be #FFFFFFFF instead of #FF000000:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/>
</vector>

Then, modify the res/menu/options.xml file to include the following <item> element:

  <item
    android:id="@+id/update"
    android:icon="@drawable/ic_refresh_white_24dp"
    android:showAsAction="ifRoom|withText"
    android:title="@string/download_update">
  </item>

Note that this menu definition requires a new string resource, named download_update, with a value like Download Update.

That allows us to add a new case to the switch statement in onOptionsItemSelected() in EmPubLiteActivity:

      case R.id.update:
        startService(new Intent(this, DownloadCheckService.class));

        return(true);

All we do here is send a command to our DownloadCheckService to see if a download is available.

Step #3: Defining Our Event

The preview of this section is [REDACTED].

Step #4: Defining Our JSON

The preview of this section is unavailable right now, but if you leave your name and number at the sound of the tone, it might get back to you (BEEEEEEEEEEEEP!).

Step #5: Defining Our Retrofit Interface

The preview of this section was lost due to a rupture in the space-time continuum.

Step #6: Retrieving Our JSON Via Retrofit

The preview of this section was lost in the sofa cushions.

Step #7: Downloading the Update

The preview of this section is unavailable right now, but if you leave your name and number at the sound of the tone, it might get back to you (BEEEEEEEEEEEEP!).

Step #8: Unpacking the Update

The preview of this section is off trying to sweet-talk the Khaleesi into providing us with a dragon.

Step #9: Using the Update

The preview of this section was lost due to a rupture in the space-time continuum.

In Our Next Episode…

The preview of this section is off trying to sweet-talk the Khaleesi into providing us with a dragon.