Downloading as a service

This allows downloads to exist outside of an activity and is a more robust way to handle potentially long running downloads. This section assumes some knowledge of Android services, see https://developer.android.com/guide/components/services.

Permissions

For Android 9 (API 28) upwards, the app should request the FOREGROUND_SERVICE permission in the manifest.

<manifest>    
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

    <application>
    <!--...-->
    </application>
</manifest>

Managing downloads

The OTVDownloadManager class handles threading, so the service just needs to manage a reference to the OTVDownloadManager instance and relay intents to it, as well as provide notifications on download state.

The OTVDownloadManager need only be instantiated once and shared over an application and service lifecycle. The example code shows a way to allow access to a single download manager by sub-classing the Android application class and providing a getter.

public class DemoApplication extends Application {
  private OTVDownloadManager mDownloadManager;

  /**
   * @return An application wide download manager instance.
   */
  public OTVDownloadManager getDownloadManager() {
    if (mDownloadManager == null) {
      mDownloadManager = new OTVDownloadManager(this);
    }
    return  mDownloadManager;
  }

  //...
}

The download manager will be linked to the application lifecycle, but the service may persist beyond that. To keep the download manager accessible, the service has to run in foreground, see https://developer.android.com/guide/components/services#StartingAService.

Notifications

Actionable notifications must be provided to allow users to interact with downloads without a foreground application. The example code demonstrates how to provide persistent notifications with an attached cancel action to allow users to stop downloads whilst they are in progress.

From Android 8 (API 26) all notifications must be attached to an explicit channel, see https://developer.android.com/training/notify-user/channels.