All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.coolerfall.download.DownloadRequest Maven / Gradle / Ivy

package com.coolerfall.download;

import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * DownloadRequest: download request, this is designed according to Request in Andoird-Volley.
 * 
 * @author Vincent Cheung
 * @since  Nov. 24, 2014
 */
public class DownloadRequest implements Comparable {
	private static final String TAG = DownloadRequest.class.getSimpleName();

	/** default download directory */
	private static final String DEFAULT_DIR = Environment
			.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
			.getAbsolutePath();

	/**
	 * Bit flag for {@link #setAllowedNetworkTypes} corresponding to
	 * {@link android.net.ConnectivityManager#TYPE_MOBILE}.
	 */
	public static final int NETWORK_MOBILE = 1 << 0;

	/**
	 * Bit flag for {@link #setAllowedNetworkTypes} corresponding to
	 * {@link android.net.ConnectivityManager#TYPE_WIFI}.
	 */
	public static final int NETWORK_WIFI = 1 << 1;

	/** download id of this download request */
	private int mDownloadId = -1;
	
	/** retry time when downloading failed, default is 1 */
	private AtomicInteger mRetryTime = new AtomicInteger(1);

	/** allowed network types, default to all network types allowed */
	private int mAllowedNetworkTypes = 0;

	/** the context used in {@link com.coolerfall.download.DownloadDispatcher} */
	private Context mContext;

	/** the download state */
	private DownloadState mDownloadState;
	
	/** URL of download request */
	private String mUrl;
	
	/** destination file path */
	private String mDestinationFilePath;
	
	/** download request queue */
	private DownloadRequestQueue mDownloadRequestQueue;
	
	/** timestamp of this download request when created */
	private long mTimestamp = System.currentTimeMillis() / 1000;
	
	/** the priority of this download request, normal by default */
	private Priority mPriority = Priority.NORMAL;
	
	/** Whether or not this request has been canceled. */
	private boolean mCanceled = false;
    
	/** download listener */
	private DownloadListener mDownloadListener;

	/* simple download listener */
	private SimpleDownloadListener mSimpleDownloadListener;
	
	/**
	 * Priority values: download request will be processed from 
	 * higher priorities to lower priorities.
	 */
	public enum Priority {
		/**
		 * The lowest priority.
		 */
		LOW,
		/**
		 * Normal priority(default).
		 */
		NORMAL,
		/**
		 * The highest priority.
		 */
		HIGH,
	}
	
	/**
	 * State valuse: this will used to mark the state of download request.
	 */
	protected enum DownloadState {
		/**
		 * State invalid(the request is not in queue).
		 */
		INVALID,
		/**
		 * State when the download is currently pending.
		 */
		PENDING,
		/**
		 * State when the download is currently running.
		 */
		RUNNING,
		/**
		 * State when the download is successful.
		 */
		SUCCESSFUL,
		/**
		 * State when the download is failed.
		 */
		FAILURE,
	}
	
	/**
	 * The default constructor, set the download state as pending.
	 */
	public DownloadRequest() {
		mDownloadState = DownloadState.PENDING;
	}
	
	@Override
	public int compareTo(DownloadRequest other) {
		Priority left = this.getPriority();
		Priority right = other.getPriority();
		
		/*
		 * High-priority requests are "lesser" so they are sorted to the front.
		 * Equal priorities are sorted by timestamp to provide FIFO ordering.
		 */
		return left == right ? 
				(int) (this.mTimestamp - other.mTimestamp) : 
				right.ordinal() - left.ordinal();
	}
	
	/**
	 * Set the priority of this downloader.
	 * 
	 * @param  priority {@link Priority}
	 * @return          this Request object to allow for chaining
	 */
	public DownloadRequest setPriority(Priority priority) {
		mPriority = priority;
		
		return this;
	}
	
	/**
	 * Get the priority of download request.
	 * 
	 * @return {@link Priority},
	 *         {@link Priority#NORMAL} by default.
	 */
	protected Priority getPriority() {
		return mPriority;
	}
	
	/**
	 * Set the download listener.
	 * 
	 * @param  l download listener
	 * @return   this Request object to allow for chaining
	 */
	public DownloadRequest setDownloadListener(DownloadListener l) {
		mDownloadListener = l;
		
		return this;
	}
	
	/**
	 * Get the download listener of this request.
	 * 
	 * @return download listener
	 */
	protected DownloadListener getDownloadListener() {
		return mDownloadListener;
	}

	/**
	 * Set simple download listener.
	 *
	 * @param  sl simple download listener
	 * @return    this Request object to allow for chaining
	 */
	public DownloadRequest setSimpleDownloadListener(SimpleDownloadListener sl) {
		mSimpleDownloadListener = sl;

		return this;
	}

	/**
	 * Get the simple download listener of this request.
	 *
	 * @return simple download listener
	 */
	protected SimpleDownloadListener getSimpleDownloadListener() {
		return mSimpleDownloadListener;
	}
	
	/**
     * Associates this request with the given queue. The request queue will be 
     * notified when this request has finished.
     *
     * @param  queue download request queue
     * @return       this Request object to allow for chaining
     */
	protected DownloadRequest setDownloadQueue(DownloadRequestQueue queue) {
		mDownloadRequestQueue = queue;
		
		return this;
	}
	
	/**
	 * Set download state of this request.
	 * 
	 * @param state download state
	 */
	protected void setDownloadState(DownloadState state) {
		mDownloadState = state;
	}
	
	/**
	 * Get download state of current request.
	 * 
	 * @return download state
	 */
	protected DownloadState getDownloadState() {
		return mDownloadState;
	}
	
	/**
	 * Set download id of this download request.
	 * 
	 * @param  downloadId download id
	 * @return            download request
	 */
	public DownloadRequest setDownloadId(int downloadId) {
		mDownloadId = downloadId;
		
		return this;
	}
	
	/**
	 * Get the download id of this download request.
	 * 
	 * @return download id
	 */
	protected int getDownloadId() {
		return mDownloadId;
	}
	
	/**
	 * Set retry time, the manager will re-download with retry time.
	 * 
	 * @param  retryTime retry time
	 * @return           this Request object to allow for chaining
	 */
	public DownloadRequest setRetryTime(int retryTime) {
		mRetryTime = new AtomicInteger(retryTime);
		
		return this;
	}
	
	/**
	 * Get retry time, the retry time will decrease automatically 
	 * after invoking this method.
	 * 
	 * @return retry time
	 */
	protected int getRetryTime() {
		return mRetryTime.decrementAndGet();
	}

	/**
	 * Restrict the types of networks over which this download may proceed.
	 * By default, all network types are allowed.
	 * Be sure to add permission android.permission.ACCESS_NETWORK_STATE.
	 *
	 * @param  context context
	 * @param  types   any network type
	 * @return         this Request object to allow for chaining
	 */
	public DownloadRequest setAllowedNetworkTypes(Context context, int types) {
		mContext = context;
		mAllowedNetworkTypes = types;

		return this;
	}

	/**
	 * Get the types of allowed network.
	 *
	 * @return all the types
	 */
	protected int getAllowedNetworkTypes() {
		return mAllowedNetworkTypes;
	}

	/**
	 * Get the context.
	 *
	 * @return context
	 */
	protected Context getContext() {
		return mContext;
	}

	/**
	 * Set the URL of this download request.
	 * 
	 * @param  url the url
	 * @return     this Request object to allow for chaining.
	 */
	public DownloadRequest setUrl(String url) {
		if (TextUtils.isEmpty(url)) {
			throw new IllegalArgumentException("url cannot be null");
		}
		
		if (!url.startsWith("http") && !url.startsWith("https")) {
			throw new IllegalArgumentException("can only download 'HTTP/HTTPS' url");
		}
		
		mUrl = url;
		
		return this;
	}
	
	/**
	 * Get the URL of this request.
	 * 
	 * @return the URL of this request
	 */
	protected String getUrl() {
		return mUrl;
	}

	/** get the default download file path */
	private String getDefaultFilePath() {
		return DEFAULT_DIR + File.separator + DownloadUtils.getFilenameFromHeader(mUrl);
	}

	/**
	 * Set destination file path of this download request. This method has deprecated,
	 * use {@link #setDestFilePath} instead.
	 * 
	 * @return download request
	 */
	@Deprecated
	public DownloadRequest setDestinationPath(String filePath) {
		mDestinationFilePath = filePath;
		
		return this;
	}

	/**
	 * Set destination file path of this download request. The file will be createad
	 * according to the file path. This file path must be absolute file
	 * path(such as: /sdcard/test.txt).
	 *
	 * @return  this Request object to allow for chaining.
	 */
	public DownloadRequest setDestFilePath(String filePath) {
		mDestinationFilePath = filePath;

		return this;
	}
	
	/**
	 * Get destination file path of this download request.
	 * 
	 * @return destination file path
	 */
	@SuppressWarnings("ResultOfMethodCallIgnored")
	protected String getDestFilePath() {
		/* if the destination file path is empty, use default file path */
		if (TextUtils.isEmpty(mDestinationFilePath)) {
			mDestinationFilePath = getDefaultFilePath();
		}

		/* if the destination path is directory */
		File file = new File(mDestinationFilePath);
		if (file.isDirectory()) {
			Log.w(TAG, "the destination file path cannot be directory");
			return getDefaultFilePath();
		} else if (!file.getParentFile().exists()) {
			/* make dirs in case */
			file.getParentFile().mkdirs();
		}

		return mDestinationFilePath;
	}

	/**
	 * Get temporary destination file path of this download request.
	 *
	 * @return temporary destination file path
	 */
	protected String getTmpDestinationPath() {
		return getDestFilePath() + ".tmp";
	}
	
	/**
	 * Mark this download request as canceled.  No callback will be delivered.
	 */
	protected void cancel() {
		mCanceled = true;
	}
	
	/**
     * Returns true if this request has been canceled.
     */
	protected boolean isCanceled() {
		return mCanceled;
	}
	
	/**
	 * Notifies the download request queue that this request has finished(succesfully or fail)
	 */
	protected void finish() {
		if (mDownloadRequestQueue != null) {
			mDownloadRequestQueue.finish(this);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy