我想使用排球库下载视频。我在我的应用程序中使用凌空库进行所有网络调用。
答案 0 :(得分:6)
首先,我们需要创建一个扩展Volley Request类的自定义类。要下载文件数据,我们可以创建自定义字节数组请求。该字节数组可以转换为输入流,将数据写入SD卡。以下InputStreamVolleyRequest.java文件显示了如何创建自定义字节数组请求和访问响应标头,稍后将用于创建文件名。
InputStreamVolleyRequest.java
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import java.util.HashMap;
import java.util.Map;
public class InputStreamVolleyRequest extends Request<byte[]> {
private final Response.Listener<byte[]> mListener;
private Map<String, String> mParams;
//create a static map for directly accessing headers
public Map<String, String> responseHeaders ;
public InputStreamVolleyRequest(int post, String mUrl,Response.Listener<byte[]> listener,
Response.ErrorListener errorListener, HashMap<String, String> params) {
// TODO Auto-generated constructor stub
super(post, mUrl, errorListener);
// this request would never use cache.
setShouldCache(false);
mListener = listener;
mParams=params;
}
@Override
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return mParams;
};
@Override
protected void deliverResponse(byte[] response) {
mListener.onResponse(response);
}
@Override
protected Response<byte[]> parseNetworkResponse(NetworkResponse response) {
//Initialise local responseHeaders map with response headers received
responseHeaders = response.headers;
//Pass the response data here
return Response.success(response.data, HttpHeaderParser.parseCacheHeaders(response));
}
}
你的活动课.....
import android.os.Environment;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HurlStack;
import com.android.volley.toolbox.Volley;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
public class FileDownloadActivity extends ActionBarActivity implements Response.Listener<byte[]>, ErrorListener{
Button btn_download;
InputStreamVolleyRequest request;
int count;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_download);
btn_download =(Button)findViewById(R.id.button);
btn_download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Change your url below
String mUrl="http://yoururl.com";
request = new InputStreamVolleyRequest(Request.Method.GET, mUrl, FileDownloadActivity.this, FileDownloadActivity.this, null);
RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext(),
new HurlStack());
mRequestQueue.add(request);
}
});
}
@Override
public void onResponse(byte[] response) {
HashMap<String, Object> map = new HashMap<String, Object>();
try {
if (response!=null) {
//Read file name from headers
String content =request.responseHeaders.get("Content-Disposition")
.toString();
StringTokenizer st = new StringTokenizer(content, "=");
String[] arrTag = st.toArray();
String filename = arrTag[1];
filename = filename.replace(":", ".");
Log.d("DEBUG::RESUME FILE NAME", filename);
try{
long lenghtOfFile = response.length;
//covert reponse to input stream
InputStream input = new ByteArrayInputStream(response);
File path = Environment.getExternalStorageDirectory();
File file = new File(path, filename);
map.put("resume_path", file.toString());
BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(file));
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
}catch(IOException e){
e.printStackTrace();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("KEY_ERROR", "UNABLE TO DOWNLOAD FILE");
e.printStackTrace();
}
}
@Override
public void onErrorResponse(VolleyError error) {
Log.d("KEY_ERROR", "UNABLE TO DOWNLOAD FILE. ERROR:: "+error.getMessage());
}
}
和这个StringTokenizer类..... StringTokenizer.java
答案 1 :(得分:3)
首先,您必须创建自己的自定义请求类,如
document = doc_form.save(commit=False)
现在只需通过我们的自定义类发送请求,其中包含Request.Method.GET和您要下载文件的网址。
class InputStreamVolleyRequest extends Request<byte[]> {
private final Response.Listener<byte[]> mListener;
private Map<String, String> mParams;
//create a static map for directly accessing headers
public Map<String, String> responseHeaders ;
public InputStreamVolleyRequest(int method, String mUrl ,Response.Listener<byte[]> listener,
Response.ErrorListener errorListener, HashMap<String, String> params) {
// TODO Auto-generated constructor stub
super(post, mUrl, errorListener);
// this request would never use cache.
setShouldCache(false);
mListener = listener;
mParams=params;
}
@Override
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return mParams;
};
@Override
protected void deliverResponse(byte[] response) {
mListener.onResponse(response);
}
@Override
protected Response<byte[]> parseNetworkResponse(NetworkResponse response) {
//Initialise local responseHeaders map with response headers received
responseHeaders = response.headers;
//Pass the response data here
return Response.success( response.data, HttpHeaderParser.parseCacheHeaders(response));
}
}
现在转到您的应用程序文件夹数据/数据//还有您的文件,您也可以将文件下载到外部存储。
您可以使用
访问内部存储中的文件String mUrl= <YOUR_URL>;
InputStreamVolleyRequest request = new InputStreamVolleyRequest(Request.Method.GET, mUrl,
new Response.Listener<byte[]>() {
@Override
public void onResponse(byte[] response) {
// TODO handle the response
try {
if (response!=null) {
FileOutputStream outputStream;
String name=<FILE_NAME_WITH_EXTENSION e.g reference.txt>;
outputStream = openFileOutput(name, Context.MODE_PRIVATE);
outputStream.write(response);
outputStream.close();
Toast.makeText(this, "Download complete.", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("KEY_ERROR", "UNABLE TO DOWNLOAD FILE");
e.printStackTrace();
}
}
} ,new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// TODO handle the error
error.printStackTrace();
}
}, null);
RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext(), new HurlStack());
mRequestQueue.add(request);
它从应用程序的内部目录返回具有该名称的文件,如果没有具有此类名称的文件,则返回null。别忘了用名称添加文件的扩展名。
答案 2 :(得分:0)
从理论上讲,这也应作为该问题的答案。
有关我的设置的快速信息
我正在使用AWS lambda函数,该函数向我发送了一个以base64编码的results.csv
文件。
这是函数针对GET请求返回的响应。
response = {
'statusCode': 200,
'headers': {
'content-type': 'text/csv'
},
'msg': 'Successfully got GET request',
'body': get_file(filename=filename),
'isBase64Encoded': True
}
get_file()
函数返回base64编码的文件
通过对Harshal Benake的答案进行一些细微调整,我能够将文件下载并保存到data / com.android.my_app / results.csv
这是怎么回事
为您的请求创建一个自定义类,您可以了解有关here
的更多信息我复制了Harshal的答案并对其进行了一些修改,使我的自定义请求类称为EncodedByteArrayFileRequest.java
这是(略有简化的)源代码
package com.android.resultsgrapherlive;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import java.util.HashMap;
import java.util.Map;
class EncodedByteArrayFileRequest extends Request<byte[]> {
private final Response.Listener<byte[]> mListener;
private Map<String, String> mParams;
public Map<String, String> responseHeaders;
public EncodedByteArrayFileRequest(int method, String mUrl,
Response.Listener<byte[]> listener,
Response.ErrorListener errorListener,
HashMap<String, String> params)
{
// TODO Auto-generated constructor stub
super(method, mUrl, errorListener);
// this request would never use cache.
setShouldCache(false);
mListener = listener;
mParams = params;
}
// NOTE: original answer had this method set as protected
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return mParams;
}
@Override
protected void deliverResponse(byte[] response) {
mListener.onResponse(response);
}
@Override
protected Response<byte[]> parseNetworkResponse(NetworkResponse response) {
responseHeaders = response.headers;
return Response.success(response.data, HttpHeaderParser.parseCacheHeaders(response));
}
}
这是我上课的方式
首先,您需要在代码中的某个位置初始化RequestQueue, 通常在您的onCreate方法中,所以它会像这样:
class MainActivity extends AppCompatActivity {
private RequestQueue queue;
@Override
protected void onCreate() {
// ...
queue = new Volley.newRequestQueue(this);
// ...
}
}
Witihin MainActivity,我创建了一个名为sendGetRequest的函数,该函数接收要下载文件的文件名
private void sendGetRequest(final String filename) {
String url = "add.yourownurl.com";
EncodedByteArrayFileRequest request = new EncodedByteArrayFileRequest(
Request.Method.GET, url,
new Response.Listener<byte[]>() {
@Override
public void onResponse(byte[] response) {
handleResponse(response, filename);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
handleError(error);
}
},
(HashMap<String, String>) requestParams(filename)
);
queue.add(request);
}
为了减少代码的混乱度,我添加了handleResponse
,handleError
和requestParams
并按以下方式对它们进行了定义:
private void handleResponse(byte[] response, String saveAs) {
try {
saveFile(response, saveAs);
} catch (IOException e) {
// TODO: remove all logs before finalizing app
Log.d("failed to save file", "File not saved", e);
String msg = "Failed to save file";
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
}
private void handleError(VolleyError error) {
Log.d("VolleyError", "Got error in get request", error);
Toast.makeText(this, "Error. Check Logcat", Toast.LENGTH_SHORT).show();
}
private Map<String, String> requestParams(String filename) {
Map<String, String> params = new HashMap<>();
params.put("filename", filename); // I setup my lambda function to check for this header
return params;
}
最后,要保存下载的文件,请使用saveFile
函数。这几乎是一个复制粘贴。
private void saveFile(byte[] response, String filename) throws IOException {
FileOutputStream outputStream;
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(response);
outputStream.close();
}
出于我的目的,我在不同的地方下载并使用了多个不同的文件,因此要加载使用此功能保存的文件,我使用了getFilesDir().listFiles()
并将其遍历直到找到正确的文件名。然后可以使用简单的扫描仪读取文件。
也许有更好的方法来加载文件,但是由于这对我有用,所以我决定将其保留为这样。
答案 3 :(得分:-12)
Volley库已被弃用,因此请勿使用Volley库。
Volley的最佳替代品是RetroFit库。
您可以下载使用Async Task的视频文件。