Загрузка многопользовательского изображения Android с помощью HttpConnectionParams устарела в новых api

Я использую класс MultiPartRequester для загрузки многостраничного изображения на сервер, но я обнаружил, что в нем часть устарела. Например, HttpConnectionParams, getConnectionManager () и т. Д., Так что у кого-то есть новое решение, которое не устарело с новым уровнем API для загрузки файлов?

Я использую этот код.

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"); } } 

Это класс FileUploadMultipartRequest:

 /** * 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; } } 

Это класс BaseRequest:

 /** * 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 eg 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 eg 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(); } } 

И это класс GsonRequest:

 @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; } } } 

Образец трески:

 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); } } 

Вы можете добавить дополнительный запрос к моему запросу и позвонить в него где угодно. как это:

 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 public void OnEmptyResponse() { Toast.makeText(getApplicationContext(), "added pics successfully", Toast.LENGTH_LONG).show(); finish(); } }, new ErrorTypeListener() { @Override public void onError(ErrorType errorType) { } }); 

Серверная треска (.net):

 public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider { public CustomMultipartFormDataStreamProvider(string path) : base(path) { } //below only allows images and pdf files to be uploaded. public override Stream GetStream(HttpContent parent, System.Net.Http.Headers.HttpContentHeaders headers) { // following line handles other form fields other than files. if (String.IsNullOrEmpty(headers.ContentDisposition.FileName)) return base.GetStream(parent, headers); // restrict what filetypes can be uploaded List<string> extensions = new List<string> { "png", "gif", "jpg", "jpeg", "tiff", "pdf", "tif", "bmp","doc","docx","ods","xls","odt","csv","txt","rtf" }; var filename = headers.ContentDisposition.FileName.Replace("\"", string.Empty); // correct for chrome. //make sure it has an extension if (filename.IndexOf('.') < 0) { return Stream.Null; } //get the extension var extension = filename.Split('.').Last(); //Return stream if match otherwise return null stream. return extensions.Contains(extension) ? base.GetStream(parent, headers) : Stream.Null; } public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers) { var name = !string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName) ? headers.ContentDisposition.FileName : "NoName"; name = name.Replace("\"", string.Empty); //name = (Guid.NewGuid()).ToString() +System.IO.Path.GetExtension(name); //this is here because Chrome submits files in quotation marks which get treated as part of the filename and get escaped name = Path.GetRandomFileName().Replace(".", string.Empty) + Path.GetExtension(name); //this is here because Chrome submits files in quotation marks which get treated as part of the filename and get escaped return name; } } 

Public class ImageRouteHandler:

 IRouteHandler { public IHttpHandler GetHttpHandler(RequestContext requestContext) { var filename = requestContext.RouteData.Values["filename"] as string; var section = requestContext.RouteData.Values["section"] as string; if (string.IsNullOrEmpty(filename) && string.IsNullOrEmpty(section)) { // return a 404 HttpHandler here requestContext.HttpContext.Response.StatusCode = 404; requestContext.HttpContext.Response.End(); return null; } requestContext.HttpContext.Response.Clear(); requestContext.HttpContext.Response.Cache.SetMaxAge(TimeSpan.FromSeconds(500000)); requestContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.Public); requestContext.HttpContext.Response.ContentType = GetContentType(filename); // find physical path to image here. var path = GetPath(section); if (string.IsNullOrEmpty(path)) { // return a 404 HttpHandler here requestContext.HttpContext.Response.StatusCode = 404; requestContext.HttpContext.Response.End(); return null; } var filepath = requestContext.HttpContext.Server.MapPath(path + filename); requestContext.HttpContext.Response.WriteFile(filepath); requestContext.HttpContext.Response.End(); return null; } private static string GetPath(string section) { switch (section) { case "user": return "~/Resources/Users/";//where you want save pics in project } return ""; } private static string GetContentType(string path) { switch (Path.GetExtension(path)) { case ".bmp": return "Image/bmp"; case ".gif": return "Image/gif"; case ".jpg": return "Image/jpeg"; case ".png": return "Image/png"; } return ""; } } 

И измените свой RouteConfige следующим образом:

 public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // proccess all for protected resources with ImageRouteHandler routes.Add("ImagesRoute", new Route("res/{section}/{filename}", new ImageRouteHandler())); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } } 

Пример кода для серверной части:

 public interface IUserManagement { void UploadNewPics( IEnumerable<string> imageUrls); } public class UserManagement : IUserManagement { public void UploadNewPics(IEnumerable<string> imageUrls) { using (var ctx = new Context()) { foreach (var imageUrl in imageUrls) { //save to data base . . . } try { ctx.SaveChanges(); } catch (Exception e) { throw; } } } } public class UserApiController : ApiController { [HttpPost] public async Task<IHttpActionResult> UploadNewPics() { if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } var root = HttpContext.Current.Server.MapPath("~/Resources/Users/"); var provider = new CustomMultipartFormDataStreamProvider(root); try { // Read the form data. await Request.Content.ReadAsMultipartAsync(provider); IUserManagement userManagement = new UserManagement(); var imageUrls = provider.FileData.Select(x=> Path.GetFileName(x.LocalFileName)); //userManagement.UploadUserImage(uploadImageJson, Path.GetFileName(imageFile.LocalFileName), (long)imageFile.Headers.ContentLength); userManagement.UploadNewPics(imageUrls); } catch (Exception e) { return InternalServerError(); } return Ok(); } } 

ИМО, вы должны использовать одно из следующих:

  1. OkHttp

  2. модифицировать

  3. Волейбол Google

С помощью Volley и Retrofit yon может прочитать мои ответы на рабочем POST- запросе Multipart с помощью Volley и без HttpEntity и Retrofit – запрос на многостраничный запрос: требуемый параметр «файл» параметра MultipartFile отсутствует

Regaring OkHttp, пожалуйста, попробуйте образец проекта My GitHub с базовым примером кода следующим образом:

 // Multipart request, upload file... Drawable drawable = ContextCompat.getDrawable(mContext, R.drawable.ic_launcher); if (drawable != null) { Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 0, stream); final byte[] bitmapdata = stream.toByteArray(); OkHttpClient client = new OkHttpClient(); RequestBody requestBody = new MultipartBuilder() .type(MultipartBuilder.FORM) .addPart( Headers.of("Content-Disposition", "form-data; name=\"title\""), RequestBody.create(null, "Sample Text Content")) .addPart( Headers.of("Content-Disposition", "form-data; name=\"file\"; filename=\"ic_launcher.png\""), RequestBody.create(MEDIA_TYPE_PNG, bitmapdata)) .build(); final Request request = new Request.Builder() .url("http://192.168.1.100:20583/fileupload") .post(requestBody) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(final Request request, final IOException e) { Log.e(LOG_TAG, e.toString()); mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(mContext, e.toString(), Toast.LENGTH_SHORT).show(); mTextView.setText(e.toString()); } }); } @Override public void onResponse(Response response) throws IOException { final String message = response.toString(); Log.i(LOG_TAG, message); mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show(); mTextView.setText(message); } }); } }); } 

Надеюсь, поможет!

Да, поскольку Apache HTTPClient устарел, теперь вы можете использовать HTTPURLConnection. Я использовал этот код для отправки нескольких файлов через gmail через SMTP, вы изменяете код и используете его!

  public class sendMails extends AsyncTask<String, String, String> { ProgressDialog progress; public sendMails(Context context) { progress = new ProgressDialog(context); } @Override protected void onPreExecute() { progress.setMessage("Contacting Server!" + "\nPlease make sure internet is working!"); progress.setProgressStyle(ProgressDialog.STYLE_SPINNER); progress.setIndeterminate(true); progress.show(); progress.setCancelable(false); } @Override protected String doInBackground(String... params) { System.out.println("asd"); // Get system properties Properties props = System.getProperties(); props.put("mail.smtp.host", "smtp.gmail.com"); props.put("mail.smtp.socketFactory.port", "465"); props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.port", "465"); // Get session Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("EMAIL ADDRESS", "password"); // return new PasswordAuthentication("", "password"); } }); try { // Define message MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress("EMAIL ADDRESS")); // Set To: header field of the header. message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email)); message.setSubject("Your Photos"); String text = "Content"; message.setText(text); Multipart multipart = new MimeMultipart("mixed"); for (String str : listOfImages) { System.out.println(str); MimeBodyPart messageBodyPart = new MimeBodyPart(); DataSource source = new FileDataSource(str); messageBodyPart.setDataHandler(new DataHandler(source)); messageBodyPart.setFileName(source.getName()); multipart.addBodyPart(messageBodyPart); } message.setContent(multipart); // Send message Transport.send(message); } catch (AddressException e) { e.printStackTrace(); } catch (MessagingException e) { e.printStackTrace(); } return ""; } @Override protected void onPostExecute(String s) { setupScreenOnReciever(); progress.dismiss(); } } 
 public class MultiPartRequester { private Map<String, String> map; private AsyncTaskCompleteListener mAsynclistener; private int serviceCode; private HttpClient httpclient; private Activity activity; private AsyncHttpRequest request; public MultiPartRequester(Activity activity, Map<String, String> map, int serviceCode, AsyncTaskCompleteListener asyncTaskCompleteListener) { this.map = map; this.serviceCode = serviceCode; this.activity = activity; // is Internet Connection Available... if (AndyUtils.isNetworkAvailable(activity)) { mAsynclistener = (AsyncTaskCompleteListener) asyncTaskCompleteListener; request = (AsyncHttpRequest) new AsyncHttpRequest().execute(map .get("url")); } else { showToast("Network is not available!!!"); } } 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(), 80000); MultipartEntityBuilder builder = MultipartEntityBuilder .create(); for (String key : map.keySet()) { AppLog.Log(key, map.get(key)); builder.addTextBody(key, map.get(key), ContentType .create("text/plain", MIME.UTF8_CHARSET)); } 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"); return responseBody; } catch (Exception e) { e.printStackTrace(); } catch (OutOfMemoryError oume) { System.gc(); Toast.makeText( activity.getParent().getParent(), "Run out of memory please colse the other background apps and try again!", Toast.LENGTH_LONG).show(); } finally { if (httpclient != null) httpclient.getConnectionManager().shutdown(); } return null; } @Override protected void onPostExecute(String response) { if (mAsynclistener != null) { mAsynclistener.onTaskCompleted(response, serviceCode); } } } private void showToast(String msg) { Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show(); } public void cancelTask() { request.cancel(true); // System.out.println("task is canelled"); } } 
Intereting Posts
Как сохранить положение прокрутки RecyclerView в Android? NameValuePair, HttpParams, HttpConnection Params не рекомендуется использовать класс запроса сервера для входа в приложение Android – существует ли база данных SQLite? Как отключить физическую клавиатуру в коде (используйте виртуальную клавиатуру все время) Android – пиксели для провалов Кордовая градиентная оболочка отсутствует в android sdk SSLPeerUnverifiedException при создании SSL-соединения на Android Есть ли способ проверить, определена ли переменная в Java? Почему Android-загрузчик классов допускает отражающий доступ к публичному полю пакета-частного класса из другого пакета? Facebook Android SDK 3.0, как обмениваться контентом без LoginButton WebViewClient перенаправляется, хотя URL отсутствует Как реализовать onRetainNonConfigurationInstance Google FCM getIntent не возвращает ожидаемые данные, когда приложение находится в фоновом состоянии Bash не может найти adb, хотя определенно там Специальная проблема с URL-адресом Android Media Player