web-dev-qa-db-ja.com

Android)でmultipart / form-dataアップロード画像/画像を使用する方法

これは私のコードです。

Http 400エラーが発生しました。誰か助けてもらえますか?

HttpClient   httpClient;
HttpPost     httpPost;
HttpResponse response;
HttpContext  localContext;
FileEntity   tmp = null;   
String       ret = null;

httpClient = new DefaultHttpClient( );
httpClient.getParams().setParameter( ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109) ;

httpPost = new HttpPost(url);
tmp      = new FileEntity( data,"UTF-8" );

httpPost.setEntity( tmp );
httpPost.setHeader( "Content-Type", "multipart/form-data" );
httpPost.setHeader( "access_token", facebook.getAccessToken( ) );
httpPost.setHeader( "source",       data.getAbsolutePath( ) );
httpPost.setHeader( "message",      "Caption for the photo" );

localContext = new BasicHttpContext( );
response     = httpClient.execute( httpPost,localContext );

bobince、これが私の新しいIDであるおかげで、接続ヘッダーにOAuthを入れてみます。

これは私の古いコードです。すぐに更新します。

private void uploadPicture( ) throws ParseException, IOException {
    HttpClient httpclient = new DefaultHttpClient();
    httpclient.getParams( ).setParameter( CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1 );

    HttpPost httppost = new HttpPost( "https://graph.facebook.com/me/photos" );
    File file = new File( sdpicturePath );

    // DEBUG
    Log.d( "TSET", "FILE::" + file.exists( ) ); // IT IS NOT NULL
    Log.d( "TEST", "AT:" + fbAccessToken ); // I GOT SOME ACCESS TOKEN

    MultipartEntity mpEntity  = new MultipartEntity( );
    ContentBody cbFile        = new FileBody( file, "image/png" );
    ContentBody cbMessage     = new StringBody( "TEST TSET" );
    ContentBody cbAccessToken = new StringBody( fbAccessToken );

    mpEntity.addPart( "access_token", cbAccessToken );
    mpEntity.addPart( "source",       cbFile        );
    mpEntity.addPart( "message",      cbMessage     );        

    httppost.setEntity( mpEntity );

    // DEBUG
    System.out.println( "executing request " + httppost.getRequestLine( ) );
    HttpResponse response = httpclient.execute( httppost );
    HttpEntity resEntity = response.getEntity( );

    // DEBUG
    System.out.println( response.getStatusLine( ) );
    if (resEntity != null) {
      System.out.println( EntityUtils.toString( resEntity ) );
    } // end if

    if (resEntity != null) {
      resEntity.consumeContent( );
    } // end if

    httpclient.getConnectionManager( ).shutdown( );
} // end of uploadPicture( )
11
Joseph

setEntityはリクエスト本文全体のソースを設定するため、これはdataファイルがすでにエンコードされたmultipart/form-dataブロックである場合にのみ機能します。

POSTリクエスト本文として使用するためのmultipart/form-dataエンコードされたフォーム送信を作成するには、MIMEマルチパートエンコーダー(通常はorg.Apache.http.entity.mime.MultipartEntity)が必要です。残念ながら、これはそうではありませんAndroidによってバンドルされているため、必要に応じて、Apacheから新しい HttpClient をプルする必要があります。

コードの例については この質問 を、背景については このスレッド を参照してください。

8
bobince

Apache httpライブラリを使用して、投稿付きの画像を送信するための私の実用的なソリューションがあります。

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
            byte[] imageBytes = baos.toByteArray();

            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(StaticData.AMBAJE_SERVER_URL + StaticData.AMBAJE_ADD_AMBAJ_TO_GROUP);

            String boundary = "-------------" + System.currentTimeMillis();

            httpPost.setHeader("Content-type", "multipart/form-data; boundary="+boundary);

            ByteArrayBody bab = new ByteArrayBody(imageBytes, "pic.png");
            StringBody sbOwner = new StringBody(StaticData.loggedUserId, ContentType.TEXT_PLAIN);
            StringBody sbGroup = new StringBody("group", ContentType.TEXT_PLAIN);

            HttpEntity entity = MultipartEntityBuilder.create()
                    .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                    .setBoundary(boundary)
                    .addPart("group", sbGroup)
                    .addPart("owner", sbOwner)
                    .addPart("image", bab)
                    .build();

            httpPost.setEntity(entity);

            try {
                HttpResponse response = httpclient.execute(httpPost);
                ...then reading response
3
Krystian

facebookのグラフAPIに関しては、このコードは完璧に機能します。ただし、場合によっては、ファイル名の代わりに名前を使用する必要があります。グラフAPIはrfcドキュメントと競合しているようです。

final String BOUNDERY = "3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f";
final String CRLF = "\r\n";
StringBuilder sbBody_1 = new StringBuilder();
sbBody_1.append("--" + BOUNDERY + CRLF);
sbBody_1.append("Content-Disposition: form-data; filename=\"source\"" + CRLF);
sbBody_1.append(CRLF);
StringBuilder sbBody_2 = new StringBuilder();
sbBody_2.append(CRLF + "--" + BOUNDERY + "--");
URL url = new URL("https://graph.facebook.com/me/photos?access_token=" + accessToken);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDERY);
connection.setChunkedStreamingMode(0);
OutputStream out = new BufferedOutputStream(connection.getOutputStream());
out.write(sbBody_1.toString().getBytes());
out.write(bFile);// bFile is byte array of the bitmap
out.write(sbBody_2.toString().getBytes());
out.close();
BufferedReader bips = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String temp = null;
while ((temp = bips.readLine()) != null) {
    Log.d("fbnb", temp);
}
bips.close();
connection.disconnect();
1
Shaw