Android: загрузка изображения в Twitter с использованием REST API и Fabric, ошибка сломанной трубы

Я пытаюсь создать приложение, в котором пользователь может сделать снимок и загрузить его на сервер Twitter (через конечную точку мультимедиа / загрузки), чтобы прикрепить этот мультимедийный объект к сообщению (также отправленному из приложения). Я использую Fabric для доступа к Twitter REST API. Моя проблема в том, что всякий раз, когда я пытаюсь загрузить изображение, я получаю сообщение об ошибке сломанной трубы.

Вот некоторые части моего кода:

Мой пользовательский сервис для загрузки изображения:

public interface UploadMediaService {

    @Multipart
    @POST("/1.1/media/upload.json")
    void upload(@Part("media") TypedFile file, @Part("additional_owners") String owners, com.twitter.sdk.android.core.Callback<JSONObject> cb);

}

Загрузка файла изображения:

File photo = new File(mCurrentPhotoPath);
                            TypedFile typedFile = new TypedFile("application/octet-stream", photo);    

                            RestAdapter restAdapter = new RestAdapter.Builder()
                                    .setEndpoint("https://upload.twitter.com")
                                    .setLogLevel(RestAdapter.LogLevel.FULL)
                                    .setRequestInterceptor(new RequestInterceptor() {
                                        @Override
                                        public void intercept(RequestFacade request) {

                                            request.addHeader("Authorization", createSignature(session));

                                        }
                                    })
                                    .build();

                            UploadMediaService service = restAdapter.create(UploadMediaService.class);
                            service.upload(typedFile, null, new Callback<JSONObject>() {
                                @Override
                                public void success(Result<JSONObject> twitterMediaResult) {
                                    try {
                                        Log.v("success", twitterMediaResult.data.getString("media_id_string"));

                                        MyTwitterApiClient myclient = new MyTwitterApiClient(Twitter.getSessionManager().getActiveSession());

                                        StatusWithMediaService mediaService = myclient.getStatusWithMediaService();
                                        mediaService.update("@xxxxx " + eventtype + ": \n" + comment.getText().toString(), null, false, mypos.latitude, mypos.longitude, null, true, false, twitterMediaResult.data.getString("media_id_string"), new Callback<Tweet>() {
                                            @Override
                                            public void success(Result<Tweet> tweetResult) {
                                                Toast.makeText(getActivity(), "Raportin lähettäminen onnistui.", Toast.LENGTH_SHORT).show();
                                            }

                                            @Override
                                            public void failure(TwitterException e) {
                                                TwitterApiException apiException = (TwitterApiException) e;
                                                Log.e("testapp", apiException.getErrorMessage());
                                                Log.e("testapp", apiException.getMessage());
                                            }
                                        });
                                    } catch (Exception e) {
                                        Log.e("testapp", e.getMessage());
                                    }
                                }

                                @Override
                                public void failure(TwitterException e) {
                                    Log.e("testapp", e.getMessage());
                                }
                            });

Создание подписи:

public String createSignature(TwitterSession session) {
        byte[] b = new byte[32];
        new Random().nextBytes(b);
        String randomBytes = null;

        try {
            randomBytes = URLEncoder.encode(String.valueOf(b), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            Log.e("encoding error", e.getMessage());
        }

        long currentTimeInMillis = System.currentTimeMillis();
        TwitterAuthToken authToken = session.getAuthToken();
        String token = session.getAuthToken().token;
        String signature = String.format("oauth_consumer_key=%s&oauth_nonce=%s&oauth_signature_method=HMAC-SHA1&oauth_timestamp=%s&oauth_token=%s&oauth_version=1.0", MainActivity.TWITTER_KEY, randomBytes, currentTimeInMillis, token);
        String finalSignature = null;
        try {
            finalSignature = sha1(signature, MainActivity.TWITTER_SECRET + "&" + authToken.secret);
        } catch (UnsupportedEncodingException e) {
            Log.e("encoding error", e.getMessage());
        } catch (NoSuchAlgorithmException e) {
            Log.e("algorithm error", e.getMessage());
        } catch (InvalidKeyException e) {
            Log.e("key error", e.getMessage());
        }

        String header = String.format("OAuth oauth_consumer_key=\"%s\", oauth_nonce=\"%s\", oauth_signature=\"%s\", " +
                "oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"%s\", oauth_token=\"%s\", oauth_version=\"1.0\")", MainActivity.TWITTER_KEY, randomBytes, finalSignature, currentTimeInMillis, token);

        return header;
    }

public static String sha1(String s, String keyString) throws
            UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {

        SecretKeySpec key = new SecretKeySpec((keyString).getBytes("UTF-8"), "HmacSHA1");
        Mac mac = Mac.getInstance("HmacSHA1");

        mac.init(key);
        byte[] bytes = mac.doFinal(s.getBytes("UTF-8"));

        return Base64.encodeToString(bytes, Base64.URL_SAFE);
    }

Когда я запускаю приложение, я получаю следующие вещи в logcat:

Начало HTTP-запроса:

08-07 14:48:02.932  14395-15643/com.example.test.testapp D/Retrofit﹕ ---> HTTP POST https://upload.twitter.com/1.1/media/upload.json
08-07 14:48:02.932  14395-15643/com.example.test.testapp D/Retrofit﹕ Authorization: OAuth oauth_consumer_key="XXXXX", oauth_nonce="XXXXX", oauth_signature="XXXXX", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1438948082911", oauth_token="XXXXX", oauth_version="1.0")
08-07 14:48:02.932  14395-15643/com.example.test.testapp D/Retrofit﹕ Content-Type: multipart/form-data; boundary=2d963c0d-6f81-4b88-8718-7d4100b7f8e3
08-07 14:48:02.934  14395-15643/com.example.test.testapp D/Retrofit﹕ Content-Length: 1056730
08-07 14:48:03.086  14395-15643/com.example.test.testapp D/Retrofit﹕ --2d963c0d-6f81-4b88-8718-7d4100b7f8e3
    Content-Disposition: form-data; name="media"; filename="JPEG_20150807_144749_1349351950.jpg"
    Content-Type: application/octet-stream
    Content-Length: 1056450
    Content-Transfer-Encoding: binary

Сообщения об ошибках:

08-07 14:48:04.236  14395-15643/com.example.test.testapp D/Retrofit﹕ ---- ERROR https://upload.twitter.com/1.1/media/upload.json
08-07 14:48:04.252  14395-15643/com.example.test.testapp D/Retrofit﹕ javax.net.ssl.SSLException: Write error: ssl=0x9f822c00: I/O error during system call, Broken pipe
            at com.android.org.conscrypt.NativeCrypto.SSL_write(Native Method)
            at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:765)
            at com.android.okio.Okio$1.write(Okio.java:70)
            at com.android.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:116)
            at com.android.okio.RealBufferedSink.write(RealBufferedSink.java:44)
            at com.android.okhttp.internal.http.HttpConnection$FixedLengthSink.write(HttpConnection.java:291)
            at com.android.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:116)
            at com.android.okio.RealBufferedSink$1.write(RealBufferedSink.java:131)
            at java.io.OutputStream.write(OutputStream.java:82)
            at retrofit.mime.TypedByteArray.writeTo(TypedByteArray.java:66)
            at retrofit.client.UrlConnectionClient.prepareRequest(UrlConnectionClient.java:68)
            at retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.java:37)
            at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:321)
            at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
            at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
            at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at retrofit.Platform$Android$2$1.run(Platform.java:142)
            at java.lang.Thread.run(Thread.java:818)
08-07 14:48:04.252  14395-15643/com.example.test.testapp D/Retrofit﹕ ---- END ERROR
08-07 14:48:04.261  14395-14395/com.example.test.testapp E/fail﹕ Write error: ssl=0x9f822c00: I/O error during system call, Broken pipe

У кого-нибудь есть идеи, в чем может быть проблема и как ее обойти? Заранее благодарю за любую помощь:)

0 ответов

Другие вопросы по тегам