2015-08-19 56 views

回答

3

我已經找到了一個解決方案(基於 Multipart/form-data requests in Android: HttpURLConnection vs OkHttp

這是我工作的代碼示例(與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

您好,首先感謝您的例子!我試圖把de method de getParams,但它沒有被調用,你有一個解決方案? – Spierki

+0

@Spierki正如你可以看到我用'getBody()','不getParams' – BNK

+0

是的,我看到我用getBody把我的文件,但如果我需要把其他PARAMS一個HashMap中,我需要把他們在這方法呢?或者是否有getParams被調用的解決方案? – Spierki

相關問題