Android Open Source - com.elsewhat.android.slideshow File Downloader






From Project

Back to project page com.elsewhat.android.slideshow.

License

The source code is released under:

Copyright (C) 2012 Dagfinn Parnas <dagfinn.parnas@gmail.com> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Sof...

If you think the Android project com.elsewhat.android.slideshow listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.elsewhat.android.slideshow.api;
//from   w  w w .  ja v a  2  s  .co m
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

/**
 * Class which is used to download a queue of DownloadableObjects to the file system
 * 
 * 
 * @author dagfinn.parnas
 *
 */
public class FileDownloader {
  protected static final String LOG_PREFIX="Slideshow FileDownloader";
  protected int numberOfThreads=2;
  protected static final int connectionTimeOutSec=20;
  protected static final int socketTimeoutSec=20;
  protected ArrayList<FileDownloaderTask>  downloaderTasks;
  Context context;
  File rootDirectory;
  //this list must be synchronized! See constructor
  List<DownloadableObject> downloadableObjects;
  FileDownloaderListener listener;
  
  private List<String> arDownloadSize;
  
  public FileDownloader(Context context,FileDownloaderListener listener, File rootDirectory,
      List<DownloadableObject> downloadableObjects) {
    super();
    this.context = context;
    this.listener=listener;
    this.rootDirectory = rootDirectory;
    
    //lets make sure the List is synchronized
    this.downloadableObjects = Collections.synchronizedList(downloadableObjects);
    arDownloadSize=Collections.synchronizedList(new ArrayList<String>(300));
  }
  
  /**
   * Listener which is notified when the download is complete or retrieved error
   */
  public interface FileDownloaderListener {
    /*These methods should be synchronized when implemented*/
    void onDownloadCompleted (DownloadableObject downloadableObject);
    void onAllDownloadsCompleted ();
    void onAllDownloadsFailed (String message);
    void onDownloadError (DownloadableObject downloadableObject);
  }
  
  /**
   * Start the download of the files to the file system
   * 
   */
  public void execute(){
    if(!rootDirectory.exists()){
      boolean result =rootDirectory.mkdirs();
      if(result==false){
        String userErrorMsg="Unable to download photos\nFailed to create directory at " +rootDirectory.getAbsolutePath();
        listener.onAllDownloadsFailed(userErrorMsg);
        Log.i("FileDownloader", userErrorMsg);
        return;
      }
    }
    
    downloaderTasks= new ArrayList<FileDownloaderTask>(numberOfThreads);
    for (int i = 0; i < numberOfThreads; i++) {
      FileDownloaderTask downloaderTask = new FileDownloaderTask(i);
      downloaderTasks.add(downloaderTask);
      //start downloading untill the list is empty
      downloaderTask.execute();  
    }
  }
  
  /**
   * Stops the ongoing downloads.
   * If execute() is called after stop() is called it will continue where it was stopped
   * 
   */
  public void stop(){
    
    
    for (Iterator<FileDownloaderTask> iterator = downloaderTasks.iterator(); iterator.hasNext();) {
      FileDownloaderTask downloaderTask = iterator.next();
      if(downloaderTask.isFinished()==false){
        Log.i(LOG_PREFIX, "Stopping ongoing download task");
        downloaderTask.cancel(true);
      }
    }
    
  
  }
  
  /**
   * If there are remaining downloads (used if it is temporarily stopped)
   * 
   * @return
   */
  public boolean hasRemainingDownloads(){
    if(downloadableObjects==null || downloadableObjects.size()==0){
      return false;
    }else {
      return true;
    }
  }
  
  
    /**
     * Asynch task representing a thread which downloads 
     * 
     */
    public class FileDownloaderTask extends AsyncTask<Void, DownloadableObject, Void> {
      boolean hasError=false;


    Throwable throwable;
      String userErrorMsg;
      int threadId;
      boolean isFinished=false;
      
      public FileDownloaderTask(int threadId){
        this.threadId=threadId;
      }
      
    @Override
    protected Void doInBackground(Void... arg0) {
      DefaultHttpClient httpClient = new DefaultHttpClient();
      
      

      while(!downloadableObjects.isEmpty()){
        if(isCancelled()){
          Log.w(LOG_PREFIX,"Async task was cancelled");
          return null;
        }
        try {
          DownloadableObject downloadableObject = downloadableObjects.remove(0);
          String fileUrl = downloadableObject.getUrlStringForDownload();
          String fileName = downloadableObject.getFileName();
                
          //setup the HTTP request
            HttpGet request = new HttpGet(fileUrl);
                HttpParams httpParameters = httpClient.getParams();
                HttpConnectionParams.setConnectionTimeout(httpParameters, connectionTimeOutSec * 1000);
                HttpConnectionParams.setSoTimeout        (httpParameters, socketTimeoutSec * 1000);

          try {
            //perform the HTTP request
                  HttpResponse response = httpClient.execute(request);
                  int responseCode = response.getStatusLine().getStatusCode();
                  //Log.i(LOG_PREFIX, responseCode  + " response code for download of " + fileUrl  );
                  
                  if(responseCode!=200){
                    String message=responseCode  + " was not 200. Will not write to file";
                    Log.w(LOG_PREFIX,  message );
                    downloadableObject.setDownloadFailed(null, message);
                    
                  }else {
                    InputStream is = response.getEntity().getContent();
              
                  //write to file
                    File file = new File(rootDirectory,fileName);
              FileOutputStream f= new FileOutputStream(file);
                    
                    byte[] buffer = new byte[1024];
                    int len1 = 0;
                    while ((len1 = is.read(buffer)) > 0) {                          
                        f.write(buffer, 0, len1);               
                    }       
                    f.close();
                    
                    arDownloadSize.add(file.length()/(1024L) + "KB "+ fileUrl);
                    //Log.d(LOG_PREFIX, file.length()/(1024L) + "KB "+ fileUrl );
                    Log.i(LOG_PREFIX, file.getPath()+ " " +file.getName() + " has been written to the file system" );
                    
                    //this object is now finished, alert the listener
                    publishProgress(downloadableObject);
                  }

                  
          } catch (FileNotFoundException e) {
            downloadableObject.setDownloadFailed(e, "File " + fileName+ " could not be found. Root folder "+rootDirectory );
            publishProgress(downloadableObject);
            Log.w(LOG_PREFIX, e);
          } catch (IOException e) {
            downloadableObject.setDownloadFailed(e, "File " + fileName+ " failed to download due to IOException ");
            publishProgress(downloadableObject);
            Log.w(LOG_PREFIX, e);
          }
  
        }catch (IndexOutOfBoundsException e) {
          Log.w(LOG_PREFIX, " Got IndexOutOfBoundsException most likely due to synchronization issues");
        }
          
        
      }
      
      
      return null;
    }
    
    
    /* (non-Javadoc)
     * @see android.os.AsyncTask#onProgressUpdate(Progress[])
     */
    @Override
    protected void onProgressUpdate(DownloadableObject... values) {
      if(values.length==1){
        DownloadableObject downloadedObject = values[0];
        if(downloadedObject.isDownloadFailed()){
          listener.onDownloadError(downloadedObject);
        }else {
          listener.onDownloadCompleted(downloadedObject);
        }
        
      }else {
        Log.w(LOG_PREFIX, "Unexpected number of DownloadableObject in onProgressUpdate:"+values.length );
      }

      super.onProgressUpdate(values);
    }

    protected boolean isFinished(){
      return isFinished;
    }

    @Override
    protected void onPostExecute(Void result) {
      isFinished=true;

      
      if(threadId==0){//only report this from the first thread
        listener.onAllDownloadsCompleted();
      }
      
    }
    
      /* (non-Javadoc)
     * @see android.os.AsyncTask#onCancelled()
     */
    @Override
    protected void onCancelled() {
      Log.i(LOG_PREFIX, "Download task stopped");
      super.onCancelled();
    }
    }
  
  
  
  

  
}




Java Source Code List

com.elsewhat.android.slideshow.activities.ChromecastAddin.java
com.elsewhat.android.slideshow.activities.ISlideshowInstance.java
com.elsewhat.android.slideshow.activities.SlideshowActivity.java
com.elsewhat.android.slideshow.activities.SlideshowDreamService.java
com.elsewhat.android.slideshow.activities.SlideshowPreferences.java
com.elsewhat.android.slideshow.api.Analytics.java
com.elsewhat.android.slideshow.api.AndroidUtils.java
com.elsewhat.android.slideshow.api.AsyncQueueableObject.java
com.elsewhat.android.slideshow.api.AsyncReadQueue.java
com.elsewhat.android.slideshow.api.CustomGallery.java
com.elsewhat.android.slideshow.api.DeletablePreference.java
com.elsewhat.android.slideshow.api.DownloadableObject.java
com.elsewhat.android.slideshow.api.FileDownloader.java
com.elsewhat.android.slideshow.api.FileUtils.java
com.elsewhat.android.slideshow.api.FlingKeyEvent.java
com.elsewhat.android.slideshow.api.ImageAdapter.java
com.elsewhat.android.slideshow.api.QueueablePhotoObject.java
com.elsewhat.android.slideshow.api.ReadOnlyPreference.java
com.elsewhat.android.slideshow.api.SlideshowBackend.java
com.elsewhat.android.slideshow.api.SlideshowPhotoCached.java
com.elsewhat.android.slideshow.api.SlideshowPhotoDrawable.java
com.elsewhat.android.slideshow.api.SlideshowPhoto.java
com.elsewhat.android.slideshow.backend.FlickrPublicSetBackend.java
com.elsewhat.android.slideshow.backend.OPMLBackend.java
com.elsewhat.android.slideshow.backend.SmugMugRecentBackend.java