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; } }