Register your application as a DownloadManager BroadcastReceiver
The previous examples received the DownloadManager ACTION_DOWNLOAD_COMPLETE and ACTION_NOTIFICATION_CLICKED broadcasts because we used the RegisterReceiver method to register the Activity or Service as a receiver.
This works fine BUT what to do if you want your application to receive these broadcasts even if it is not running?
The answer is to register your application as a BroadcastReceiver for DownloadManager broadcasts by editing the manifest file.
Now whenever any DownloadManager request completes or a DownloadManager notification is clicked, your application will receive an ACTION_DOWNLOAD_COMPLETE or ACTION_NOTIFICATION_CLICKED broadcast.
You can register your application as a BroadcastReceiver for both or either broadcasts.
Here's the syntax to register your application for both broadcasts:
Code:
AddReceiverText(MyServiceName, <intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
<action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED" />
</intent-filter>)
Whenever a DownloadManager request completes or notification is clicked, the Android OS will start the service name
MyServiceName, so you want to
change that to match the name of your application's service.
In this example code the service to register is named
DownloaderService.
The activity code for this example is identical to the previous
DownloadManager using a service example, the
DownloaderService code is different of course:
Code:
Sub Process_Globals
Dim DOWNLOAD_ADDRESS As String="http://www.b4x.com/android/images/wiki_logo.png"
Dim DOWNLOAD_FILENAME As String="wiki_logo.png"
' DownloadId is a unique identifier assigned by the DownloadManager to this download task
Dim DownloadId As Long
Dim DownloadManager1 As DownloadManager
End Sub
Sub Service_Create
' removed the code to call the DownloadManager RegisterReceiver method
' Utils is a helper code module
If Utils.IsInitialized=False Then
Utils.Initialize(DownloadManager1)
End If
End Sub
Sub Service_Start (StartingIntent As Intent)
Select StartingIntent.Action
Case DownloadManager1.ACTION_DOWNLOAD_COMPLETE
HandleDownloadComplete(StartingIntent)
Case DownloadManager1.ACTION_NOTIFICATION_CLICKED
HandleNotificationClicked(StartingIntent)
Case Else
' the service has not been started by a DownloadManager broadcast
' it must have been started by a button click in the Main Activity
' so we'll start a new download request
Dim DownloadManagerRequest1 As DownloadManagerRequest
DownloadManagerRequest1.Initialize(DOWNLOAD_ADDRESS)
DownloadManagerRequest1.Description="DownloadManager demo"
' save the download to external memory
' note you must manually update your project's manifest file adding android.permission.WRITE_EXTERNAL_STORAGE
DownloadManagerRequest1.DestinationUri="file://"&File.Combine(File.DirRootExternal, DOWNLOAD_FILENAME)
DownloadManagerRequest1.Title=DOWNLOAD_FILENAME
DownloadManagerRequest1.VisibleInDownloadsUi=True
DownloadId=DownloadManager1.Enqueue(DownloadManagerRequest1)
' we can now stop the service, it will be restarted whenever a download request completes
StopService("")
End Select
End Sub
Sub Service_Destroy
' removed the code to call the DownloadManager UnregisterReceiver method
End Sub
Sub HandleDownloadComplete(StartingIntent As Intent)
' the Intent that started this service contains all the info we need
Dim DownloadId1 As Long
DownloadId1=StartingIntent.GetExtra(DownloadManager1.EXTRA_DOWNLOAD_ID)
If DownloadId=DownloadId1 Then
' this is the download request we started
' query the DownloadManager for info on this request
Dim DownloadManagerQuery1 As DownloadManagerQuery
DownloadManagerQuery1.Initialize
DownloadManagerQuery1.SetFilterById(DownloadId)
' you must enable the SQL library to work with the Cursor object
Dim StatusCursor As Cursor
' pass our DownloadManagerQuery to the DownloadManager
StatusCursor=DownloadManager1.Query(DownloadManagerQuery1)
If StatusCursor.RowCount>0 Then
StatusCursor.Position=0
Dim StatusInt As Int
StatusInt=StatusCursor.getInt(DownloadManager1.COLUMN_STATUS)
Log("Download Status = "&Utils.GetStatusText(StatusInt))
If StatusInt=DownloadManager1.STATUS_FAILED OR StatusInt=DownloadManager1.STATUS_PAUSED Then
Dim ReasonInt As Int
ReasonInt=StatusCursor.GetInt(DownloadManager1.COLUMN_REASON)
Log("Status Reason = "&Utils.GetReasonText(ReasonInt))
End If
If StatusInt=DownloadManager1.STATUS_SUCCESSFUL Then
CallSub2(Main, "ShowBitmap", LoadBitmap(File.DirRootExternal, DOWNLOAD_FILENAME))
End If
Else
' always check that the Cursor returned from the DownloadManager Query method is not empty
Log("The DownloadManager has no trace of our request, it could have been cancelled by the user using the Android Downloads app or an unknown error has occurred.")
End If
StatusCursor.Close
StopService("")
End If
End Sub
Sub HandleNotificationClicked(StartingIntent As Intent)
' the Intent that started this service contains all the info we need
Dim DownloadIds() As Long
DownloadIds=StartingIntent.GetExtra(DownloadManager1.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS)
Log("HandleNotificationClicked our download request is: "&DownloadId)
If DownloadIds<>Null Then
Log("DownloadIds length is: "&DownloadIds.Length)
Dim i As Int
For i=0 To DownloadIds.Length-1
Log("DownloadIds("&i&")="&DownloadIds(i))
Next
Else
Log("DownloadIds is Null")
End If
End Sub
The service starts and checks the Intent that started it.
From there it knows whether it has been started to handle a DownloadManager broadcast or whether it was started by the user clicking the Activity Button.
The code is much like the previous example, in this example we have to get the download request id or notifications clicked ids from the Intent that started the service.
In previous examples these ids were passed as parameters to the Event Subs.
You might like to change the URL of the download request to point to a non-existent file and watch the logs to see what's reported.
You could also change the URL to point to a large file to give you time to click the notification - change it to point to a large non-image file and comment out the CallSub2 statement to avoid exceptions when the download completes.
And be sure to start your device's Download app and see all of your download requests listed there - from here you can delete/clear/cancel downloads.
That's the basics of DownloadManager covered.
Next i'll show you how to create a service that is of use in the real world - but first time for a break!
Martin.