- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有字节数组中的数据,我需要将它从 Volley 库
发送到服务。这是我尝试过的,但它没有到达 getBody()
方法,并在读取正文之前返回响应,
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d("Success", response.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("Error", error.toString());
}
}){
@Override
public byte[] getBody() throws AuthFailureError {
return bytesObject;
}
@Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
};
RequestQueue requestQueue = Volley.newRequestQueue(AnalyticsApplication.getAppContext());
requestQueue.add(stringRequest);
可能是我遗漏了什么,请指导我如何从 Volley
库发送 byte array
。
最佳答案
试试这个
public void actionCallWebServiceWithFiles(String url, final HashMap<String, String> params, final Map<String, VolleyMultipartRequest.DataPart> file) {
VolleyMultipartRequest multipartRequest = new VolleyMultipartRequest(Request.Method.POST, url, new Response.Listener<NetworkResponse>() {
@Override
public void onResponse(NetworkResponse response) {
String resultResponse = new String(response.data);
try {
JSONObject result = new JSONObject(resultResponse);
/*String status = result.getString("status");
String message = result.getString("message");
if (status.equals(Constants.SUCCESS)) {
// tell everybody you have succed upload image and post strings
Log.i("Messsage", message);
} else {
Log.i("Unexpected", message);
}*/
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
String errorMessage = "Unknown error";
if (networkResponse == null) {
if (error.getClass().equals(TimeoutError.class)) {
errorMessage = "Request timeout";
} else if (error.getClass().equals(NoConnectionError.class)) {
errorMessage = "Failed to connect server";
}
} else {
String result = new String(networkResponse.data);
try {
JSONObject response = new JSONObject(result);
String status = response.getString("status");
String message = response.getString("message");
Log.e("Error Status", status);
Log.e("Error Message", message);
if (networkResponse.statusCode == 404) {
errorMessage = "Resource not found";
} else if (networkResponse.statusCode == 401) {
errorMessage = message + " Please login again";
} else if (networkResponse.statusCode == 400) {
errorMessage = message + " Check your inputs";
} else if (networkResponse.statusCode == 500) {
errorMessage = message + " Something is getting wrong";
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Log.i("Error", errorMessage);
error.printStackTrace();
}
}, onProgressUpdate) {
@Override
protected Map<String, String> getParams() {
return params;
}
@Override
protected Map<String, DataPart> getByteData() {
Map<String, DataPart> params = new HashMap<>();
// file name could found file base or direct access from real path
// for now just get bitmap data from ImageView
// params.put("doc_file", new DataPart("file_avatar.jpg", Common.getFileDataFromDrawable(context, context.getDrawable(R.drawable.ic_app_icon)), "image/png"));
// params.put("upload_file", new DataPart("screens.zip",file,"application/zip"));
return file;
}
};
MyApplication.getInstance().addToRequestQueue(multipartRequest);
}
VolleyMultiPartRequest.java
public class VolleyMultipartRequest extends Request<NetworkResponse> {
private final String twoHyphens = "--";
private final String lineEnd = "\r\n";
private final String boundary = "apiclient-" + System.currentTimeMillis();
private Response.Listener<NetworkResponse> mListener;
private Response.ErrorListener mErrorListener;
private Map<String, String> mHeaders;
private OnProgressUpdate onProgressUpdate;
private int transferred = 0;
/**
* Default constructor with predefined header and post method.
*
* @param url request destination
* @param headers predefined custom header
* @param listener on success achieved 200 code from request
* @param errorListener on error http or library timeout
*/
public VolleyMultipartRequest(String url, Map<String, String> headers,
Response.Listener<NetworkResponse> listener,
Response.ErrorListener errorListener) {
super(Method.POST, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
this.mHeaders = headers;
}
/**
* Constructor with option method and default header configuration.
*
* @param method method for now accept POST and GET only
* @param url request destination
* @param listener on success event handler
* @param errorListener on error event handler
*/
public VolleyMultipartRequest(int method, String url,
Response.Listener<NetworkResponse> listener,
Response.ErrorListener errorListener, OnProgressUpdate onProgressUpdate) {
super(method, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
this.onProgressUpdate = onProgressUpdate;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return (mHeaders != null) ? mHeaders : super.getHeaders();
}
@Override
public String getBodyContentType() {
return "multipart/form-data;boundary=" + boundary;
}
@Override
public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
try {
// populate text payload
Map<String, String> params = getParams();
if (params != null && params.size() > 0) {
textParse(dos, params, getParamsEncoding());
}
// populate data byte payload
Map<String, DataPart> data = getByteData();
if (data != null && data.size() > 0) {
dataParse(dos, data);
}
// close multipart form data after text and file data
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* Custom method handle data payload.
*
* @return Map data part label with data byte
* @throws AuthFailureError
*/
protected Map<String, DataPart> getByteData() throws AuthFailureError {
return null;
}
@Override
protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
try {
return Response.success(
response,
HttpHeaderParser.parseCacheHeaders(response));
} catch (Exception e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(NetworkResponse response) {
mListener.onResponse(response);
}
@Override
public void deliverError(VolleyError error) {
mErrorListener.onErrorResponse(error);
}
/**
* Parse string map into data output stream by key and value.
*
* @param dataOutputStream data output stream handle string parsing
* @param params string inputs collection
* @param encoding encode the inputs, default UTF-8
* @throws IOException
*/
private void textParse(DataOutputStream dataOutputStream, Map<String, String> params, String encoding) throws IOException {
try {
for (Map.Entry<String, String> entry : params.entrySet()) {
buildTextPart(dataOutputStream, entry.getKey(), entry.getValue());
}
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + encoding, uee);
}
}
/**
* Parse data into data output stream.
*
* @param dataOutputStream data output stream handle file attachment
* @param data loop through data
* @throws IOException
*/
private void dataParse(DataOutputStream dataOutputStream, Map<String, DataPart> data) throws IOException {
for (Map.Entry<String, DataPart> entry : data.entrySet()) {
buildDataPart(dataOutputStream, entry.getValue(), entry.getKey());
}
}
/**
* Write string data into header and data output stream.
*
* @param dataOutputStream data output stream handle string parsing
* @param parameterName name of input
* @param parameterValue value of input
* @throws IOException
*/
private void buildTextPart(DataOutputStream dataOutputStream, String parameterName, String parameterValue) throws IOException {
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + parameterName + "\"" + lineEnd);
//dataOutputStream.writeBytes("Content-Type: text/plain; charset=UTF-8" + lineEnd);
dataOutputStream.writeBytes(lineEnd);
dataOutputStream.writeBytes(parameterValue + lineEnd);
}
/**
* Write data file into header and data output stream.
*
* @param dataOutputStream data output stream handle data parsing
* @param dataFile data byte as DataPart from collection
* @param inputName name of data input
* @throws IOException
*/
private void buildDataPart(DataOutputStream dataOutputStream, DataPart dataFile, String inputName) throws IOException {
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" +
inputName + "\"; filename=\"" + dataFile.getFileName() + "\"" + lineEnd);
if (dataFile.getType() != null && !dataFile.getType().trim().isEmpty()) {
dataOutputStream.writeBytes("Content-Type: " + dataFile.getType() + lineEnd);
}
dataOutputStream.writeBytes(lineEnd);
ByteArrayInputStream fileInputStream = new ByteArrayInputStream(dataFile.getContent());
int bytesAvailable = fileInputStream.available();
int maxBufferSize = 1024 * 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
long total = 0;
while (bytesRead > 0) {
dataOutputStream.write(buffer, 0, bufferSize);
total = dataOutputStream.size();
transferred = (int) (total * 100 / dataFile.getContent().length) ;
onProgressUpdate.onTransferred(transferred);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
dataOutputStream.writeBytes(lineEnd);
}
/**
* Simple data container use for passing byte file
*/
public static class DataPart {
private String fileName;
private byte[] content;
private String type;
/**
* Default data part
*/
public DataPart() {
}
/**
* Constructor with data.
*
* @param name label of data
* @param data byte data
*/
public DataPart(String name, byte[] data) {
fileName = name;
content = data;
}
/**
* Constructor with mime data type.
*
* @param name label of data
* @param data byte data
* @param mimeType mime data like "image/jpeg"
*/
public DataPart(String name, byte[] data, String mimeType) {
fileName = name;
content = data;
type = mimeType;
}
/**
* Getter file name.
*
* @return file name
*/
public String getFileName() {
return fileName;
}
/**
* Setter file name.
*
* @param fileName string file name
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}
/**
* Getter content.
*
* @return byte file data
*/
public byte[] getContent() {
return content;
}
/**
* Setter content.
*
* @param content byte file data
*/
public void setContent(byte[] content) {
this.content = content;
}
/**
* Getter mime type.
*
* @return mime type
*/
public String getType() {
return type;
}
/**
* Setter mime type.
*
* @param type mime type
*/
public void setType(String type) {
this.type = type;
}
}
}
关于android - 如何从 Volley 库发送字节数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43736719/
我正在使用 voip 推送通知制作 ios 应用程序。 我想从 Node js 发送 voip 推送通知,但不是很好。 我阅读了本教程 CallKit iOS Swift Tutorial for V
我编写了一个服务器,当浏览器尝试连接到某些站点时,它会检查黑名单并发回 404,但是当我调用 send() 时没有错误,但消息不会出现在网络上浏览器,除非我关闭连接? 有什么建议吗? 接受来自浏览器的
#include int main() { char c = getchar(); //EOF (ctrl + d ) while( ( c = getchar() ) != '?'
我正在尝试使用MailMessage对象通过PowerShell发送电子邮件。该脚本使用Import-CSV来使用文件,然后在电子邮件正文中使用ConvertTo-HTML。由于我要发送的电子邮件客户
我需要创建一个脚本,每 30 秒对网络流量进行一次采样并存储发送/接收的字节。该数据随后用于绘制图形。我编写了一个在 Windows 2012 上完美运行的程序,但我意识到某些 cmdlet 在以前的
我正在运行“autoit3.chm”文件。当它运行时,我想发送一个向下键箭头,但它不起作用: $file = FileGetShortName("C:\Users\PHSD100-SIC\Deskto
当我使用网络浏览器测试我的程序时,我可以很好地写入套接字/FD,所以我决定循环它并在连接中途切断连接,我发现了一个问题。 send() 能够在套接字不可用时关闭整个程序。我认为问题在于该程序陷入了第
我正在运行“autoit3.chm”文件。当它运行时,我想发送一个向下键箭头,但它不起作用: $file = FileGetShortName("C:\Users\PHSD100-SIC\Deskto
所以我试图向自己发送数据并接收数据然后打印它,现在我已经测试了一段时间,我注意到它没有发送任何东西,事实上,也许它是,但我没有正确接收它,我需要这方面的帮助。 这就是我用来发送数据的
问题:开发人员创建自己的序列化格式有多常见?具体来说,我使用 java 本质上将对象作为一个巨大的字符串发送,并用标记来分隔变量。 我的逻辑:我选择这个是因为它几乎消除了语言依赖性(忽略java的修改
我必须在 Linux 上编写一个应用程序,该应用程序需要与具有自定义以太网类型的设备进行通信。甚至在如何编写这样的应用程序中也有很多解决方案。一个缺点是需要 root 访问权限(AFAIK)。之后释放
我有一个包含三个单选按钮选项的表单。我需要将表单数据提交到另一个文件,但由于某种原因,发送的数据包含所选单选按钮的值“on”,而不是 value 属性的值。 我尝试通过 post() 函数手动操作和发
基本上我想实现这样的目标: Process 1 Thread 1 Receive X from process 2 Thread 2 Receive Y from proces
我目前正在 Google App Engine 上开发一个系统,对它还很陌生,我正在使用 Java 平台进行开发。我在 servlet 之间发送 session 对象时遇到问题。我已经在 appeng
当我尝试将“this”(触发的元素)作为参数发送给函数时,函数收到“Object[Document build.php]”作为参数,而不是触发的元素。请让我知道我的错误: function set(a
我正在寻找让我的应用响应联系人 > 发送的魔法咒语。我希望能够接收联系人的 URI 以便检索联系人。谁有 list 过滤器/代码 fragment 吗? 最佳答案 我没有睾丸,但您可以尝试基于 ACT
关于我心爱的套接字的另一个问题。我先解释一下我的情况。之后我会告诉你是什么困扰着我。 我有一个客户端和一个服务器。这两个应用程序都是用 C++ 编写的,实现了 winsock2。连接通过 TCP 和
我看到了这篇文章 http://www.eskimo.com/~scs/cclass/int/sx5.html 但这部分让我感到困惑:如果我们已经使用 send_array 或 send_array_
我对这行代码有疑问。我必须将一个数据包带到一个端口并重新发送到接口(interface)(例如:eth0)。我的程序成功地从端口获取数据包,但是当我重新发送(使用 send())到接口(interfa
我正在尝试编写一个 X11 输入驱动程序,它可以使用我的 Android 手机上的触摸屏来移动和单击鼠标。我可以正常移动鼠标,但我无法让应用程序正确识别点击。我当前的代码位于 https://gist
我是一名优秀的程序员,十分优秀!