0

Ich versuche, ein Bild an einen Server mit MultipartEntityBuilder und HttpURLConnection zu senden, und erhalten dann eine String-Antwort (heutzutage verwendet HTTP-Protokoll, aber ich werde es mit https mit diesem Code tun, oder etwas sehr ähnliches). Aber wenn ich den Knopf drücke, um es zu senden, stürzt die App ab und der Logcat sagt mir nichts über den Fang. Der Code aus der Klasse, wo ich es tun, ist der nächste:Senden Sie ein Bild mit MultipartEntityBuilder und 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; 
     } 
    } 
} 

Ich habe die MultipartEntityBuilder Bibliothek Download es so Link sagt: Android - MultipartEntity and dependencies. Das Problem ist, dass, wenn die build.gradle prüft, ob everithing okey ist, es zeigt mir diese Warnung:

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. 

habe ich versucht, es zu lösen, das Paket aus dem Browser herunterzuladen und Einfügen dann in dem Ordner/lib innen die Bibliothek, und dann den Code von der build.gradle zu ändern, damit das Programm die Bibliotheken von dort überprüft, aber dann hatte ich den Fehler, dass die Bibliotheken in dem Code, wo ich den MultipartEntityBuilder verwende, nicht erkannt wurden; Ich denke, das Problem ist auf den Code selbst zurückzuführen, vor allem, weil ich den httpClient nicht verwende. Für jede Frage, ist der Code von build.gradle eigentlich diese:

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' 
} 

Antwort

0

Ich ging diesen Weg nach unten zog aber letztlich SyncHttpClient zu verwenden.

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

Sie können den HttpResponseHandler auf das ändern, was Sie wollen. In diesem Fall habe ich eine Klasse erstellt, die den Fortschritt verfolgt und in einer Benachrichtigung anzeigt. Sie können stattdessen tun, was Sie möchten.

+0

Was ich als Antwort erhalten möchte, ist eine Zeichenfolge, die besagt, dass der Server das Bild korrekt empfangen hat. Aber damit hattest du kein Problem mit der Bibliothek oder direkt, du hast es nicht gebraucht? Wie können Sie danach eine Antwort vom Server erhalten? Ich möchte etwas verwenden, das ich dann eine https Antwort schreiben kann (heute habe ich das Zertifikat nicht, so verwende ich etwas, das zweimal verwendet und dann werde ich es ändern). Ich werde für alle Fragen diese Dinge in der Post schreiben –

+0

Sie verwenden TextHttpResponseHandler, um die Antwort des Servers zurück. Übergeben Sie es in die client.post() -Methode oben. Die onSuccess (int statusCode, Header [] Header, String responseString) geben Ihnen, was Sie suchen. –

+0

Kann SyncHttpClient mit http und https ohne große Änderungen wie HttpUrlConnection arbeiten? Braucht es eine zusätzliche Bibliothek wie MultipartEntityBuilder? –

Verwandte Themen