Last active
August 29, 2015 14:21
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I added a usage example of the gist on separate file.