package com.android.volley.toolbox; import android.os.Environment; import android.os.StatFs; import android.text.TextUtils; import com.android.volley.FileError; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.VolleyLog; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; /** * Created by weiji.chen on 14-3-9. * 文件下载的请求.请求的队列会加到默认的RequestQueue中. * 由于是下载的文件,所以默认不使用缓存,因为默认缓存大小只有10M.除非RequestQueue配置大的缓存. * 如果需要下载小文件图片,比如头像,小文件可以缓存. * TODO:因为使用了路径,避免多余的网络请求,所以要进行路径拦截.首先进行的是:判断路径是否有效,如果无效,直接return了. */ public class DownloadRequest extends Request<File> { Response.Listener listener; private String filePath; public DownloadRequest(String url, String filePath) { this(url, filePath, null, null, null); } public DownloadRequest(String url, String filePath, Response.Listener listener, Response.ErrorListener errorListener) { this(Method.GET, url, filePath, listener, errorListener, null); } public DownloadRequest(String url, String filePath, Response.Listener listener, Response.ErrorListener errorListener, Response.ProgressListener progressListener) { this(Method.GET, url, filePath, listener, errorListener, progressListener); } /** * 创建下载请求. * * @param method * @param url * @param filePath * @param errorListener * @param progressListener 下载进度监听.默认1s刷新一次. */ public DownloadRequest(int method, String url, String filePath, Response.Listener listener, Response.ErrorListener errorListener, Response.ProgressListener progressListener) { super(method, url, errorListener, progressListener); this.filePath = filePath; this.listener = listener; // 如果路径不可用,就要取消下载. if (!validateFilePath(filePath)) { VolleyLog.d("The file path is invalited."); cancel(); } } /** * 判断文件的路径是否可用,且有合适的内存空间.粗鲁一点,直接判断10M可用空间.不可用就不仅要下载了. * * @param filePath 将要保存的文件及文件名. * @return true:路径可用,false:路径不可用. */ private boolean validateFilePath(String filePath) { //检测是否存在SD卡 if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { return false; } String parentPath = ""; // 根据文件名获取该文件的目录 if (!TextUtils.isEmpty(filePath)) { int lastSeparater = filePath.lastIndexOf('/'); if (lastSeparater >= 0) { parentPath = filePath.substring(0, lastSeparater); } } //检测是否存在下载目录,没有则创建,创建失败则返回. File downloadDir = new File(parentPath); if (!downloadDir.exists()) { downloadDir.mkdirs(); } if (!downloadDir.exists()) { return false; } //检查可用的空间 final StatFs stats = new StatFs(parentPath); long size = (long) stats.getBlockSize() * (long) stats.getAvailableBlocks(); return (size > 10 * 1024 * 1024); } @Override protected Response<File> parseNetworkResponse(NetworkResponse response) { // 将数据保存到文件了. FileOutputStream stream = null; try { stream = new FileOutputStream(filePath); stream.write(response.data); } catch (IOException e) { e.printStackTrace(); } finally { try { stream.close(); } catch (IOException e) { e.printStackTrace(); } } File file = new File(filePath); if (file.exists()) { return Response.success(file, null); } else { return Response.error(new FileError(response)); } } @Override protected void deliverResponse(File response) { if (listener != null) { listener.onResponse(response); } } }