Skip to content

Instantly share code, notes, and snippets.

@ishmaelmakitla
Last active August 29, 2015 14:21
Show Gist options
  • Save ishmaelmakitla/898bc5c20b5963e780d6 to your computer and use it in GitHub Desktop.
Save ishmaelmakitla/898bc5c20b5963e780d6 to your computer and use it in GitHub Desktop.
This Gist shows how the Volley Request<T> class can be extended to support file download. The response listener will receive a File through the callback method onResponse(File downloadedFile). The file will already be on the device at this point.
package za.org.pta.gdg.gists;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;
import android.content.Context;
import android.os.Environment;
import android.util.Log;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.VolleyError;
/**
* This is a File Download request using the Volley library in Android.
* Essentially it parses network response and then writes this into a File object and return this to the response listener.
*
* @author Ishmael Makitla, 2015
Country Mentor: Google Developer Groups South Africa,
GDG-Pretoria
*
*/
public class FileDownloadRequest extends Request<File>{
private static final String TAG = FileDownloadRequest.class.getSimpleName();
//the listener of our custom File Download Request expects a File
private Response.Listener<File> mReponseListener;
private ErrorListener mErrorListener;
//this is the name of the file the user wants to download
//- so it is the last segment of the HPPT-GET URL (www.mystuff.com/downloads/file1.json) = file1.json
private String targetFileName;
private Context context;
public FileDownloadRequest(Context ctx, String url, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
mErrorListener = errorListener;
targetFileName = getFileNameFromURL(url);
context = ctx;
}
public FileDownloadRequest (Context ctx, String url, Response.ErrorListener errorListener, Response.Listener<File> listener){
super(Method.GET, url, errorListener);
mReponseListener = listener;
mErrorListener = errorListener;
targetFileName = getFileNameFromURL(url);
context = ctx;
}
private String getFileNameFromURL(String url){
if(url == null || url.trim().isEmpty()){ return null; }
String filename = null;
try{
filename = url.substring(url.lastIndexOf(File.separator)+1);
Log.i(TAG, "Target-File-Name For URL "+ url+" is "+filename);
}
catch(Exception e){
e.printStackTrace();
}
return filename;
}
@Override
protected void deliverResponse(File downloadedFile) {
if(downloadedFile != null){
Log.i(TAG, "deliverResponse Downloaded File = "+downloadedFile.getPath());
mReponseListener.onResponse(downloadedFile);
}
else{
//Not a file - error
Log.i(TAG, "The content received from Server is not a valid file. ");
mErrorListener.onErrorResponse(new VolleyError("The content received from Server is not a valid file."));
}
}
@Override
protected Response<File> parseNetworkResponse(NetworkResponse networkResponse) {
Log.i(TAG, "parseNetworkResponse. Data = "+networkResponse.data);
//write the response string into into a file (.json file in our case) and then pass onto the listener
byte[] data = networkResponse.data;
FileOutputStream fileOutput;
File downloadedFile = null;
try{
String filename = (targetFileName != null && !targetFileName.trim().isEmpty()? targetFileName : String.valueOf(new Date().getTime())+".json");
Log.i(TAG, "parseNetworkResponse. File-Name = "+filename);
//Ideally, you could take the download path as a parameter and that because the location of the downloaded file
downloadedFile = new File(Environment.getExternalStorageDirectory()+File.separator+filename);
downloadedFile.createNewFile();
fileOutput = new FileOutputStream(downloadedFile);
fileOutput.write(data);
fileOutput.close();
Log.i(TAG, "parseNetworkResponse. new File(filename) = downloadedFile = "+downloadedFile.getName());
//now we have the file, deliver it as success-response payload
Log.i(TAG, "parseNetworkResponse. Before Response.success. downloadedFile = "+downloadedFile);
return Response.success(downloadedFile, getCacheEntry());
}
catch(Exception e){
Log.e(TAG, "parseNetworkResponse. Error at this point", e);
e.printStackTrace();
return null;
}
}
//Here is a usage example for the FileDownloadRequest gists
RequestQueue queue = Volley.newRequestQueue(context);
FileDownloadRequest fileDownloadRequest = new FileDownloadRequest(context,"http://my-file-server/files/file1.txt", new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
try {
Log.w(TAG, "There was an error downloading a file. Error is "+error);
}
catch (NullPointerException err) {Log.e(TAG, err.getLocalizedMessage(), err);}
}
}, new Response.Listener<File>() {
@Override
public void onResponse(File file) {
Log.i(TAG, "Got file: "+file); //we got the file file1.txt
//do whatever with this file here - if it was a audio/video, you could start playing it
}
});
queue.add(fileDownloadRequest);
@ishmaelmakitla
Copy link
Author

I added a usage example of the gist on separate file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment