2015-08-19 11 views
5

Sto seguendo la soluzione per inviare una richiesta multiparte utilizzando il volley da How to multipart data using Android Volley. Ma, dal momento che SDK 22, httpentity è deprecato e viene rimossa completamente sul SDK 23.Come inviare una richiesta multipart utilizzando Volley senza HttpEntity?

La soluzione è quella di utilizzare OpenConnection, proprio come HttpEntity is deprecated on Android now, what's the alternative?, ma non so come usarlo per la richiesta più parti

risposta

3

ho trovato una soluzione per questo (sulla base di Multipart/form-data requests in Android: HttpURLConnection vs OkHttp)

Ecco il mio codice di esempio di lavoro (testato con ASP.Net WebAPI)

MultipartActivity.java

package com.example.volleyapp; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.Drawable; 
import android.os.Bundle; 
import android.support.v4.content.ContextCompat; 
import android.view.Menu; 
import android.view.MenuItem; 

import com.android.volley.AuthFailureError; 
import com.android.volley.NetworkResponse; 
import com.android.volley.Response; 
import com.android.volley.VolleyError; 
import com.example.volleyapp.BaseVolleyRequest; 
import com.example.volleyapp.VolleySingleton; 

import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.DataOutputStream; 
import java.io.IOException; 

public class MultipartActivity extends Activity { 

    final Context mContext = this; 
    String mimeType; 
    DataOutputStream dos = null; 
    String lineEnd = "\r\n"; 
    String boundary = "apiclient-" + System.currentTimeMillis(); 
    String twoHyphens = "--"; 
    int bytesRead, bytesAvailable, bufferSize; 
    byte[] buffer; 
    int maxBufferSize = 1024 * 1024; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_multipart);    

     Drawable drawable = ContextCompat.getDrawable(mContext, R.drawable.ic_action_file_attachment_light); 
     Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); 
     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
     bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream); 
     final byte[] bitmapData = byteArrayOutputStream.toByteArray(); 
     String url = "http://192.168.1.100/api/postfile"; 

     mimeType = "multipart/form-data;boundary=" + boundary; 

     BaseVolleyRequest baseVolleyRequest = new BaseVolleyRequest(1, url, new Response.Listener<NetworkResponse>() { 
      @Override 
      public void onResponse(NetworkResponse response) { 

      } 
     }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 

      } 
     }) { 
      @Override 
      public String getBodyContentType() { 
       return mimeType; 
      } 

      @Override 
      public byte[] getBody() throws AuthFailureError { 
       ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
       dos = new DataOutputStream(bos); 
       try { 
        dos.writeBytes(twoHyphens + boundary + lineEnd); 
        dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" 
          + "ic_action_file_attachment_light.png" + "\"" + lineEnd); 
        dos.writeBytes(lineEnd); 
        ByteArrayInputStream fileInputStream = new ByteArrayInputStream(bitmapData); 
        bytesAvailable = fileInputStream.available(); 

        bufferSize = Math.min(bytesAvailable, maxBufferSize); 
        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; 
      } 
     }; 

     VolleySingleton.getInstance(mContext).addToRequestQueue(baseVolleyRequest); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_multipart, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 
} 

BaseVolleyRequest.java:

package com.example.volleyapp; 

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 com.google.gson.JsonSyntaxException; 


public class BaseVolleyRequest extends Request<NetworkResponse> { 

    private final Response.Listener<NetworkResponse> mListener; 
    private final Response.ErrorListener mErrorListener; 

    public BaseVolleyRequest(String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) { 
     super(0, url, errorListener); 
     this.mListener = listener; 
     this.mErrorListener = errorListener; 
    } 

    public BaseVolleyRequest(int method, String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) { 
     super(method, url, errorListener); 
     this.mListener = listener; 
     this.mErrorListener = errorListener; 
    } 

    @Override 
    protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) { 
     try { 
      return Response.success(
        response, 
        HttpHeaderParser.parseCacheHeaders(response)); 
     } catch (JsonSyntaxException e) { 
      return Response.error(new ParseError(e)); 
     } catch (Exception e) { 
      return Response.error(new ParseError(e)); 
     } 
    } 

    @Override 
    protected void deliverResponse(NetworkResponse response) { 
     mListener.onResponse(response); 
    } 

    @Override 
    protected VolleyError parseNetworkError(VolleyError volleyError) { 
     return super.parseNetworkError(volleyError); 
    } 

    @Override 
    public void deliverError(VolleyError error) { 
     mErrorListener.onErrorResponse(error); 
    } 
} 
+0

Ciao, prima grazie per il tuo esempio! Sto provando a mettere de metodo de getParams ma non viene chiamato, hai una soluzione? – Spierki

+0

@Spierki Come puoi vedere io uso 'getBody()', non 'getParams' – BNK

+0

Sì. Vedo che ho usato getBody per mettere i miei file, ma se ho bisogno di mettere altri parametri in una hashmap, devo metterli in questa anche il metodo? O c'è una soluzione per getParams da chiamare? – Spierki

Problemi correlati