Android Tutorial Downloading files using Service module

Discussion in 'Tutorials & Examples' started by Erel, Jan 29, 2011.

Thread Status:
Not open for further replies.
  1. Erel

    Erel Administrator Staff Member Licensed User

    It is recommended to use HttpUtils2 instead of this code module. HttpUtils2 is more powerful and is easier to work with.

    As discussed in the Services tutorial, some tasks are easier to implement with services than with activities.
    In this example we will download an image file with a service and use it for the activity background.
    This service can be used to download larger files as well.

    The advantage of a service over activity in this case is that the service isn't paused when the application is in the background.

    The steps required for downloading a file with this service is to first set the URL and the target file (the downloaded file is written to this file) and then call StartService.
    The process global variables are used for passing those values to the service.
    Process global variables can be accessed from all modules and are always available (even when the component is paused).

    The service then downloads the file. When download completes the service uses CallSub to notify the Activity that the download has completed.
    It is possible that the activity is not active when download is complete. In this case CallSub will not do anything. Press on Home button after starting the download to pause the activity.
    We are handling this case in the activity resume event. When the activity resumes we check if we were in the middle of a download task. If yes, then we check the service JobStatus global variable which tells us whether the task has finished.

    In most cases it is better to let the activity pull data from the service than pushing the data to the activity from the service. This way when the activity is ready it can grab the data and work with it.

    If we were to download a large file in the background it is possible that the OS will at some point kill our process to free some memory. This will of course break our download.
    To avoid this issue the service calls Service.StartForeground while downloading. This call marks our process as a foreground process. Which means that it is important not to kill it. A status bar notification is also displayed when the service is in this state.
    You should be careful not to overuse this method and only call it if it is really problematic for your service to be killed.

    When download completes we also check if the activity is currently active. If not we show a status bar notification that notifies the user that download has completed. When the user presses on the notification (by first dragging the status bar downwards) our activity is resumed.

    The program is attached.
    Main activity:
    Code:
    'Activity module
    Sub Process_Globals
        
    Dim image As Bitmap
    End Sub

    Sub Globals
        
    Dim btnDownload As Button
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    Activity.LoadLayout("1")
        
    'check if we already loaded the image previously.
        If image.IsInitialized Then
            
    Activity.SetBackgroundImage(image)
        
    End If
    End Sub

    Sub Activity_Resume
        
    'check if download has finished while the activity was paused
        If btnDownload.Enabled = False AND DownloadService.JobStatus = DownloadService.STATUS_DONE Then
            FinishDownload
        
    End If
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)

    End Sub

    Sub btnDownload_Click
        
    Activity.Color = Colors.Black
        DownloadService.URL = 
    "http://www.basic4ppc.com/basic4android/images/designer1.png"
        DownloadService.Target = 
    File.OpenOutput(File.DirInternalCache, "image.png"False)
        
    StartService(DownloadService)
        btnDownload.Enabled = 
    False
    End Sub

    Sub FinishDownload
        
    'Load the saved image
        If DownloadService.DoneSuccessfully = True Then
            
    image = LoadBitmapSample(File.DirInternalCache, "image.png", _
             
    100%x100%y)
            
    Activity.SetBackgroundImage(image)
        
    End If
        btnDownload.Enabled = 
    True
        DownloadService.JobStatus = DownloadService.STATUS_NONE
    End Sub
    DownloadService service:
    Code:
    'Service module
    Sub Process_Globals
        
    Dim HC As HttpClient
        
    'Activity is expected to set URL
        Dim URL As String
        
    Dim Target As OutputStream
        
    Dim JobStatus As Int
        
    Dim STATUS_NONE, STATUS_WORKING, STATUS_DONE As Int
        STATUS_NONE = 
    0
        STATUS_WORKING = 
    1
        STATUS_DONE = 
    2
        
    Dim DoneSuccessfully As Boolean
        
    Dim Notification1 As Notification
    End Sub
    Sub Service_Create
        HC.Initialize(
    "HC")
        Notification1.Initialize
        Notification1.Icon = 
    "icon" 'use the application icon file for the notification
        Notification1.Vibrate = False
    End Sub

    Sub Service_Start
        
    'URL and Target should be set by the calling module
        Dim request As HttpRequest
        request.InitializeGet(URL)
        HC.Execute(request, 
    1)
        JobStatus = STATUS_WORKING
        Notification1.SetInfo(
    "Download Service example""Downloading: " & URL, Main)
        Notification1.Sound = 
    False
        
    'Make sure that the process is not killed during the download
        'This is important if the download is expected to be long.
        'This will also show the status bar notification
        Service.StartForeground(1, Notification1) 
    End Sub

    Sub HC_ResponseError (Reason As String, StatusCode As Int, TaskId As Int)
        
    ToastMessageShow("Error downloading file: " & Reason, True)
        DoneSuccessfully = 
    False
        Finish
    End Sub

    Sub HC_ResponseSuccess (Response As HttpResponse, TaskId As Int)
        
    'Asynchronously download the stream
        Response.GetAsynchronously("Response", Target, True, TaskId)
    End Sub

    Sub Response_StreamFinish (Success As Boolean, TaskId As Int)
        
    If Success = False Then
            
    ToastMessageShow("Error downloading file: " & LastException.Message, True)
        
    Else
            
    ToastMessageShow("Download successfully."True)
        
    End If
        DoneSuccessfully = Success
        Finish
    End Sub

    Sub Finish
        
    Log("Service finished downloading")
        JobStatus = STATUS_DONE
        
    'Notify the activity that the download has finished.
        'It will do nothing if the activity is currently paused.
        CallSub(Main, "FinishDownload")
        
    Service.StopForeground(1'Return the service to the "background" (also removes the ongoing notification)
        If IsPaused(Main) Then
            
    'The activity is paused. The user is probably busy with some other activity.
            'Notify the user that the download has finished
            Notification1.Sound = True
            Notification1.SetInfo(
    "Download Service""Download complete", Main)
            Notification1.AutoCancel = 
    True
            Notification1.Notify(
    1)
        
    End If
    End Sub
    Sub Service_Destroy

    End Sub
     

    Attached Files:

    ibra939 likes this.
  2. ZJP

    ZJP Active Member Licensed User

    Last edited: Jan 30, 2011
  3. Erel

    Erel Administrator Staff Member Licensed User

    The Flickr Viewer is also not the best example as the user is not likely to leave the activity while the 9 images are downloaded.
    You can however change the URL to point to some other larger file instead (and don't assign it as the activity background).
     
  4. ZJP

    ZJP Active Member Licensed User

    Tx.
     
  5. bluedude

    bluedude Well-Known Member Licensed User

    Great, now one for a multipart upload and we are done :)
     
  6. Erel

    Erel Administrator Staff Member Licensed User

  7. philgoodgood

    philgoodgood Member Licensed User

    hello,

    very good english Erel, "Google translator" was too happy .... and so do i :sign0060:
     
  8. Malky

    Malky Active Member Licensed User

    I am trying to get a simple listview up, but have problems obtaining the image?

    I need to acquire the image, but keep getting an error.

    It is an essential function of my app and I'm pulling my hair out going in circles.

    The httputils2 example seems the best, but like all of them, they just display the image in a background image.

    I hope to store the image files onto the SD card, but returning the image seems to be the problem?

    I've attached the bas file if it helps?

    Malky
     
  9. Erel

    Erel Administrator Staff Member Licensed User

    Please start a new thread and provide more information about your implementation and the error encountered.
     
  10. little3399

    little3399 Active Member Licensed User

    in downloadservice example Notification1.Icon="Icon" the icon file can be change in other file name ? such as myicon ? TKS!
     
  11. DonManfred

    DonManfred Expert Licensed User

    Look at the documentation!
     
  12. Erel

    Erel Administrator Staff Member Licensed User

    I don't recommend you to use the code above. It will be simpler to use HttpUtils2 instead.
     
Thread Status:
Not open for further replies.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice