这是我要求将图像上传到服务器https://gist.github.com/anggadarkprince/a7c536da091f4b26bb4abf2f92926594
的要点但我使用TedPicker OnMultiImageSelectedListener来选择多个图像https://android-arsenal.com/details/1/4320
它在ArrayLIst中给出了selectedUriList。我将所有的Uri转换为byteArray并上传到服务器。 这是我的上传图像代码。
private void imageUpload() {
final ProgressDialog loading = ProgressDialog.show(this,"Uploading...","Please wait...",false,false);
VolleyMultipartRequest multipartRequest = new VolleyMultipartRequest(Request.Method.POST, Constants.UPLOAD_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");
loading.dismiss();
if (status.equals(Constants.REQUEST_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) {
loading.dismiss();
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);
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("folder_name", FOLDER_NAME);
return params;
}
@Override
protected Map<String, DataPart> getByteData() {
Map<String, DataPart> params = new HashMap<>();
int i = 0;
for (Uri uri : selectedUriList) {
i++;
try {
InputStream iStream = getContentResolver().openInputStream(uri);
byte[] inputData = getBytes(iStream);
params.put("image_file"+i, new DataPart("image"+i+".jpg", inputData , "image/jpeg"));
} catch (IOException e) {
e.printStackTrace();
}
}
return params;
}
};
VolleySingleton.getInstance(getBaseContext()).addToRequestQueue(multipartRequest);
}
public byte[] getBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
尝试上传图片时面临的错误
I/System.out: [socket]rx timeout:2500
I/System.out: [socket][0] connection ascentcity.com/119.81.195.196:80;LocalPort=45296(2500)
I/System.out: [CDS]connect[ascentcity.com/119.81.195.196:80] tm:2
D/Posix: [Posix_connect Debug]Process com.vst.image.vehiclestimageclassifier :80
I/System.out: [socket][/192.168.31.42:45296] connected
I/System.out: [socket]rx timeout:2500
D/Volley: [22832] BasicNetwork.logSlowRequests: HTTP response for request=<[ ] http://ascentcity.com/Mobileapp/upload.php 0x43980958 NORMAL 1> [lifetime=48143], [size=116], [rc=200], [retryCount=0]
W/System.err: org.json.JSONException: Value Sorry of type java.lang.String cannot be converted to JSONObject
W/System.err: at org.json.JSON.typeMismatch(JSON.java:111)
W/System.err: at org.json.JSONObject.<init>(JSONObject.java:160)
W/System.err: at org.json.JSONObject.<init>(JSONObject.java:173)
W/System.err: at com.vst.image.vehiclestimageclassifier.MainActivity$3.onResponse(MainActivity.java:171)
W/System.err: at com.vst.image.vehiclestimageclassifier.MainActivity$3.onResponse(MainActivity.java:166)
W/System.err: at com.vst.image.vehiclestimageclassifier.VolleyMultipartRequest.deliverResponse(VolleyMultipartRequest.java:127)
W/System.err: at com.vst.image.vehiclestimageclassifier.VolleyMultipartRequest.deliverResponse(VolleyMultipartRequest.java:24)
W/System.err: at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err: at android.os.Looper.loop(Looper.java:157)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5429)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
我有几个问题
是否可以从这样的图像中检索字节数据,还是有更好的方法?
@Override
protected Map<String, DataPart> getByteData() {
Map<String, DataPart> params = new HashMap<>();
int i = 0;
for (Uri uri : selectedUriList) {
i++;
try {
InputStream iStream = getContentResolver().openInputStream(uri);
byte[] inputData = getBytes(iStream);
// file name could found file base or direct access from real path
// for now just get bitmap data from ImageView
params.put("image_file"+i, new DataPart("image"+i+".jpg", inputData , "image/jpeg"));
} catch (IOException e) {
e.printStackTrace();
}
}
return params;
}
iam面临的错误是由于服务器速度慢?或者是其他东西 ?如何调试?
我需要与后端团队(服务器端)沟通,我可以处理我的请求。
以下是完成项目代码https://github.com/sooorajjj/vstImageClassifier的github链接 谢谢!
答案 0 :(得分:0)
这是我自定义的 VolleyMultipartRequest 文件。您可以直接使用它上传具有相同参数名称的多张图片:
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Map;
/**
* Custom request to make multipart header and upload file.
* <p>
* Sketch Project Studio
* Created by bhuvnesh 8/10/2019
*/
@SuppressWarnings("unused")
public class VolleyMultipartRequest extends Request<JSONObject> {
private final String twoHyphens = "--";
private final String lineEnd = "\r\n";
private final String boundary = "apiclient-" + System.currentTimeMillis();
private Response.Listener<JSONObject> mListener;
private Response.ErrorListener mErrorListener;
private Map<String, String> mHeaders;
public VolleyMultipartRequest(String url, Map<String, String> headers,
Response.Listener<JSONObject> listener,
Response.ErrorListener errorListener) {
super(Method.POST, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
this.mHeaders = headers;
}
public VolleyMultipartRequest(int method, String url,
Response.Listener<JSONObject> listener,
Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
}
@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, ArrayList<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;
}
protected Map<String, ArrayList<DataPart>> getByteData() throws AuthFailureError {
return null;
}
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
@Override
protected void deliverResponse(JSONObject response) {
mListener.onResponse(response);
}
@Override
public void deliverError(VolleyError error) {
mErrorListener.onErrorResponse(error);
}
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);
}
}
private void dataParse(DataOutputStream dataOutputStream, Map<String, ArrayList<DataPart>> data) throws IOException {
for (Map.Entry<String, ArrayList<DataPart>> entry : data.entrySet()) {
buildDataPart(dataOutputStream, entry.getValue(), entry.getKey());
}
}
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);
}
private void buildDataPart(DataOutputStream dataOutputStream, ArrayList<DataPart> dataFile, String inputName) throws IOException {
for (int i=0; i<dataFile.size(); i++){
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
DataPart dp = dataFile.get(i);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" +
inputName + "\"; filename=\"" + dp.getFileName() + "\"" + lineEnd);
if (dp.getType() != null && !dp.getType().trim().isEmpty()) {
dataOutputStream.writeBytes("Content-Type: " + dp.getType() + lineEnd);
}
dataOutputStream.writeBytes(lineEnd);
ByteArrayInputStream fileInputStream = new ByteArrayInputStream(dp.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);
while (bytesRead > 0) {
dataOutputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
dataOutputStream.writeBytes(lineEnd);
}
}
public class DataPart {
private String fileName;
private byte[] content;
private String type;
public DataPart() {
}
public DataPart(String name, byte[] data) {
fileName = name;
content = data;
}
public DataPart(String name, byte[] data, String mimeType) {
fileName = name;
content = data;
type = mimeType;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public byte[] getContent() {
return content;
}
public void setContent(byte[] content) {
this.content = content;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
}
这是使用此volleyMultipartRequest文件的代码:
VolleyMultipartRequest multipartRequest = new VolleyMultipartRequest(Request.Method.POST,
BaseURL.ADD_INVOICE, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
Toast.makeText(HomeActivity.this, response.getString("message"), Toast.LENGTH_LONG).show();
if (response.getString("message").equals("Invoice added successfully!!")){
check=true;
Intent intent = new Intent(HomeActivity.this, ThankyouActivity.class);
startActivity(intent);
//finish();
}else {
Toast.makeText(HomeActivity.this, response.getString("message"), Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
progressdialog.dismisswaitdialog();
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
Toast.makeText(HomeActivity.this, getResources().getString(R.string.connection_time_out), Toast.LENGTH_SHORT).show();
}
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("user_id", user_id);
params.put("year", et_year.getText().toString());
params.put("make", et_make.getText().toString());
params.put("model", et_model.getText().toString());
return params;
}
@Override
protected Map<String, ArrayList<DataPart>> getByteData() {
Map<String, VolleyMultipartRequest.DataPart> params = new HashMap<>();
Map<String, ArrayList<DataPart>> imageList = new HashMap<>();
ArrayList<DataPart> dataPart = new ArrayList<>();
String imagename = "image[]";
for (int i=0; i<encodedImageList.size(); i++){
VolleyMultipartRequest.DataPart dp = new VolleyMultipartRequest.DataPart(imagename+i, Base64.decode(encodedImageList.get(i), Base64.DEFAULT), "image/jpeg");
dataPart.add(dp);
//params.put(imagename, new DataPart(imagename+i, Base64.decode(encodedImageList.get(i), Base64.DEFAULT), "image/jpeg"));
}
imageList.put("image[]", dataPart);
return imageList;
}
};
int socketTimeout = 500000;//30 seconds - change to what you want
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
multipartRequest.setRetryPolicy(policy);
AppController.getInstance().addToRequestQueue(multipartRequest);
答案 1 :(得分:0)
对于 Kotlin,使用 MutableMap<String,ArrayList<DataPart>>
而不是 Map<String,ArrayList<DataPart>>
。
并且应该像这样初始化。
val dataParts:MutableMap<String,ArrayList<DataPart>> = mutableMapOf()
并将数据与HashMap<K,V>
相同。