繁体   English   中英

Android:尝试使用Fabric和Twitter REST API推媒体时出现“ 400错误请求”错误

[英]Android: “400 bad request” error when trying to tweet with media using Fabric and Twitter REST API

我正在尝试构建一个应用程序,用户可以在其中发布图像并附加图像。 我正在使用Fabric进行Twitter集成,并在推文中尝试扩展API客户端,以制作Statuses Service更新方法的改进版本。 我不想使用Tweet Composer进行图像推文,因为我想避免使用plus UI调用,并且我也希望能够在推文中包含位置。

这是我的自定义Twitter API客户端类:

public class MyTwitterApiClient extends TwitterApiClient {

    public MyTwitterApiClient(TwitterSession session)
    {
        super(session);
    }

    public StatusWithMediaService getStatusWithMediaService() {
        return  getService(StatusWithMediaService.class);
    }


}

public interface StatusWithMediaService {
    @FormUrlEncoded
    @POST(value="/1.1/statuses/update.json")
    void update(@Field(value="status")
                java.lang.String status,
                @Field(value="in_reply_to_status_id")
                java.lang.Long inReplyToStatusId,
                @Field(value="possibly_sensitive")
                java.lang.Boolean possiblySensitive,
                @Field(value="lat")
                java.lang.Double latitude,
                @Field(value="long")
                java.lang.Double longitude,
                @Field(value="place_id")
                java.lang.String placeId,
                @Field(value="display_cooridnates")
                java.lang.Boolean displayCoordinates,
                @Field(value="trim_user")
                java.lang.Boolean trimUser,
                @Field(value ="media_ids")
                String mediaIds,
                com.twitter.sdk.android.core.Callback<Tweet> cb);
}

这是我尝试鸣叫的代码的一部分(到目前为止,我为媒体实体使用了静态值-我使用twurl上传的图片的ID):

submit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (eventtype != null && mypos != null) {

                    final TwitterSession session = Twitter.getSessionManager().getActiveSession();

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

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

                    }
                })
                .build();

                StatusWithMediaService mediaService = restAdapter.create(StatusWithMediaService.class);

                    mediaService.update("@xxxx " + eventtype + ": \n" + comment.getText().toString(), null, false, mypos.latitude, mypos.longitude, null, true, false, "628524774898180096", 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) {
                            Log.e("testapp", e.getMessage());
                        }
                    });
                }
                else
                {
                    Toast.makeText(getActivity(), "Puuttuvat tiedot: sijainti", Toast.LENGTH_SHORT).show();
                }
            }
        });

创建签名的功能:

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

当我运行该应用程序并尝试进行鸣叫时,出现以下错误消息: 400 Bad Request

问题是什么? 我应该怎么做? 我是Fabric,Twitter REST API和Retrofit的新手,所以我将感谢经验丰富的成员的建议:)预先感谢!

编辑:

我试图记录发送到服务器的请求和得到的响应,现在我在logcat中得到了:

08-05 10:46:54.364  20026-20561/com.example.test.testapp D/testapp retrofit﹕ ---HTTP POST https://api.twitter.com/1.1/statuses/update.json
08-05 10:46:54.364  20026-20561/com.example.test.testapp D/testapp retrofit﹕ Authorization: OAuth oauth_consumer_key="XXXXX", oauth_nonce="XXXXX", oauth_signature="XXXXX", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1438760814359", oauth_token="XXXXX", oauth_version="1.0")
08-05 10:46:54.364  20026-20561/com.example.test.testapp D/testapp retrofit﹕ Content-Type: application/x-www-form-urlencoded; charset=UTF-8
08-05 10:46:54.364  20026-20561/com.example.test.testapp D/testapp retrofit﹕ Content-Length: 164
08-05 10:46:54.366  20026-20561/com.example.test.testapp D/testapp retrofit﹕ status=%40tkl_testi+Onnettomuus%3A+%0A&possibly_sensitive=false&lat=61.4892668&long=23.7791515&display_cooridnates=true&trim_user=false&media_ids=628825606512316416
08-05 10:46:54.366  20026-20561/com.example.test.testapp D/testapp retrofit﹕ ---> END HTTP (164-byte body)
08-05 10:46:55.170  20026-20561/com.example.test.testapp D/testapp retrofit﹕ <--- HTTP 400 https://api.twitter.com/1.1/statuses/update.json (803ms)
08-05 10:46:55.170  20026-20561/com.example.test.testapp D/testapp retrofit﹕ : HTTP/1.0 400 Bad Request
08-05 10:46:55.170  20026-20561/com.example.test.testapp D/testapp retrofit﹕ content-length: 0
08-05 10:46:55.170  20026-20561/com.example.test.testapp D/testapp retrofit﹕ date: Wed, 05 Aug 2015 07:46:55 GMT
08-05 10:46:55.170  20026-20561/com.example.test.testapp D/testapp retrofit﹕ server: tsa_b
08-05 10:46:55.170  20026-20561/com.example.test.testapp D/testapp retrofit﹕ X-Android-Received-Millis: 1438760815133
08-05 10:46:55.170  20026-20561/com.example.test.testapp D/testapp retrofit﹕ X-Android-Response-Source: NETWORK 400
08-05 10:46:55.170  20026-20561/com.example.test.testapp D/testapp retrofit﹕ X-Android-Sent-Millis: 1438760814969
08-05 10:46:55.170  20026-20561/com.example.test.testapp D/testapp retrofit﹕ x-connection-hash: fb74c0c2ee1c7830163453a33dd099de
08-05 10:46:55.170  20026-20561/com.example.test.testapp D/testapp retrofit﹕ <--- END HTTP (0-byte body)

众所周知,错误的请求错误可能表示格式错误的请求(例如JSON问题),但是,根据Twitter REST API文档和其他用户的示例,我的请求应该没问题。 我还尝试发送一条没有任何媒体ID的推文(至于其他字段,我完全遵循了Fabric Statuses Service的update方法中提供的格式,应该可以使用),在这种情况下,我也遇到了同样的错误。 现在我完全迷路了。 有人可以帮我吗?

编辑:

现在,我不再使用Retrofit REST适配器,而是通过自定义Twitter API客户端调用自定义更新方法,因此代码的更新部分现在如下所示:

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

                    StatusWithMediaService mediaService = myclient.getStatusWithMediaService();
                    mediaService.update("@xxxx " + eventtype + ": \n" + comment.getText().toString(), null, false, mypos.latitude, mypos.longitude, null, true, false, "629232743633842180", 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());
                        }
                    });

现在,我可以不带图像(媒​​体ID)进行发布,但是当我尝试使用媒体ID进行发布时,出现以下错误: The validation of media ids failed.

我可以使用twurl成功发布相同的tweet,所以我认为问题不在于图像。 我使用twurl手动上传图像,并使用它返回的ID。 我总是在尝试发布之前上载新图像,因此问题不在于重复的ID。 现在我显然不知道实际出了什么问题。 有人能帮我吗?

好的,原来是我的一个愚蠢的错误。 当我用twurl发布图像时,我是使用与我在应用程序中使用的帐户不同的Twitter帐户进行操作的。 为了在推文中使用,上载的媒体必须来自同一用户或包括其他用户作为其他所有者(具有Additional_owners参数),这一点很重要。 在twurl中切换帐户后,一切正常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM