Android 如何找到使用截击时图像无法上传的原因?
我尝试了很多方法将图像上传到我的节点服务器,但都没有成功。最后,我偶然发现了Ion库来上传图像,但这也不起作用。它到达onCompleteListener,但图像未上载到MongoDB。它在Postman中运行良好,但在android中不起作用。 这是节点代码Android 如何找到使用截击时图像无法上传的原因?,android,node.js,mongodb,android-volley,ion,Android,Node.js,Mongodb,Android Volley,Ion,我尝试了很多方法将图像上传到我的节点服务器,但都没有成功。最后,我偶然发现了Ion库来上传图像,但这也不起作用。它到达onCompleteListener,但图像未上载到MongoDB。它在Postman中运行良好,但在android中不起作用。 这是节点代码 const multer= require('multer'); const storage = multer.diskStorage({ destination: function(req, file, cb) {
const multer= require('multer');
const storage = multer.diskStorage({
destination: function(req, file, cb) {
var tok = decode(req.params.id);
// const url = req.protocol + "://" + req.get("host");
let path = './images/'+tok.email;
fs.mkdirsSync(path);
cb(null, path);
},
filename: function(req, file, cb) {
var tok = decode(req.params.id);
cb(null, tok.email +'profilePic' + file.originalname);
}
});
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 1
},
fileFilter: fileFilter
});
app.post('/profilepic/:id',upload.single('profilePic'),function (req,res) {
// if(!req.session.user){
// return res.status(200).send("failure@Not Authorized");
// }
var tok = decode(req.params.id);
console.log(req.file.filename);
User.updateOne({'_id': tok.id },{'profilePic':tok.email+'/'+req.file.filename}).then(result =>{
console.log(result);
if (result.n > 0) {
res.status(200).json({ message: "success" });
}else {
res.status(200).json({ message: "failure@err in Updating pic" });
}
})
.catch(error => {
res.status(200).json({
message: "failure@User not found!"
});
});
这是我的android代码
private void chooseImage(int imageReq) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), imageReq);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST)
&& resultCode == RESULT_OK
&& data != null
&& data.getData() != null) {
showProgressDialog();
Uri filePath = data.getData();
Log.d(TAG,getAbsolutePath(filePath));
uploadFile(getAbsolutePath(filePath));
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
Bitmap lastBitmap = null;
lastBitmap = bitmap;
if (requestCode == PICK_IMAGE_REQUEST) {
Glide.with(this)
.load(bitmap)
.into(profileCoverPic);
}
}
public String getAbsolutePath(Uri uri) {
String[] projection = { MediaStore.MediaColumns.DATA };
@SuppressWarnings("deprecation")
Cursor cursor = managedQuery(uri, projection, null, null, null);
if (cursor != null) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} else
return null;
}
private void uploadFile(String path){
Ion.with(getApplicationContext())
.load(profilePicUrl)
.setMultipartParameter("name", "source")
.setMultipartFile("profilepic", "image/jpeg", new File(path))
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
hideProgressDialog();
Log.d(TAG,"photo uploaded");
Toast.makeText(ProfileActivity.this, "Photo uploaded", Toast.LENGTH_SHORT).show();
//do stuff with result
}
});
}
任何其他方法也将不胜感激。在未完成的函数中,您需要检查是否存在异常。“异常”将为您提供有关其不工作原因的详细信息
public void onCompleted(Exception e, JsonObject result) {
hideProgressDialog();
if(e != null){
//IN ERROR CASE
Log.d(TAG, e.getLocalizedMessage());
}else{
Log.d(TAG,"photo uploaded");
Toast.makeText(ProfileActivity.this, "Photo uploaded",
Toast.LENGTH_SHORT).show();
//do stuff with result
}
}
});
如果您不理解LogCat中打印的错误,请在帖子中发布异常文本。对于图像上载,请使用Volleymultipart类
package com.conceptioni.ashebbicom.util;
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 java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
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;
public VolleyMultipartRequest(int method, String url,
Response.Listener<NetworkResponse> 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, 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, DataPart> getByteData() {
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);
}
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, DataPart> data) throws IOException {
for (Map.Entry<String, 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(lineEnd);
dataOutputStream.writeBytes(parameterValue + lineEnd);
}
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);
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;
}
String getFileName() {
return fileName;
}
byte[] getContent() {
return content;
}
String getType() {
return type;
}
}
}
我以前见过这种情况,但问题是客户端希望网络响应成功。您能为我提供相应的节点服务器代码吗?String json=new Stringresponse.data,HttpHeaderParser.parseCharsetresponse.headers;不,我的意思是,我可以在客户端将网络响应转换为字符串,但如何在服务器端为其编写代码。请为多部分请求提供完整的节点服务器代码。
VolleyMultipartRequest volleyMultipartRequest = new VolleyMultipartRequest(Request.Method.POST, Constants.edit_photo,
new Response.Listener<NetworkResponse>() {
@SuppressLint("ApplySharedPref")
@Override
public void onResponse(NetworkResponse response) {
try {
//Response
} catch (JSONException e) {
e.printStackTrace();
}
pb.setVisibility(View.GONE);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("API", "edit_photo");
//all params here
return params;
}
@Override
protected Map<String, DataPart> getByteData() {
Map<String, DataPart> params = new HashMap<>();
long imagename = System.currentTimeMillis();
params.put("var_image", new DataPart(imagename + ".png", getFileDataFromDrawable(bitmap)));
return params;
}
};
//adding the request to volley
Volley.newRequestQueue(ActivityProfileDetailSlider.this).add(volleyMultipartRequest);
public byte[] getFileDataFromDrawable(Bitmap bitmap) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 80, byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}