Mit einer Mischung aus dem Code in verwandten Antworten, gelang es mir, mit multipart zu telefonieren. Ich kann es jedoch nicht mit dem korrekten Parameternamen senden.Android Volley mehrteiliger Parametername
Wie muss der Antrag (von der iOS-App genommen) werden:
Wie meine Anfrage aussieht:
Code:
MultipartRequest soll eine mehrteilige Basisanforderung sein.
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.util.Log;
import com.android.volley.Request;
import com.android.volley.Response;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import com.android.volley.AuthFailureError;
import com.android.volley.toolbox.StringRequest;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class MultipartRequest extends StringRequest {
private final int maxImageWidth = 200;
private final int maxImageHeight = 200;
static String mimeType;
private final File file;
DataOutputStream dos = null;
String lineEnd = "\r\n";
static String boundary = "apiclient-" + System.currentTimeMillis();
String twoHyphens = "--";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 124 * 124;
public static MultipartRequest newInstance(final PlayEarnAPIImpl.OnPlayEarnAPIResponse listener, File file, Response.Listener<String> responseListener, Response.ErrorListener errorListener, String serviceURL) {
mimeType = "multipart/form-data;boundary=" + boundary;
return new MultipartRequest(Request.Method.PUT, serviceURL, responseListener, errorListener, file, serviceURL);
}
public MultipartRequest(int method, String url, Response.Listener<String> listener, Response.ErrorListener errorListener, File file, String serviceURL) {
super(method, url, listener, errorListener);
this.file = file;
}
private byte[] decodeFile(File file) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inSampleSize = calculateInSampleSize(options, 400, 400);
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height/2;
final int halfWidth = width/2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight/inSampleSize) > reqHeight
&& (halfWidth/inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
//solution 2
private byte[] shrinkImage(File file) {
try {
int inWidth = 0;
int inHeight = 0;
InputStream in = new FileInputStream(file.getAbsolutePath());
// decode image size (decode metadata only, not the whole image)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, options);
in.close();
in = null;
// save width and height
inWidth = options.outWidth;
inHeight = options.outHeight;
// decode full image pre-resized
in = new FileInputStream(file.getAbsolutePath());
options = new BitmapFactory.Options();
// calc rought re-size (this is no exact resize)
options.inSampleSize = Math.max(inWidth/maxImageWidth, inHeight/maxImageHeight);
// decode full image
Bitmap roughBitmap = BitmapFactory.decodeStream(in, null, options);
// calc exact destination size
Matrix m = new Matrix();
RectF inRect = new RectF(0, 0, roughBitmap.getWidth(), roughBitmap.getHeight());
RectF outRect = new RectF(0, 0, maxImageWidth, maxImageHeight);
m.setRectToRect(inRect, outRect, Matrix.ScaleToFit.CENTER);
float[] values = new float[9];
m.getValues(values);
// resize bitmap
Bitmap resizedBitmap = Bitmap.createScaledBitmap(roughBitmap, (int) (roughBitmap.getWidth() * values[0]), (int) (roughBitmap.getHeight() * values[4]), true);
// save image
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
resizedBitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
} catch (IOException e) {
Log.e("Image", e.getMessage(), e);
}
return null;
}
@Override
public String getBodyContentType() {
return mimeType;
}
@Override
public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
dos = new DataOutputStream(bos);
byte[] bitmapData = null;
try {
//dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes(lineEnd);
dos.writeBytes(" ------------------12345");
dos.writeBytes(lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"picture\"; filename=\"file.png\"");
dos.writeBytes(lineEnd);
dos.writeBytes("Content-Type: image/png");
//dos.writeBytes("Content-Disposition: form-data; name=\"picture\";filename=\""
// + file.getName() + "\"" + lineEnd);
dos.writeBytes(lineEnd);
bitmapData = shrinkImage(this.file);
ByteArrayInputStream fileInputStream = new ByteArrayInputStream(bitmapData);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
Log.d("MultipartRequest", "bufferSize:" + bufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return bitmapData;
}
Dies ist die Anfrage Ich verwende:
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.google.gson.Gson;
import java.io.File;
import java.util.Map;
public class ChangeProfileImageRequest extends MultipartRequest {
private static final String UPDATE_PATH = "users/update";
String serviceURL = APIImpl.API_URL + UPDATE_PATH;
public static ChangeProfileImageRequest newInstance(final APIImpl.OnAPIResponse listener, File file) {
String serviceURL = APIImpl.API_URL + UPDATE_PATH;
return new ChangeProfileImageRequest(Request.Method.PUT, serviceURL, new ResponseListener(listener), new ErrorListener(listener), file, serviceURL);
}
public ChangeProfileImageRequest(int method, String url, Response.Listener<String> listener, Response.ErrorListener errorListener, File file, String serviceURL) {
super(method, url, listener, errorListener, file, serviceURL);
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new APIImpl().getTokenHeader();
//headers.put("Accept", "*/*");
headers.put("Content-Type", "multipart/form-data;boundary=----------------12345");
AppController.getInstance().addSessionCookie(headers);
return headers;
}
Also ich denke, es hat etwas mit dem Screenshot zu tun, die „multi Körper kann nicht entschlüsseln“, sagt, aber ich weiß nicht, Was ist das spezifische Problem? Auch von der Serverseite wird der Bildparameter nicht empfangen.
IMO, vielleicht 'dos.writeBytes (" ------------------ 12345 ");' jedoch verwenden Sie 'dos.writeBytes (twoHyphens + boundary + twoHyphens + lineEnd); 'verursacht später dieses Problem. Sie können ein Beispiel unter https://www.asp.net/web-api/overview/advanced/sending-html-form-data-part-2 sehen (achten Sie auf 'Das Format einer mehrteiligen MIME-Nachricht ist am einfachsten zu Verstehen Sie, indem Sie auf eine Beispielanfrage schauen '). Versuchen Sie meinen Code http://StackOverflow.com/Questions/32240177/working-post-multipart-request-with-volley-and-without-httpentity, um zu sehen, ob es helfen kann – BNK