FMX.Android Download Service Sample
This demo shows an Android application using an Android Service to download an image from the Internet. The Android Service works as a background task, even if the main application is not running.
When the image file is downloaded to the device, a notification is presented. Handling the notification loads the image previously downloaded.
The service stops itself after performing the download process.
You can find the Download Service Demo sample project at:
- Start | Programs | Appmethod 1.16 | Samples, and then navigate to:
Object Pascal\Multi-Device Samples\Device Sensors and Services\DownloadServiceDemo
- Subversion Repository:
This sample demonstrates how to create and use a local Android service to handle asynchronous requests on demand, using intents.
The demo is prepared to manage several requests using a different thread for each one. When the service is destroyed all the threads are freed.
How to Use the Sample
To open the projects:
- Navigate to the location given above.
- Open the sample application group project file: DownloadServiceDemo.groupproj.
To compile the Android Service:
- Select libDownloadService.so on the Project Manager.
- Right-click to select Compile.
- Note: Compiling the project generates the files that you need to add to the main application.
To add the Android Service to the main application:
- Select DownloadImage on the Project Manager.
- Expand the Target Platforms node.
- Select the Android device.
- Right-click on the Android device, and select Add Android Service.
- Select the location to
C:\Users\Public\Documents\Studio\16.0\Samples\Object Pascal\Multi-Device Samples\Device Sensors and Services\DownloadServiceDemo\DownloadService.
- Note: Check that the location contains two folders: Android and JavaClasses.
- Click Next.
- Note: Check that the location to these files is added: libDownloadService.so, DownloadService.jar, and DownloadServiceUnit.pas.
- Click Finish.
- Remove the DownloadServiceUnit form the DownloadImage project.
- Press F9 or choose Run > Run to deploy the application to an Android device.
Using the Application
- To start the service, on the application, click Download.
- The download process starts.
- When the download finishes, a notification is presented in the screen.
- Click the notification to trigger the OnReceiveLocalNotification event of the TNotificationCenter from the main application.
- After handling the notification, the image is loaded to the TImage of the form.
- Click Delete File to clear the bitmap of the TImage.
The sample consists of a multi-device application with a local service. The main activity starts the local service with an intent that contains the name of the service and the data.
The service runs in the background and remains active even if the main activity is killed. The service starts the downloading process in an anonymous thread. The demo is designed to hold more than one downloading process at the same time. There is an array of threads and each thread is removed after the downloading process finishes. The service stops after the last download ends. The array of threads is freed when the service is destroyed.
Once the download is completed, a notification is created and presented immediately. When the notification is handled in the activity, the download image is loaded in the main form.
IntentServiceUnit is a helper unit where the intent structure is defined with the properties and functions.
TIntentServiceHelper class contains properties and functions to create the intent.
class function TIntentServiceHelper.Create(const AServiceName: string; Code: Integer; Data: string): TIntentServiceHelper;
This function creates an intent with the service name, code and data passed as arguments. The main application calls this function to create the intent.
- To add properties to the intent, it uses putextra.
- To assign the parameters to the intent, to start the service, it uses setclass defining where the service is, and which service to launch.
- It uses getPackageName() to get the name of the local package. For a remote service you need to set the package name explicitly.
- It takes the name of the service as the second argument.
class function TIntentServiceHelper.Create(const Intent: JIntent): TIntentServiceHelper;
This function gets the code and data from the intent passed as an argument. The Service calls this function to extract the information from the intent received from the main application. To extract the code it uses getIntExtra, to extract the path to the file it uses getStringExtra.
The Download Service is an Android Service project. The type of the service is local.
The Data Module has a TNotificationCenter component.
The service starts by clicking Download in the main application. The OnClick event calls StartService(<service_intent>). The intent service structure is declared in a class created in IntentServiceUnit.pas. The intent service is composed by the service_name, a code, and the URL + the <file_name>.
The OnStartCommand event from the Data Module triggers when the service starts. It creates an anonymous thread starting the downloading process with a StartId.
The OnCreate event creates the arrays of threads to manage more than one download process for the same service.
The OnDestroy event frees the arrays of threads.
Download Image App
The Download Image app is a multi-device application. It has a TNotificationCenter component to manage the received notification.
The Download button creates the intent with the URL + filename from the TEdit, and the service name DownloadService. It also starts the service.
The Delete button clears the TBitmap from the TImage and disables the Button.
The sample uses Built-in Java libraries for Android.