android Volley 實現檔案上傳功能,androidvolley

來源:互聯網
上載者:User

android Volley 實現檔案上傳功能,androidvolley

Volley不解釋了吧, android 官方的一個網路請求庫.


原始碼的地址在:

git@github.com:com314159/VolleyMultiPartRequest.git


是根據

https://github.com/smanikandan14/Volley-demo

這位大神修改而來的, 但是那位大神的代碼有bug, 上傳檔案不成功.


注: 我的demo裡面還整合了okhttp, 不需要的同學不用理這個類即可


實現方法:

1.添加三個jar包,

httpcore-4.3.2.jar

httpclient-4.3.5.jar

httpmime-4.3.5.jar


2.實現MultiPartStack

package com.example.volleytest;import java.io.File;import java.io.IOException;import java.util.Map;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpDelete;import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPatch;import org.apache.http.client.methods.HttpPost;import org.apache.http.client.methods.HttpPut;import org.apache.http.client.methods.HttpUriRequest;import org.apache.http.entity.ByteArrayEntity;import org.apache.http.entity.ContentType;import org.apache.http.entity.mime.HttpMultipartMode;import org.apache.http.entity.mime.MultipartEntityBuilder;import org.apache.http.entity.mime.content.FileBody;import org.apache.http.entity.mime.content.StringBody;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.params.HttpConnectionParams;import org.apache.http.params.HttpParams;import org.apache.http.protocol.HTTP;import com.android.volley.AuthFailureError;import com.android.volley.Request;import com.android.volley.Request.Method;import com.android.volley.toolbox.HurlStack;/** * @author ZhiCheng Guo * @version 2014年10月7日 上午11:00:52 這個Stack用於上傳檔案, 如果沒有這個Stack, 則上傳檔案不成功 */public class MultiPartStack extends HurlStack {@SuppressWarnings("unused")private static final String TAG = MultiPartStack.class.getSimpleName();    private final static String HEADER_CONTENT_TYPE = "Content-Type";@Overridepublic HttpResponse performRequest(Request<?> request,Map<String, String> additionalHeaders) throws IOException, AuthFailureError {if(!(request instanceof MultiPartRequest)) {return super.performRequest(request, additionalHeaders);}else {return performMultiPartRequest(request, additionalHeaders);}}    private static void addHeaders(HttpUriRequest httpRequest, Map<String, String> headers) {        for (String key : headers.keySet()) {            httpRequest.setHeader(key, headers.get(key));        }    }public HttpResponse performMultiPartRequest(Request<?> request,Map<String, String> additionalHeaders)  throws IOException, AuthFailureError {        HttpUriRequest httpRequest = createMultiPartRequest(request, additionalHeaders);        addHeaders(httpRequest, additionalHeaders);        addHeaders(httpRequest, request.getHeaders());        HttpParams httpParams = httpRequest.getParams();        int timeoutMs = request.getTimeoutMs();        // TODO: Reevaluate this connection timeout based on more wide-scale        // data collection and possibly different for wifi vs. 3G.        HttpConnectionParams.setConnectionTimeout(httpParams, 5000);        HttpConnectionParams.setSoTimeout(httpParams, timeoutMs);                        /* Make a thread safe connection manager for the client */        HttpClient httpClient = new DefaultHttpClient(httpParams);        return httpClient.execute(httpRequest);}    static HttpUriRequest createMultiPartRequest(Request<?> request,            Map<String, String> additionalHeaders) throws AuthFailureError {        switch (request.getMethod()) {            case Method.DEPRECATED_GET_OR_POST: {                // This is the deprecated way that needs to be handled for backwards compatibility.                // If the request's post body is null, then the assumption is that the request is                // GET.  Otherwise, it is assumed that the request is a POST.                byte[] postBody = request.getBody();                if (postBody != null) {                    HttpPost postRequest = new HttpPost(request.getUrl());                    if(request.getBodyContentType() != null)                    postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());                    HttpEntity entity;                    entity = new ByteArrayEntity(postBody);                    postRequest.setEntity(entity);                    return postRequest;                } else {                    return new HttpGet(request.getUrl());                }            }            case Method.GET:                return new HttpGet(request.getUrl());            case Method.DELETE:                return new HttpDelete(request.getUrl());            case Method.POST: {                HttpPost postRequest = new HttpPost(request.getUrl());                postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());                setMultiPartBody(postRequest,request);                return postRequest;            }            case Method.PUT: {                HttpPut putRequest = new HttpPut(request.getUrl());                if(request.getBodyContentType() != null)                putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());                setMultiPartBody(putRequest,request);                return putRequest;            }            // Added in source code of Volley libray.            case Method.PATCH: {            HttpPatch patchRequest = new HttpPatch(request.getUrl());            if(request.getBodyContentType() != null)            patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());                return patchRequest;            }            default:                throw new IllegalStateException("Unknown request method.");        }    }/** * If Request is MultiPartRequest type, then set MultipartEntity in the * httpRequest object. *  * @param httpRequest * @param request * @throws AuthFailureError */private static void setMultiPartBody(HttpEntityEnclosingRequestBase httpRequest,Request<?> request) throws AuthFailureError {// Return if Request is not MultiPartRequestif (!(request instanceof MultiPartRequest)) {return;}// MultipartEntity multipartEntity = new// MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);MultipartEntityBuilder builder = MultipartEntityBuilder.create();/* example for setting a HttpMultipartMode */builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);// Iterate the fileUploadsMap<String, File> fileUpload = ((MultiPartRequest) request).getFileUploads();for (Map.Entry<String, File> entry : fileUpload.entrySet()) {builder.addPart(((String) entry.getKey()), new FileBody((File) entry.getValue()));}ContentType contentType = ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8);// Iterate the stringUploadsMap<String, String> stringUpload = ((MultiPartRequest) request).getStringUploads();for (Map.Entry<String, String> entry : stringUpload.entrySet()) {try {builder.addPart(((String) entry.getKey()),new StringBody((String) entry.getValue(), contentType));} catch (Exception e) {e.printStackTrace();}}httpRequest.setEntity(builder.build());}}


3. 實現MultiPartRequest, 這個介面是為了方便擴充

package com.example.volleytest;import java.io.File;import java.util.Map;/** * @author ZhiCheng Guo * @version 2014年10月7日 上午11:04:36 */public interface MultiPartRequest {    public void addFileUpload(String param,File file);         public void addStringUpload(String param,String content);         public Map<String,File> getFileUploads();        public Map<String,String> getStringUploads(); }


/** * Copyright 2013 Mani Selvaraj * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.example.volleytest;import java.io.File;import java.io.UnsupportedEncodingException;import java.util.HashMap;import java.util.Map;import com.android.volley.NetworkResponse;import com.android.volley.Request;import com.android.volley.Response;import com.android.volley.Response.ErrorListener;import com.android.volley.Response.Listener;import com.android.volley.toolbox.HttpHeaderParser;/** * MultipartRequest - To handle the large file uploads. * Extended from JSONRequest. You might want to change to StringRequest based on your response type. * @author Mani Selvaraj * */public class MultiPartStringRequest extends Request<String> implements MultiPartRequest{private final Listener<String> mListener;/* To hold the parameter name and the File to upload */private Map<String,File> fileUploads = new HashMap<String,File>();/* To hold the parameter name and the string content to upload */private Map<String,String> stringUploads = new HashMap<String,String>();    /**     * Creates a new request with the given method.     *     * @param method the request {@link Method} to use     * @param url URL to fetch the string at     * @param listener Listener to receive the String response     * @param errorListener Error listener, or null to ignore errors     */    public MultiPartStringRequest(int method, String url, Listener<String> listener,            ErrorListener errorListener) {        super(method, url, errorListener);        mListener = listener;    }    public void addFileUpload(String param,File file) {    fileUploads.put(param,file);    }        public void addStringUpload(String param,String content) {    stringUploads.put(param,content);    }        /**     * 要上傳的檔案     */    public Map<String,File> getFileUploads() {    return fileUploads;    }        /**     * 要上傳的參數     */    public Map<String,String> getStringUploads() {    return stringUploads;    }        @Override    protected Response<String> parseNetworkResponse(NetworkResponse response) {        String parsed;        try {            parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));        } catch (UnsupportedEncodingException e) {            parsed = new String(response.data);        }        return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));    }@Overrideprotected void deliverResponse(String response) {if(mListener != null) {mListener.onResponse(response);}}/** * 空表示不上傳 */    public String getBodyContentType() {        return null;    }}

3.使用方法:

/**

* 通過put來上傳檔案

* @param url

* @param files

* @param params

* @param responseListener

* @param errorListener

* @param tag

*/

public staticvoid addPutUploadFileRequest(final Stringurl,

final Map<String, File>files, final Map<String, String> params,

final Listener<String>responseListener, final ErrorListenererrorListener,

final Objecttag) {

if (null ==url || null == responseListener) {

return;

}


MultiPartStringRequest multiPartRequest =new MultiPartStringRequest(

Request.Method.PUT,url, responseListener, errorListener) {


@Override

public Map<String, File> getFileUploads() {

returnfiles;

}


@Override

public Map<String, String> getStringUploads() {

returnparams;

}

};


Log.i(TAG," volley put : uploadFile " + url );


MainApplication.getVolleyQueue().add(multiPartRequest);

}





android實現檔案上傳的功可以

我是這樣做的
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, "請選擇一個要上傳的檔案"), 1);
然後選擇檔案後調用
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
Uri uri = data.getData();
String url= uri.toString();


獲得路徑,根據路徑調用
public String convertCodeAndGetText(String str_filepath) {// 轉碼\
try {
File file1 = new File(str_filepath);
file_name = file1.getName();
FileInputStream in = new FileInputStream(file1);
byte[] buffer = new byte[(int) file1.length() + 100];
int length = in.read(buffer);
load = Base64.encodeToString(buffer, 0, length,
Base64.DEFAULT);
in.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return load;
}
對檔案進行編碼
 
Volley有提供檔案上傳的方法?還是要自己去實現?

我想使用類比表單提交的方式,同時傳文本資料和檔案,有沒有例子? 查看原帖>>

採納哦
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.