Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
806 views
in Technique[技术] by (71.8m points)

json - Android multipart image upload with HttpConnectionParams deprecated in new api

I am using MultiPartRequester class for multipart image upload to server, but i found that some part is deprecated in this. for example HttpConnectionParams , getConnectionManager() etc. so anyone have new solution that is not deprecated with new API level for file upload?

I am using this code.

public class MultiPartRequester {
private Map<String, String> map;
private AsyncTaskCompleteListener mAsynclistener;
private int serviceCode;
private HttpClient httpclient;
private Activity activity;
private AsyncHttpRequest request;
private static final String TAG = "MultiPartRequester";

public MultiPartRequester(Activity activity, Map<String, String> map,
int serviceCode, AsyncTaskCompleteListener asyncTaskCompleteListener) {
this.map = map;
this.serviceCode = serviceCode;
this.activity = activity;
}

class AsyncHttpRequest extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
map.remove("url");
try {
HttpPost httppost = new HttpPost(urls[0]);
httpclient = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(
httpclient.getParams(), 600000);
MultipartEntityBuilder builder = MultipartEntityBuilder
.create();
for (String key : map.keySet()) {
if (key.equalsIgnoreCase(AndyConstants.Params.PICTURE)) {
File f = new File(map.get(key));
builder.addBinaryBody(key, f,
ContentType.MULTIPART_FORM_DATA, f.getName());
} else {
builder.addTextBody(key, map.get(key), ContentType
.create("text/plain", MIME.UTF8_CHARSET));
}
AppLog.Log(TAG, key + "---->" + map.get(key));
}
httppost.setEntity(builder.build());
ActivityManager manager = (ActivityManager) activity
.getSystemService(Context.ACTIVITY_SERVICE);
if (manager.getMemoryClass() < 25) {
System.gc();
}
HttpResponse response = httpclient.execute(httppost);
String responseBody = EntityUtils.toString(
response.getEntity(), "UTF-8");
reurn responseBody;
} catch (Exception e) {
e.printStackTrace();
} catch (OutOfMemoryError oume) {
System.gc();
} finally {
if (httpclient != null)
httpclient.getConnectionManager().shutdown();
}
return null;
}

@Override
protected void onPostExecute(String response) {
if (mAsynclistener != null) {
mAsynclistener.onTaskCompleted(response, serviceCode);
}
}
}
public void cancelTask() {
request.cancel(true);
AppLog.Log(TAG, "task is canelled");
}
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

this is FileUploadMultipartRequest class:

/**
 * Multipart request for sending files over http
 * also can return generic type of response data
 * @param <T> the type of data for http responses
 */
public class FileUploadMultipartRequest<T> extends BaseRequest<T>
{
    private static final MediaType JSON = MediaType.parse("application/json");
    private File[] files;
    private String jsonString;
    private RequestBody requestBody;

    public FileUploadMultipartRequest(String url, Map<String, String> headers, String jsonString, OnEmptyResponseListener listener, ErrorTypeListener errorListener, File... files)
    {
        super(Method.POST, url, headers, listener, new ErrorListenerImpl(errorListener));
        this.jsonString = jsonString;
        this.files = files;
    }

    public FileUploadMultipartRequest(String url, Map<String, String> headers, String jsonString, Type responseType, Response.Listener listener, ErrorTypeListener errorListener, File... files)
    {
        super(Method.POST, url, headers, responseType, listener, new ErrorListenerImpl(errorListener));
        this.jsonString = jsonString;
        this.files = files;
    }

    @Override
    public String getBodyContentType()
    {
        return buildMultipartEntity().contentType().toString();
    }

    @Override
    public byte[] getBody() throws AuthFailureError
    {
        Buffer buffer = new Buffer();
        try
        {
            buildMultipartEntity().writeTo(buffer);
        } catch (IOException e)
        {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        return buffer.readByteArray();
    }

    private RequestBody buildMultipartEntity()
    {

        if (requestBody == null)
        {
            MultipartBuilder multipartBuilder = new MultipartBuilder().type(MultipartBuilder.FORM);

            multipartBuilder.addPart(
                    Headers.of("Content-Disposition", "form-data; name=json-part"),
                    RequestBody.create(JSON, jsonString));

            for (File file : files)
            {
                String contentType = URLConnection.guessContentTypeFromName(file.getName());
                multipartBuilder.addFormDataPart("files-part", file.getName(),
                        RequestBody.create(MediaType.parse(contentType), file));
            }

            requestBody = multipartBuilder.build();
        }
        return requestBody;
    }

}

this is BaseRequest class:

/**
 * this a abstract request class for handling http http responses
 * note : all volley request should extend this class for http request
 *
 * @param <T> the type of data for http responses
 */
public abstract class BaseRequest<T> extends Request<T>
{
    private final Map<String, String> headers;

    /**
     * the type response that {@link com.android.volley.Response.Listener} should return
     */
    private Type responseType;

    /**
     * generic listener for successful http request
     */
    private Response.Listener<T> listener;

    /**
     * constructor for request that returns data type {@link T}
     *
     * @param method        http verb e.g. POST, GET & etc
     * @param url           request URL
     * @param headers       http headers
     * @param responseType  type of data that response should return
     * @param listener      event for successful request
     * @param errorListener event for failed request
     */
    public BaseRequest(int method, String url, Map<String, String> headers, Type responseType, Response.Listener listener, ErrorListenerImpl errorListener)
    {
        super(method, url, errorListener);
        this.headers = headers;
        this.responseType = responseType;
        //noinspection unchecked
        this.listener = listener;
    }

    /**
     * constructor for requests with no returning data
     *  @param method                  http verb e.g. POST, GET & etc
     * @param url                     request URL
     * @param headers                 http headers
     * @param onEmptyResponseListener event for successful request (but no data return)
     * @param errorListener           event for failed request
     */
    public BaseRequest(int method, String url, Map<String, String> headers, OnEmptyResponseListener onEmptyResponseListener, ErrorListenerImpl errorListener)
    {
        super(method, url, errorListener);
        this.headers = headers;
        //noinspection unchecked
        listener = new OnEmptyResponseImpl(onEmptyResponseListener);
    }

    protected Response<T> parseNetworkResponse(NetworkResponse response)
    {

        // if response type is null so just pass null to success event
        if (this.responseType == null && new String(response.data).isEmpty())
        {
            return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
        }

        // if response type is specified
        try
        {
            Gson gson = new Gson();
            String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            // we use GSON to reflect response data to the generic type and pass to success event
            T parseObject = gson.fromJson(json, responseType);
            return Response.success(parseObject, HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e)
        {
            return Response.error(new ParseError(e));
        } catch (JsonSyntaxException e)
        {
            return Response.error(new ParseError(e));
        }
    }


    @Override
    protected void deliverResponse(T response)
    {
        if (listener != null)
        {
            // call successful response event when listener not empty
            listener.onResponse(response);
        }
    }

    @Override
    protected void onFinish()
    {
        super.onFinish();
        listener = null;
    }

    /**
     * this class forward response event to {@link com.khosravi.mehrdadz.garagesale.Network.RequestType.BaseRequest.OnEmptyResponseListener}
     * when volley {@link com.android.volley.Response.Listener} is called
     */
    private static class OnEmptyResponseImpl implements Response.Listener
    {
        OnEmptyResponseListener onEmptyResponseListener;

        /**
         * @param onEmptyResponseListener interface for response with not data return
         */
        public OnEmptyResponseImpl(OnEmptyResponseListener onEmptyResponseListener)
        {
            this.onEmptyResponseListener = onEmptyResponseListener;
        }

        /**
         * we call {@link com.khosravi.mehrdadz.garagesale.Network.RequestType.BaseRequest.OnEmptyResponseImpl#onEmptyResponseListener}
         * when volley listener is class so no null object passed to the event
         *
         * @param response
         */
        @Override
        public void onResponse(Object response)
        {
            onEmptyResponseListener.OnEmptyResponse();
        }
    }

    /**
     * interface for http response with no returning data
     */
    public interface OnEmptyResponseListener
    {
        void OnEmptyResponse();
    }

    public Map<String, String> getHeaders() throws AuthFailureError
    {
        return this.headers != null ? this.headers : super.getHeaders();
    }
}

and this is GsonRequest class:

@SuppressWarnings("JavaDoc")
/**
 * Gson request that return generic type of response data
 * @param <T> the type of data for http responses
 */
public class GsonRequest<T> extends BaseRequest<T>
{
    protected static final String PROTOCOL_CHARSET = "utf-8";
    /**
     * Content type for request.
     */
    private static final String PROTOCOL_CONTENT_TYPE =
            String.format("application/json; charset=%s", PROTOCOL_CHARSET);

    /**
     * message body of http request
     */
    private final String requestBody;

    /**
     * Request return response object of Type {@link T}
     * @param url
     * @param headers
     * @param type
     * @param listener
     * @param errorListener
     */
    public GsonRequest(String url, Map<String, String> headers, Type type, Listener<T> listener, ErrorTypeListener errorListener)
    {
        super(Method.GET, url, headers, type, listener, new ErrorListenerImpl(errorListener));
        requestBody = null;
    }

    /**
     * Request return response object of Type {@link T}
     * @param url
     * @param headers
     * @param jsonObject json object to send with request
     * @param type
     * @param listener
     * @param errorListener
     */
    public GsonRequest(String url, Map<String, String> headers, JSONObject jsonObject, Type type, Listener<T> listener, ErrorTypeListener errorListener)
    {
        super(Method.POST, url, headers, type, listener, new ErrorListenerImpl(errorListener));
        this.requestBody = jsonObject == null ? null : jsonObject.toString();
    }

    /**
     * Request return empty response
     * @param url
     * @param headers
     * @param jsonObject json object to send with request
     * @param listener
     * @param errorListener
     */
    public GsonRequest(String url, Map<String, String> headers, JSONObject jsonObject, OnEmptyResponseListener listener, ErrorTypeListener errorListener)
    {
        super(Method.POST, url, headers, listener, new ErrorListenerImpl(errorListener));
        this.requestBody = jsonObject == null ? null : jsonObject.toString();
    }

    /**
     * Request return empty response
     * @param url
     * @param headers
     * @param listener
     * @param errorListener
     */
    public GsonRequest(String url, Map<String, String> headers, BaseRequest.OnEmptyResponseListener listener, ErrorTypeListener errorListener)
    {
        super(Method.GET, url, headers, listener, new ErrorListenerImpl(errorListener));
        requestBody = null;
    }


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

    @Override
    public byte[] getBody()
    {
        try
        {
            return requestBody == null ? null : requestBody.getBytes(PROTOCOL_CHARSET);
        } catch (UnsupportedEncodingException uee)
        {
            VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
                    requestBody, PROTOCOL_CHARSET);
            return null;
        }
    }
}

sample cod:

public class MyRequest
{
public MyRequest(Context context)
    {
        volleySingleton = VolleySingleton.getInstance(context);
    }
private static final String INSERT_NEW_PIC = "INSERT_NEW_PIC";
public void UploadNewPic(File[] Images, BaseRequest.OnEmptyResponseListener listener, ErrorTypeListener errorListener)
    {

        FileUploadMultipartRequest fileUploadMultipartRequest = new FileUploadMultipartRequest("url", null, null, listener, errorListener,Images);
        volleySingleton.addToRequestQueue(fileUploadMultipartRequest, INSERT_NEW_PIC);
    }
}

you can add more request to my request and call that anywhere. like this:

MyRequest myRequest;
private HashMap<FrameLayout,File> Images;

myRequest = new MyRequest(context);
Images = new HashMap<>();

myRequest.UploadNewPic(Images.values().toArray(new File[Images.values().size()]),  new BaseRequest.OnEmptyResponseListener()
                    {
                        @Override
       

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...