0

Я пытаюсь отправить изображение на сервер с помощью MultipartEntityBuilder и HttpURLConnection, а затем получить строковый ответ (в настоящее время он использует протокол http, но затем я сделаю это с помощью https с помощью этого кода или что-то очень похожее). Но когда я нажимаю кнопку для ее отправки, приложение падает, и logcat ничего не говорит мне об уловке. Код из класса, где я делаю это следующим:Отправить изображение с MultipartEntityBuilder и HttpURLConnection

public class EnvioImagenes extends AsyncTask<String, Void, String> 
{ 
    public String direccion=""; 
    public EnvioImagenes(String cuerpo){ 
     direccion=cuerpo; 
    } 


    protected String doInBackground(String... url){ 
     Bitmap bitmap = null; 
     ByteArrayOutputStream bos=new ByteArrayOutputStream(); 
     bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos); 
     ContentBody contentPart = new ByteArrayBody(bos.toByteArray(), direccion); 
     MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create(); 
     multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); 
     multipartEntity.addPart("Picture",contentPart); 

     try { 
      HttpURLConnection connection = (HttpURLConnection) new URL(url[0]).openConnection(); 
      connection.setReadTimeout(10000); 
      connection.setConnectTimeout(15000); 
      connection.setRequestMethod("POST"); 
      connection.setUseCaches(false); 
      //Si quiero enviar/recibir una respuesta en el cuerpo del mensaje, tiene que estar lo siguiente: 
      connection.setDoInput(true); 
      connection.setDoOutput(true); 
      connection.setRequestProperty("Connection", "Keep-Alive"); 
      String boundary= "--------------"+System.currentTimeMillis(); 
      multipartEntity.setBoundary(boundary); 
      connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); 
      DataOutputStream dos=new DataOutputStream(connection.getOutputStream()); 
      //connection.addRequestProperty(multipartEntity.getClass().getName(), multipartEntity.getClass().toString()); 
      //OutputStream output=new BufferedOutputStream(connection.getOutputStream()); 
      dos.writeBytes("\r\n"); 
      dos.flush(); 
      dos.close(); 
      //output.write(body.getBytes()); 
      //output.flush(); 

      int responseCode = connection.getResponseCode(); 
      InputStream inputStream = connection.getInputStream(); 
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 
      String line; 
      StringBuilder result = new StringBuilder(); 

      while ((line = bufferedReader.readLine()) != null) { 
       result.append(line); 
      } 

      String responseString = result.toString(); 
      inputStream.close(); 
      connection.disconnect(); 
      return responseString; 

     } catch(Exception exc) { 
      String error = exc.toString(); 
      Log.e("This is the mistake.....", exc.getMessage()); 
      return error; 
     } 
    } 
} 

Я скачал библиотеку MultipartEntityBuilder скачивания его как ссылка говорит: Android - MultipartEntity and dependencies. Проблема заключается в том, что, когда чеки build.gradle если everithing является Окей, он показывает мне это предупреждение:

Warning:WARNING: Dependency org.apache.httpcomponents:httpclient:4.5.3 is ignored for release as it may be conflicting with the internal version provided by Android. 
     In case of problem, please repackage it with jarjar to change the class packages. 

Я пытался решить ее загрузку пакета из браузера, а затем вставить его в папку/Lib внутри библиотеку, а затем сменить код из build.gradle, чтобы программа проверила библиотеки там, но затем я ошибся, что библиотеки в коде, где я использую MultipartEntityBuilder, не были обнаружены; поэтому я думаю, что проблема заключается в самом коде: особенно потому, что я не использую httpClient. Для любого вопроса, код от build.gradle на самом деле это:

apply plugin: 'com.android.application' 

android { 
    compileSdkVersion 24 
    buildToolsVersion "24.0.0" 

    defaultConfig { 
     applicationId "com.example.franco.pruebalogin" 
     minSdkVersion 10 
     targetSdkVersion 24 
     versionCode 1 
     versionName "1.0" 
    } 
    buildTypes { 
     release { 
      minifyEnabled false 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     } 
    } 
} 
dependencies { 
    compile fileTree(include: ['*.jar'], dir: 'libs') 
    testCompile 'junit:junit:4.12' 
    compile 'com.android.support:appcompat-v7:24.0.0' 
    compile 'com.android.support:design:24.0.0' 
    compile 'org.apache.httpcomponents:httpmime:4.5.3' 
} 

ответ

0

Я пошел по этому пути, но в конце концов переехал использовать SyncHttpClient.

private static final String COMPRESSED_FILE_PREFIX = "yourapp_image_compressed_"; 
private static final String JPEG_FILE_EXTENSION = ".jpeg"; 
private static final int FIVE_MINUTE_INIT_TIMEOUT = 300000; 

public void uploadImage(Context applicationContext, ArrayList<String> filePathsToUpload) { 
     RequestParams requestParams = new RequestParams(); 

     File imagesCacheDir; 

     if (android.os.Environment.getExternalStorageState().equals(
       android.os.Environment.MEDIA_MOUNTED)) { 
      imagesCacheDir = new File(
        android.os.Environment.getExternalStorageDirectory(), 
        "/Android/data/com.example.yourapp/UploadPics"); 
     } else { 
      imagesCacheDir = applicationContext.getCacheDir(); 
     } 

     if (!imagesCacheDir.exists()) { 
      if (!imagesCacheDir.mkdirs()) { 
       throw new RuntimeException("Image directory could not be created."); 
      } 
     } 

     for (String filePath : filePathsToUpload) { 
      File file; 

      try { 
       FileOutputStream out = new FileOutputStream(new File(imagesCacheDir, 
         COMPRESSED_FILE_PREFIX + filePathsToUpload.size() + 1 + JPEG_FILE_EXTENSION)); 

       BitmapFactory.decodeFile(filePath).compress(Bitmap.CompressFormat.JPEG, compress ? 90 : 100, out); 

       file = new File(imagesCacheDir, COMPRESSED_FILE_PREFIX + filePathsToUpload.size() + 1 + JPEG_FILE_EXTENSION); 
       requestParams.put(file.getName(), file); 
       out.close(); 
      } catch (FileNotFoundException fnfe) { 
       throw new RuntimeException("Image file not found."); 
      } catch (IOException ie) { 
       throw new RuntimeException("Error writing image to file.); 
      } 
     } 

     SyncHttpClient client = new SyncHttpClient(); 
     client.setTimeout(FIVE_MINUTE_INIT_TIMEOUT); 

     Map<String, String> headers = VolleyUtils.getBigOvenHeaders(); 
     headers.putAll(VolleyUtils.getAuthenticationHeader()); 

     for (String headerKey : headers.keySet()) { 
      client.addHeader(headerKey, headers.get(headerKey)); 
     } 

     MySSLSocketFactory socketFactory; 

     try { 
      KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
      trustStore.load(null, null); 
      socketFactory = new MySSLSocketFactory(trustStore); 
      socketFactory.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
      client.setSSLSocketFactory(socketFactory); 
     } catch (Exception e) { 
      // Probably should die or something, unless http is okay (if you need https, this is no go) 
     } 

     client.setTimeout(FIVE_MINUTE_INIT_TIMEOUT); 

     client.post(this, "https://www.myapp.com/imageUploader", requestParams, new RotatingBitmapTextHttpResponseHandler(filePathsToUpload, notificationBuilder, onCompletionText)); 
} 

Вы можете изменить HttpResponseHandler на все, что захотите. В этом случае я создал класс, который отслеживает прогресс и показывает его в уведомлении. Вместо этого вы можете делать все, что хотите.

+0

То, что я хочу получить в качестве ответа, - это строка, в которой говорится, что сервер правильно получил изображение. Но с этим у вас не было проблемы с библиотекой или прямо вам это не нужно? Как вы можете получить ответ с сервера после этого? Я хочу использовать что-то, что тогда я могу написать https-ответ (сегодня у меня нет сертификата, поэтому я использую то, что использует дважды, а затем меняю его). Я напишу для любых вопросов те вещи в сообщении –

+0

Вы используете TextHttpResponseHandler, чтобы вернуть ответ сервера. Передайте его в метод client.post() выше. Заголовки onSuccess (int statusCode, Header [], String responseString) предоставят вам то, что вы ищете. –

+0

Может ли SyncHttpClient работать с http и https без больших изменений, например HttpUrlConnection? Нужна ли дополнительная библиотека, например MultipartEntityBuilder? –

Смежные вопросы