Android Tutorial - Network : Download

 Android download file tools

    

//package org.dyndns.warenix.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.os.Environment;
import android.util.Log;

public class DownloadFileTool {

  public String downloadFile(URL url, String saveInDir, String saveAsFilename) {
    return downloadFile(url, saveInDir, saveAsFilename, null);
  }

  public String downloadFile(URL url, String saveInDir,
      String saveAsFilename,
      DownloadProgressListener downloadProgressListener) {

    String sdDrive = Environment.getExternalStorageDirectory()
        .getAbsolutePath();

    // Create one directory
    String fullLocalDirPath = String.format("%s/%s", sdDrive, saveInDir);
    Log.d("warenix", "saved in " + fullLocalDirPath);
    boolean success = (new File(fullLocalDirPath)).mkdirs();
    if (success) {
      Log
          .i("warenix", String.format("created dir[%s]",
              fullLocalDirPath));
    }

    InputStream in = null;
    BufferedOutputStream out = null;
    //
    // String filepath = Environment.getExternalStorageDirectory()
    // .getAbsolutePath();
    String full_local_file_path = String.format("%s/%s", fullLocalDirPath,
        saveAsFilename);
    Log.v("warenix", String.format("of to %s", full_local_file_path));

    try {

      FileOutputStream fos = new FileOutputStream(full_local_file_path);
      BufferedOutputStream bfs = new BufferedOutputStream(fos,
          IO_BUFFER_SIZE);

      int iFileSize = DownloadFileTool.getContentLength(url);
      Log.d("warenix", String.format("going to download file size %d",
          iFileSize));

      in = new BufferedInputStream(url.openStream(), IO_BUFFER_SIZE);

      final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
      out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
      copy(in, out, downloadProgressListener, iFileSize);
      out.flush();
      final byte[] data = dataStream.toByteArray();

      bfs.write(data, 0, data.length);
      bfs.flush();

    } catch (IOException e) {
    } finally {
      closeStream(in);
      closeStream(out);
    }

    return full_local_file_path;
  }

  // helper method
  static int IO_BUFFER_SIZE = 4096;

  private void copy(InputStream in, OutputStream out,
      DownloadProgressListener downloadProgressListener,
      final int iFileSize) throws IOException {
    byte[] b = new byte[IO_BUFFER_SIZE];
    int read;
    int totalDownloaded = 0;
    while ((read = in.read(b)) != -1) {
      totalDownloaded += read;
      Log.d("warenix", String.format("downloaded: %d", totalDownloaded));
      if (downloadProgressListener != null) {
        downloadProgressListener.onReceivedProgressUpdate(
            totalDownloaded, iFileSize);
      }

      out.write(b, 0, read);
    }
  }

  DownloadProgressListener downloadProgressListener;

  private void closeStream(Closeable stream) {
    if (stream != null) {
      try {
        stream.close();
      } catch (IOException e) {
        // android.util.Log.e(LOG_TAG, "Could not close stream", e);
      }
    }
  }

  public interface DownloadProgressListener {
    public void onReceivedProgressUpdate(int totalDownloaded,
        final int fileSize);
  }

  public interface DownloadCompletedListener {
    public void onCompleted(String full_local_file_path);
  }

  public static int getContentLength(URL urlFileLocation) {
    HttpURLConnection connFile = null;
    int iFileSize = -1;
    try {
      connFile = (HttpURLConnection) urlFileLocation.openConnection();
      connFile.setDoInput(true);
      InputStream is = connFile.getInputStream();
      iFileSize = connFile.getContentLength();
      is.close();
      connFile.disconnect();
    } catch (IOException e) {
      e.printStackTrace();
    }

    return iFileSize;
  }

}

Download Manager Demo

  
package app.test;

import java.io.FileInputStream;

import android.app.Activity;
import android.app.DownloadManager;
import android.app.DownloadManager.Request;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.ImageView;

public class Test extends Activity {
  private static final String DL_ID = "downloadId";
  private SharedPreferences prefs;
  private DownloadManager dm;
  private ImageView imageView;
  
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        imageView = new ImageView(this);
        setContentView(imageView);
        prefs = PreferenceManager.getDefaultSharedPreferences(this);
        dm = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
    }
    @Override
    public void onResume() {
      super.onResume();
        if(!prefs.contains(DL_ID)) {
          Uri resource = Uri.parse("http://asdf.com/big.jpg");
          DownloadManager.Request request = new DownloadManager.Request(resource);
          request.setAllowedNetworkTypes(Request.NETWORK_MOBILE | Request.NETWORK_WIFI);
          request.setAllowedOverRoaming(false);
          request.setTitle("Download Sample");
          long id = dm.enqueue(request);
          prefs.edit().putLong(DL_ID, id).commit();
        } else {
          queryDownloadStatus();
        }
        registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }
    @Override
    public void onPause() {
      super.onPause();
      unregisterReceiver(receiver);
    }
    private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
      queryDownloadStatus();
    }
    };
    private void queryDownloadStatus() {
      DownloadManager.Query query = new DownloadManager.Query();
      query.setFilterById(prefs.getLong(DL_ID, 0));
      Cursor c = dm.query(query);
      if(c.moveToFirst()) {
        int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
        Log.d("DM Sample","Status Check: "+status);
        switch(status) {
        case DownloadManager.STATUS_PAUSED:
        case DownloadManager.STATUS_PENDING:
        case DownloadManager.STATUS_RUNNING:
          break;
        case DownloadManager.STATUS_SUCCESSFUL:
          try {
            ParcelFileDescriptor file = dm.openDownloadedFile(prefs.getLong(DL_ID, 0));
            FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(file);
            imageView.setImageBitmap(BitmapFactory.decodeStream(fis));
          } catch (Exception e) {
            e.printStackTrace();
          }
          break;
        case DownloadManager.STATUS_FAILED:
          dm.remove(prefs.getLong(DL_ID, 0));
          prefs.edit().clear().commit();
          break;
        }
      }
    }
}

Using AsyncTask to download a big file

  
package app.test;

import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

class CustomHttpClient {
  private static HttpClient customHttpClient;

  public static synchronized HttpClient getHttpClient() {
    if (customHttpClient != null) {
      return customHttpClient;
    }
    HttpParams params = new BasicHttpParams();
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(params,
        HTTP.DEFAULT_CONTENT_CHARSET);
    HttpProtocolParams.setUseExpectContinue(params, true);

    ConnManagerParams.setTimeout(params, 1000);

    HttpConnectionParams.setConnectionTimeout(params, 5000);
    HttpConnectionParams.setSoTimeout(params, 10000);

    SchemeRegistry schReg = new SchemeRegistry();
    schReg.register(new Scheme("http", PlainSocketFactory
        .getSocketFactory(), 80));
    schReg.register(new Scheme("https",
        SSLSocketFactory.getSocketFactory(), 443));
    ClientConnectionManager conMgr = new ThreadSafeClientConnManager(
        params, schReg);

    customHttpClient = new DefaultHttpClient(conMgr, params);
    return customHttpClient;

  }
}

class DownloadImageTask extends AsyncTask<String, Integer, Bitmap> {
  private Context mContext;

  DownloadImageTask(Context context) {
    mContext = context;
  }
  protected void onPreExecute() {
  }
  protected Bitmap doInBackground(String... urls) {
    Log.v("doInBackground", "doing download of image");
    return downloadImage(urls);
  }
  protected void onProgressUpdate(Integer... progress) {
    Log.v("onProgressUpdate", "Progress so far: " + progress[0]);
  }

  protected void onPostExecute(Bitmap result) {
  }

  private Bitmap downloadImage(String... urls) {
    HttpClient httpClient = CustomHttpClient.getHttpClient();
    try {
      HttpGet request = new HttpGet(urls[0]);
      HttpParams params = new BasicHttpParams();
      HttpConnectionParams.setSoTimeout(params, 60000); // 1 minute
      request.setParams(params);

      publishProgress(25);

      HttpResponse response = httpClient.execute(request);

      publishProgress(50);

      byte[] image = EntityUtils.toByteArray(response.getEntity());

      publishProgress(75);

      Bitmap mBitmap = BitmapFactory.decodeByteArray(image, 0,
          image.length);

      publishProgress(100);

      return mBitmap;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
}

public class Test extends Activity {
  private DownloadImageTask diTask;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
  }

  public void doClick(View view) {
    if (diTask != null) {
      AsyncTask.Status diStatus = diTask.getStatus();
      Log.v("doClick", "diTask status is " + diStatus);
      if (diStatus != AsyncTask.Status.FINISHED) {
        Log.v("doClick", "... no need to start a new task");
        return;
      }
    }
    diTask = new DownloadImageTask(this);
    diTask.execute("http://aBigFile");
  }
}

Using DownloadManager

  
package app.test;

import android.app.Activity;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class Test extends Activity {
    protected static final String TAG = "DownloadMgr";
  private DownloadManager dMgr;
  private TextView tv;
  private long downloadId;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv = (TextView)findViewById(R.id.tv);
    }

    @Override
    protected void onResume() {
      super.onResume();
      dMgr = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
    }

    public void doClick(View view) {
      DownloadManager.Request dmReq = new DownloadManager.Request(
            Uri.parse("http://aBigFile.zip"));
      dmReq.setTitle("Platform Tools");
      dmReq.setDescription("Download for Linux");
      dmReq.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE);

        IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        registerReceiver(mReceiver, filter);
      downloadId = dMgr.enqueue(dmReq);
      tv.setText("Download started... (" + downloadId + ")");
    }

    public BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            Bundle extras = intent.getExtras();
            long doneDownloadId =
              extras.getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
            tv.setText(tv.getText() + "\nDownload finished (" +
              doneDownloadId + ")");
            if(downloadId == doneDownloadId)
                Log.v(TAG, "Our download has completed.");
        }
    };

    @Override
    protected void onPause() {
      super.onPause();
      unregisterReceiver(mReceiver);
      dMgr = null;
    }
}

Download Task

  

/**
 *
 */
//package org.alldroid.forum.net;

import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;


import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

import android.os.Bundle;

/**
 * @author trr4rac
 *
 */
 abstract class OnDownloadTaskCompletedListener<T> {
  private DownloadTask<T> task;
  private Bundle state;
  private Object tag;

  public OnDownloadTaskCompletedListener ( DownloadTask<T> task ) {
    this(task,null);
  }

  public OnDownloadTaskCompletedListener ( DownloadTask<T> task, Bundle state ) {
    this(task,state,null);
  }

  public OnDownloadTaskCompletedListener ( DownloadTask<T> task, Bundle state, Object tag ) {
    this.setTask ( task );
    this.setState(state);
    this.setTag ( tag );
  }

  public abstract void onCompletion ( T t ) throws Exception;

  /**
   * @param task the task to set
   */
  protected void setTask ( DownloadTask<T> task ) {
    this.task = task;
  }
  /**
   * @return the task
   */
  public DownloadTask<T> getTask ( ) {
    return task;
  }
  /**
   * @param state the state to set
   */
  public void setState ( Bundle state ) {
    this.state = state;
  }
  /**
   * @return the state
   */
  public Bundle getState ( ) {
    return state;
  }

  /**
   * @param tag the tag to set
   */
  public void setTag ( Object tag ) {
    this.tag = tag;
  }

  /**
   * @return the tag
   */
  public Object getTag ( ) {
    return tag;
  }
}

/**
 * @author trr4rac
 */
 abstract class DownloadTask<T> extends AsyncTask<HttpUriRequest, Integer, T> {

  private static final String TAG = DownloadTask.class.getSimpleName ( );
  private OnDownloadTaskCompletedListener<T> listener;
  private DefaultHttpClient httpClient;
  private UsernamePasswordCredentials credentials;
  private CookieStore cookieStore;
  private Exception executionException;

  public DownloadTask ( ) {

  }

  @Override
  protected void onPostExecute ( T result ) {
    if ( getOnDownloadTaskCompletedListener ( ) != null ) {
      try {
        Log.d(TAG,"notifying completed listener");
        getOnDownloadTaskCompletedListener ( ).onCompletion ( result );
      } catch ( Exception ex ) {
        this.setExecutionException ( ex );
        Log.e ( TAG, ex.getMessage ( ), ex );
      }
    } else {
      Log.w ( TAG, "listener was not set" );
    }
  }

  /*
   * (non-Javadoc)
   * @see android.os.AsyncTask#doInBackground(Params[])
   */
  @Override
  protected abstract T doInBackground ( HttpUriRequest... requests );

  public void setOnDownloadTaskCompletedListener ( OnDownloadTaskCompletedListener<T> l ) {
    this.listener = l;
  }

  public OnDownloadTaskCompletedListener<T> getOnDownloadTaskCompletedListener ( ) {
    return listener;
  }

  /**
   * @return the httpClient
   */
  protected DefaultHttpClient getHttpClient ( HttpUriRequest request ) {
    if ( request == null ) { throw new NullPointerException ( "request parameter cannot be null" ); }

    DefaultHttpClient httpClient = new DefaultHttpClient ( );
    if ( this.getCredentials ( ) != null ) {
      httpClient.getCredentialsProvider ( ).setCredentials ( new AuthScope ( request.getURI ( ).getHost ( ), request.getURI ( ).getPort ( ) ), this.getCredentials ( ) );
    }

    if ( this.getCookieStore ( ) != null ) {
      httpClient.setCookieStore ( this.getCookieStore ( ) );
    }

    return httpClient;
  }

  /**
   * @param credentials
   *          the credentials to set
   */
  public void setCredentials ( UsernamePasswordCredentials credentials ) {
    this.credentials = credentials;
  }

  /**
   * @return the credentials
   */
  public UsernamePasswordCredentials getCredentials ( ) {
    return credentials;
  }

  /**
   * @param cookieStore
   *          the cookieStore to set
   */
  public void setCookieStore ( CookieStore cookieStore ) {
    this.cookieStore = cookieStore;
  }

  /**
   * @return the cookieStore
   */
  public CookieStore getCookieStore ( ) {
    return cookieStore;
  }

  /**
   * @param httpClient the httpClient to set
   */
  public void setHttpClient ( DefaultHttpClient httpClient ) {
    this.httpClient = httpClient;
  }

  /**
   * @return the httpClient
   */
  public DefaultHttpClient getHttpClient ( ) {
    return httpClient;
  }

  /**
   * @param executionException the executionException to set
   */
  protected void setExecutionException ( Exception executionException ) {
    this.executionException = executionException;
  }

  /**
   * @return the executionException
   */
  public Exception getExecutionException ( ) {
    return executionException;
  }

}

File Download Service


//package org.andlib.helpers;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.logging.Logger;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.IBinder;
import android.widget.RemoteViews;


 abstract class FileDownloadService extends Service
{
  public static final int SERVICE_ID = 0x101104;
  public static final int BYTES_BUFFER_SIZE = 32 * 1024;

  private NotificationManager notificationManager;
  private final IBinder binder = new FileDownloadBinder();
  private AsyncDownloadTask task = null;

  protected static boolean isRunning = false;

    public class FileDownloadBinder extends Binder
    {
      FileDownloadService getService()
      {
            return FileDownloadService.this;
        }
    }

    /**
     * 
     * @return if service is running or not
     */
    public static boolean isRunning()
    {
      return isRunning;
    }

  @Override
  public void onCreate()
  {
    if(isRunning)
      return;
    else
      isRunning = true;

    notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

    //start downloading immediately
    task = new AsyncDownloadTask();
    task.execute();

  //  Logger.v("service created");
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId)
  {
    return START_STICKY;
  }

  @Override
  public void onDestroy()
  {
    if(task != null)
    {
      if(!task.isCancelled())
        task.cancel(true);
    }

    isRunning = false;
    
  //  Logger.v("service destroyed");
  }


  @Override
  public IBinder onBind(Intent intent)
  {
    return binder;
  }

  abstract protected Class<?> getIntentForLatestInfo();
  

  abstract protected int getNotificationFlag();

  abstract protected HashMap<String, String> getTargetFiles();


  abstract protected void onFinishDownload(int successCount, HashMap<String, String> failedFiles);

  /**
   * 
   * @return
   */
  abstract protected int getNotificationIcon();


  protected RemoteViews getProgressView(int currentNumFile, int totalNumFiles, int currentReceivedBytes, int totalNumBytes)
  {
    return null;
  }

  /**
   * 
   * @param title
   * @param content
   */
  protected void showNotification(String ticker, String title, String content)
  {
    Notification notification = new Notification(getNotificationIcon(), ticker, System.currentTimeMillis());
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, getIntentForLatestInfo()), Intent.FLAG_ACTIVITY_CLEAR_TOP);
    notification.setLatestEventInfo(getApplicationContext(), title, content, contentIntent);
    notification.flags = getNotificationFlag();
    
    notificationManager.notify(SERVICE_ID, notification);
  }

  /**
   * 
   * @param remoteView
   * @param ticker
   */
  protected void showNotification(RemoteViews remoteView, String ticker)
  {
    Notification notification = new Notification(getNotificationIcon(), ticker, System.currentTimeMillis());
    notification.contentView = remoteView;
    notification.contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, getIntentForLatestInfo()), Intent.FLAG_ACTIVITY_CLEAR_TOP);
    notification.flags = getNotificationFlag();
    
    notificationManager.notify(SERVICE_ID, notification);
  }

  /**
   * override this function to alter socket connect timeout value
   * @return
   */
  protected int getConnectTimeout()
  {
    return 1000;
  }

  /**
   * override this function to alter socket read timeout value
   * @return
   */
  protected int getReadTimeout()
  {
    return 1000;
  }

  private class AsyncDownloadTask extends AsyncTask<Void, Void, Void>
  {
    private int successCount;
    private int numTotalFiles;
    private HashMap<String, String> targetFiles = null;
    private HashMap<String, String> failedFiles = null;

    @Override
    protected void onPreExecute()
    {
      super.onPreExecute();

      successCount = 0;

      targetFiles = getTargetFiles();
      numTotalFiles = targetFiles.size();
      failedFiles = new HashMap<String, String>();
    }

    /**
     * get file's size at given url (using http header)
     * 
     * @param url
     * @return -1 when failed
     */
    public  int getFileSizeAtURL(URL url)
    {
      int filesize = -1;
      try
      {
          HttpURLConnection http = (HttpURLConnection)url.openConnection();
          filesize = http.getContentLength();
          http.disconnect();
      }
      catch(Exception e)
      {
        //Logger.e(e.toString());
      }
        return filesize;
    }
    /* (non-Javadoc)
     * @see android.os.AsyncTask#doInBackground(Params[])
     */
    @Override
    protected Void doInBackground(Void... params)
    {
      String remoteFilepath, localFilepath;
      for(Entry<String, String> entry: targetFiles.entrySet())
      {
        remoteFilepath = entry.getKey();
        localFilepath = entry.getValue();
        
      //  Logger.v("downloading: '" + remoteFilepath + "' => '" + localFilepath + "'");

        try
        {
          if(isCancelled())
            return null;

          URL url = new URL(remoteFilepath);
          int filesize = getFileSizeAtURL(url);
          
          int loopCount = 0;
          if(filesize > 0)
          {
            URLConnection connection = url.openConnection();
            connection.setConnectTimeout(getConnectTimeout());
            connection.setReadTimeout(getReadTimeout());

            BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
            FileOutputStream fos = new FileOutputStream(new File(localFilepath));
            int bytesRead, totalBytesRead = 0;
            byte[] bytes = new byte[BYTES_BUFFER_SIZE];
            String progress, kbytes;
            while(!isCancelled() && (bytesRead = bis.read(bytes)) != -1)
            {
              totalBytesRead += bytesRead;
              fos.write(bytes, 0, bytesRead);

              //don't show notification too often
              if(!isCancelled() && loopCount++ % 20 == 0)
              {
                RemoteViews progressView = getProgressView(successCount + 1, numTotalFiles, totalBytesRead, filesize);
                if(progressView == null)
                {
                  progress = String.format("Download Progress (%d / %d)", successCount + 1, numTotalFiles);
                  kbytes = String.format("%s / %s", getStringByteSize(totalBytesRead), getStringByteSize(filesize));

                  if(!isCancelled())
                    showNotification("Downloading File(s)", progress , kbytes);
                }
                else
                {
                  if(!isCancelled())
                    showNotification(progressView, "Downloading File(s)");
                }
              }
            }
            fos.close();
            bis.close();
            
            if(isCancelled())
              return null;
            
            successCount ++;
          }
          else
          {
        //    Logger.i("file size unknown for remote file: " + remoteFilepath);
            
            failedFiles.put(remoteFilepath, localFilepath);
          }
        }
        catch(Exception e)
        {
      //    Logger.e(e.toString());

          showNotification("Download Failed", "Download Progress", "Failed: " + (new File(remoteFilepath)).getName());
          
          failedFiles.put(remoteFilepath, localFilepath);
        }
      }
      return null;
    }

    @Override
    protected void onCancelled()
    {
      super.onCancelled();
      
    //  Logger.v("download task cancelled");
      
      showNotification("Download Cancelled", "Download Progress", "Cancelled");
    }

    @Override
    protected void onPostExecute(Void result)
    {
      super.onPostExecute(result);
      
      onFinishDownload(successCount, failedFiles);

      String finished;
      if(successCount != numTotalFiles)
        finished = String.format("Finished (%d download(s) failed)", numTotalFiles - successCount);
      else
        finished = "Finished";
      showNotification("Download Finished", "Download Progress", finished);
      
    //  Logger.v("download task finished");
    }
  }


  protected String getStringByteSize(int size)
  {
    if(size > 1024 * 1024)  //mega
    {
      return String.format("%.1f MB", size / (float)(1024 * 1024));
    }
    else if(size > 1024)  //kilo
    {
      return String.format("%.1f KB", size / 1024.0f);
    }
    else
    {
      return String.format("%d B");
    }
  }
}

Cacheable Downloader

  
//package com.jeffcai.joyreader.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLConnection;
import java.util.HashMap;

public class CacheableDownloader {
  
  private CacheableDownloader() {
    cache = new HashMap<String, byte[]>();
    HttpURLConnection.setFollowRedirects(true);
  }
  
  public String getContentAsString(String url) throws IOException {

    byte[] content = null;

    if (cache.containsKey(url)) {
      content = cache.get(url);
    } else {
      content = downloadContent(url);
      cache.put(url, content);
    }

    try {
      // TODO: Always UTF8 Now
      return new String(content, "utf-8");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }

    return "";
  }
  
  public byte[] getContentAsByteArray(String url) throws IOException {

    byte[] content = null;

    if (cache.containsKey(url)) {
      content = cache.get(url);
    } else {
      content = downloadContent(url);
      cache.put(url, content);
    }

    return content;
  }

  public static CacheableDownloader getInstacne() {
    if (instance == null) {
      instance = new CacheableDownloader();
    }
    
    return instance;
  }
  
  private byte [] downloadContent(String url) throws IOException {    
    URI u = null;
    
    try {
      u = new URI(url);
    } catch (URISyntaxException e) {
    }
    
    //Proxy proxy = new Proxy(Type.SOCKS, new InetSocketAddress("137.117.15.37",8080));    
    URLConnection conn = u.toURL().openConnection();
    //conn.connect();
    
    InputStream is = (InputStream) conn.getContent();
    
    byte[] buf = new byte[1024];
    
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    
    int cnt = 0;
    while ((cnt = is.read(buf)) != -1) {
      os.write(buf,0,cnt);
    }
    
    return os.toByteArray();
  }
  
  private static CacheableDownloader instance;
  
  private HashMap<String, byte []> cache; 
}
Download Manager
//package com.determinato.feeddroid.util;

import java.util.Collection;
import java.util.concurrent.ConcurrentLinkedQueue;

import android.os.Handler;

public class DownloadManager {
  private static final String TAG = "DownloadManager";
  private static final int TIMEOUT = 8000;
  
  private Handler mHandler;
  
  private ConcurrentLinkedQueue<DownloadWrapper> mThreads =
    new ConcurrentLinkedQueue<DownloadWrapper>();
  
  private ConcurrentLinkedQueue<Runnable> mQueue =
    new ConcurrentLinkedQueue<Runnable>();
  
  public DownloadManager(Handler handler) {
    mHandler = handler;
  }
  
  public boolean schedule(Runnable r) {
    mQueue.add(r);
    
    if (mThreads.size() == 0) {
      mHandler.removeCallbacks(mWakeUp);
      mWakeUp.run();
      return true;
    }
    
    return false;
  }
  
  private Runnable mWakeUp = new Runnable() {
    public void run() {
      Runnable r = mQueue.poll();
      
      if (r == null) {
        // Woke up with noting to do.
        return;
      } 
      
      for (DownloadWrapper t: mThreads) {
        t.tooSlow();
      }
      
      DownloadWrapper t = new DownloadWrapper(mThreads, mHandler, r);
      mThreads.add(t);
      t.start();
      
      mHandler.removeCallbacks(this);
      mHandler.postDelayed(this, TIMEOUT);
      
      
    }
  };
  
  private class DownloadWrapper extends Thread {
    Collection<DownloadWrapper> mThreads;
    Handler mHandler;
    Runnable mWrapped;
    
    private boolean mTooSlow = false;
    
    public DownloadWrapper(Collection<DownloadWrapper> active, Handler handler, Runnable wrap) {
      mThreads = active;
      mHandler = handler;
      mWrapped = wrap;
    }
    
    public void tooSlow() {
      mTooSlow = true;
    }
    
    public void run() {
      mWrapped.run();
      
      mThreads.remove(this);
      
      if (!mTooSlow) {
        mHandler.removeCallbacks(mWakeUp);
        mHandler.post(mWakeUp);
      }
    }
  }
}

Book Downloader

  
//package org.sergy.libclient.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;

class BookDownloader extends Thread {
  public final static String KEY_SIZE = "size";
  public final static String KEY_STATE = "state";
  public final static String KEY_CURRENT = "current";
  public final static String KEY_MESSAGE = "message";
  
  //Donload process states
  public final static int CONNECTING = 0;
  public final static int DOWLOADING = 1;
  public final static int FINISHED = 2;
  public final static int ERROR = 3;
  public final static int ERROR_BAD_FILE_RETURNED = 4;
  public final static int ERROR_RESPONSE_CODE = 5;
  
  
  
  private final static int BUF_SIZE = 1024 * 10; //kb
  //private final static String LIB_URL = "http://lib.rus.ec/b/";
  private final static String LIB_URL = "http://flibusta.net/b/";
  private final static String DIR = "Books";
  private final static String EXTENSION = "zip";
  private final static int SLEEP_ON_ERROR = 2000; //Sleep before exit in error.
  
  private String url;
  private Handler handler;
  
  public BookDownloader(long id, String format, Handler handler) throws IOException {
    url = LIB_URL + String.valueOf(id) + "/" + format;
    this.handler=handler;
  }
  
  @Override
  public void run() {
    sendMessage(CONNECTING, "", 0, -1);
    
    BufferedInputStream in = null;
    BufferedOutputStream bout = null;
    FileOutputStream fos = null;
    HttpURLConnection connection = null;
    try {
      URL httpUrl = new URL(url);
      HttpURLConnection.setFollowRedirects(true);
      connection = (HttpURLConnection)httpUrl.openConnection();
      connection.setInstanceFollowRedirects(true);
      connection.connect();
      int resopnseCode = connection.getResponseCode();
      
      if (resopnseCode == HttpURLConnection.HTTP_OK) {
        String fname  = getFileName(connection.getURL().toString());
        String ext = getFileExtension(fname);
        int size = connection.getContentLength();
        File root = Environment.getExternalStorageDirectory();
        in = new BufferedInputStream(connection.getInputStream());
        
        if (EXTENSION.equalsIgnoreCase(ext)) {
          File dir = new File(root, DIR);
          dir.mkdirs();
          File file = new File(dir, fname);
          fos = new FileOutputStream(file);

          bout = new BufferedOutputStream(fos, BUF_SIZE);
          byte data[] = new byte[BUF_SIZE];
          int total = 0;
          int current = 0;
          
          sendMessage(DOWLOADING, fname, size, total);
          
          while((current = in.read(data,0,BUF_SIZE)) >=0) {
            bout.write(data, 0, current);
            
            total += current;
            sendMessage(DOWLOADING, fname, size, total);
          }
          
        } else {
          sendMessage(ERROR_BAD_FILE_RETURNED, connection.getURL().toString(), 0, -1);
          sleep(SLEEP_ON_ERROR);
        }
      } else {
        sendMessage(ERROR_RESPONSE_CODE, connection.getResponseMessage(), 0, -1);
        sleep(SLEEP_ON_ERROR);
      }
          
    } catch (MalformedURLException e) {
      sendExceptionMessage(e);
    } catch (IOException e) {
      sendExceptionMessage(e);
    } catch (Exception e) {
      e.printStackTrace();
    }finally {
      if (bout != null) {
        try {
          bout.close();
          fos.close();
        } catch (IOException e) {
          sendExceptionMessage(e);
        }
      }
      if (in != null) {
        try {
          in.close();
        } catch (IOException e) {
          sendExceptionMessage(e);
        }
      }
      
      sendMessage(FINISHED, "", 0, -1);
      if (connection != null) {
        connection.disconnect();
      }
      
      
    }
    
  }
  
  private void sendExceptionMessage(Exception e) {
    sendMessage(ERROR, e.getClass() + ":" + e.getMessage(), 0, -1);
    try {
      sleep(SLEEP_ON_ERROR);
    } catch (InterruptedException e1) {
    }
  }
  
  private void sendMessage(int state, String message, int size, int current) {
    Message msg = handler.obtainMessage();
        Bundle b = new Bundle();
        b.putInt(KEY_STATE, state);
        b.putString(KEY_MESSAGE, message);
        b.putInt(KEY_SIZE, size);
        b.putInt(KEY_CURRENT, current);
        msg.setData(b);
        handler.sendMessage(msg);
  }
  
  /**
   * Returns part of path after last '/'
   * @param path
   * @return
   */
  private String getFileName(String path) {
    return path != null ? path.substring(path.lastIndexOf('/') + 1) : null;
  }
  
  /**
   * Returns file extension
   * @param fname
   * @return
   */
  private String getFileExtension(String fname) {
    return fname != null ? fname.substring(fname.lastIndexOf(".") + 1) : null;
  }
}

download File

  
//package org.dyndns.warenix.util;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.os.Environment;
import android.util.Log;

class DownloadFileTool {

  public String downloadFile(URL url, String saveInDir, String saveAsFilename) {
    return downloadFile(url, saveInDir, saveAsFilename, null);
  }

  public String downloadFile(URL url, String saveInDir,
      String saveAsFilename,
      DownloadProgressListener downloadProgressListener) {

    String sdDrive = Environment.getExternalStorageDirectory()
        .getAbsolutePath();

    // Create one directory
    String fullLocalDirPath = String.format("%s/%s", sdDrive, saveInDir);
    Log.d("warenix", "saved in " + fullLocalDirPath);
    boolean success = (new File(fullLocalDirPath)).mkdirs();
    if (success) {
      Log
          .i("warenix", String.format("created dir[%s]",
              fullLocalDirPath));
    }

    InputStream in = null;
    BufferedOutputStream out = null;
    //
    // String filepath = Environment.getExternalStorageDirectory()
    // .getAbsolutePath();
    String full_local_file_path = String.format("%s/%s", fullLocalDirPath,
        saveAsFilename);
    Log.v("warenix", String.format("of to %s", full_local_file_path));

    try {

      FileOutputStream fos = new FileOutputStream(full_local_file_path);
      BufferedOutputStream bfs = new BufferedOutputStream(fos,
          IO_BUFFER_SIZE);

      int iFileSize = DownloadFileTool.getContentLength(url);
      Log.d("warenix", String.format("going to download file size %d",
          iFileSize));

      in = new BufferedInputStream(url.openStream(), IO_BUFFER_SIZE);

      final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
      out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
      copy(in, out, downloadProgressListener, iFileSize);
      out.flush();
      final byte[] data = dataStream.toByteArray();

      bfs.write(data, 0, data.length);
      bfs.flush();

    } catch (IOException e) {
    } finally {
      closeStream(in);
      closeStream(out);
    }

    return full_local_file_path;
  }

  // helper method
  static int IO_BUFFER_SIZE = 4096;

  private void copy(InputStream in, OutputStream out,
      DownloadProgressListener downloadProgressListener,
      final int iFileSize) throws IOException {
    byte[] b = new byte[IO_BUFFER_SIZE];
    int read;
    int totalDownloaded = 0;
    while ((read = in.read(b)) != -1) {
      totalDownloaded += read;
      Log.d("warenix", String.format("downloaded: %d", totalDownloaded));
      if (downloadProgressListener != null) {
        downloadProgressListener.onReceivedProgressUpdate(
            totalDownloaded, iFileSize);
      }

      out.write(b, 0, read);
    }
  }

  DownloadProgressListener downloadProgressListener;

  private void closeStream(Closeable stream) {
    if (stream != null) {
      try {
        stream.close();
      } catch (IOException e) {
        // android.util.Log.e(LOG_TAG, "Could not close stream", e);
      }
    }
  }

  public interface DownloadProgressListener {
    public void onReceivedProgressUpdate(int totalDownloaded,
        final int fileSize);
  }

  public interface DownloadCompletedListener {
    public void onCompleted(String full_local_file_path);
  }

  public static int getContentLength(URL urlFileLocation) {
    HttpURLConnection connFile = null;
    int iFileSize = -1;
    try {
      connFile = (HttpURLConnection) urlFileLocation.openConnection();
      connFile.setDoInput(true);
      InputStream is = connFile.getInputStream();
      iFileSize = connFile.getContentLength();
      is.close();
      connFile.disconnect();
    } catch (IOException e) {
      e.printStackTrace();
    }

    return iFileSize;
  }

}