android – Twitter OAuth Rest Api状态参数’@’符号

我正在使用twitter rest api,这是( https://api.twitter.com/1.1/).

首先,我使用路标库生成oauth_signature.它运作良好.

上传状态端点(https://api.twitter.com/1.1/statuses/upload.json)运行良好,但如果状态参数包含“@”符号,则表示无效.所以这是我的代码

TwitterStatusesService.java

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Query;

public interface TwitterStatusesService {
    @POST("/1.1/statuses/update.json")
    Call<ResponseBody> update(@Query("status") String status,@Query("in_reply_to_status_id") String inReplyToStatusId,@Query("lat") Double lat,@Query("long") Double lon,@Query("media_ids") String mediaIds);
}

TwitterStatusesapiclient.java

import android.util.Log;

import com.twitter.sdk.android.core.TwitterauthToken;
import com.twitter.sdk.android.core.TwitterCore;
import com.twitter.sdk.android.core.TwitterSession;

import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Retrofit;
import se.akerfeldt.okhttp.signpost.OkHttpOAuthConsumer;
import se.akerfeldt.okhttp.signpost.SigningInterceptor;

public class TwitterStatusesClient {

    private final String TAG = getClass().getSimpleName();

    private static final String BASE_URL = "https://api.twitter.com/";

    private final TwitterStatusesService apiService;

    private static TwitterStatusesClient webServiceClient;

    public static TwitterStatusesClient getInstance() {
        if (webServiceClient == null)
            webServiceClient = new TwitterStatusesClient();
        return webServiceClient;
    }

    private TwitterStatusesClient() {
        private TwitterStatusesClient() {
        OkHttpOAuthConsumer consumer = new OkHttpOAuthConsumer(TWITTER_KEY,TWITTER_SECRET);

        TwitterSession activeSession = TwitterCore.getInstance().getSessionManager().getActiveSession();
        if (activeSession != null) {
            TwitterauthToken authToken = activeSession.getAuthToken();
            String token = authToken.token;
            String secret = authToken.secret;
            consumer.setTokenWithSecret(token,secret);
        }

        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(new SigningInterceptor(consumer))
                .build();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .build();

        apiService = retrofit.create(TwitterStatusesService.class);
    }

    public Call<ResponseBody> update(String status,String statusId,Double lat,Double lon,String mediaIds) {
        return apiService.update(status,statusId,lat,lon,mediaIds);
    }
}

调用api客户端

String status = "@example";
TwitterStatusesClient.getInstance().update(status,null,null).enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call,Response<ResponseBody> response) {
            Log.v(TAG,"onResponse");
            progressDialog.dismiss();
            try {
                if (response.errorBody() != null) {
                    String error = response.errorBody().string();
                    Log.e(TAG,"Error : " + error);
                    ToastUtils.showErrorMessage(getContext(),"Error : " + error);
                    return;
                }

                String body = response.body().string();
                Log.v(TAG,"body : " + body);
            } catch (Exception e) {
                e.printstacktrace();
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call,Throwable t) {
            Log.v(TAG,"onFailure");
            t.printstacktrace();
        }
    });

给出错误

{"errors":[{"code":32,"message":"Could not authenticate you."}]}

但是,如果我将使用状态变量“只是示例”而不是“@example”(具体点是删除@字符)正在工作.只有’@’符号不起作用.

编辑

这是我通过改装拦截器手动创建OAuth v1.0a签名签名代码

OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Interceptor.Chain chain) throws IOException {
                    Request request = chain.request();

                    String method = request.method();
                    String baseUrl = "https://api.twitter.com" + request.url().url().getPath();

                    String oauthToken = "";
                    String oauthTokenSecret = "";

                    TwitterSession activeSession = TwitterCore.getInstance().getSessionManager().getActiveSession();
                    if (activeSession != null) {
                        TwitterauthToken authToken = activeSession.getAuthToken();
                        oauthToken = authToken.token;
                        oauthTokenSecret = authToken.secret;
                    }

                    String oauthNonce = "TXZScw4M8TG";
                    String oauthSignatureMethod = "HMAC-SHA1";
                    String oauthTimestamp = String.valueOf(System.currentTimeMillis() / 1000);
                    String oauthVersion = "1.0";

                    String parameterString = "";

                    parameterString = OAuthParams.addParam(request,parameterString,"count");
                    parameterString = OAuthParams.addParam(request,"id");
                    parameterString = OAuthParams.addParam(request,"in_reply_to_status_id");

                    // if any parameter added to parameterString,append '&' character.
                    if (parameterString.length() > 0) {
                        parameterString += "&";
                    }

                    parameterString += "oauth_consumer_key=" + TWITTER_KEY + "&"
                            + "oauth_nonce=" + oauthNonce + "&"
                            + "oauth_signature_method=" + oauthSignatureMethod + "&"
                            + "oauth_timestamp=" + oauthTimestamp + "&"
                            + "oauth_token=" + oauthToken + "&"
                            + "oauth_version=" + oauthVersion;

                    // add status parameter to parameterString.
                    parameterString = OAuthParams.addParam(request,"status");

                    Log.d(TAG,"normalizedParameters : " + parameterString);
                    Log.d(TAG,"parameterStringPercent : " + OAuth.percentEncode(parameterString));

                    String signatureBaseString = "";
                    signatureBaseString += OAuth.percentEncode(method) + "&";
                    signatureBaseString += OAuth.percentEncode(baseUrl) + "&";
                    signatureBaseString += OAuth.percentEncode(parameterString);

                    String oauthSignature = OauthSignature.generateSignature(signatureBaseString,TWITTER_SECRET,oauthTokenSecret);

                    String authorization = "OAuth oauth_consumer_key=\"" + TWITTER_KEY + "\"," +
                            "oauth_signature_method=\"HMAC-SHA1\"," +
                            "oauth_timestamp=\"" + oauthTimestamp + "\"," +
                            "oauth_nonce=\"" + oauthNonce + "\"," +
                            "oauth_version=\"1.0\"," +
                            "oauth_token=\"" + oauthToken + "\"," +
                            "oauth_signature=\"" + OAuth.percentEncode(oauthSignature) + "\"";

                    Log.w(TAG,"Authorization : " + authorization);

                    request = request.newBuilder()
                            .addHeader("Authorization",authorization)
                            .build();
                    return chain.proceed(request);
                }
            }).addInterceptor(interceptor).build();

OAuth.java

public static String percentEncode(String s) {
    if (s == null) {
        return "";
    }
    try {
        return URLEncoder.encode(s,ENCODING)
                // OAuth encodes some characters differently:
                .replace("+","%20").replace("*","%2A")
                .replace("%7E","~");
        // This Could be done faster with more hand-crafted code.
    } catch (UnsupportedEncodingException wow) {
        throw new RuntimeException(wow.getMessage(),wow);
    }
}

OAuthSignature.java

import android.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class OauthSignature {

public static String generateSignature(String signatueBaseStr,String oAuthConsumerSecret,String oAuthTokenSecret) {
    byte[] byteHMAC = null;
    try {
        Mac mac = Mac.getInstance("HmacSHA1");
        SecretKeySpec spec;
        if (null == oAuthTokenSecret) {
            String signingKey = OAuth.percentEncode(oAuthConsumerSecret) + '&';
            spec = new SecretKeySpec(signingKey.getBytes(),"HmacSHA1");
        } else {
            String signingKey = OAuth.percentEncode(oAuthConsumerSecret) + '&' + OAuth.percentEncode(oAuthTokenSecret);
            spec = new SecretKeySpec(signingKey.getBytes(),"HmacSHA1");
        }
        mac.init(spec);
        byteHMAC = mac.doFinal(signatueBaseStr.getBytes());
    } catch (Exception e) {
        e.printstacktrace();
    }
    return new String(Base64.encode(byteHMAC,Base64.DEFAULT));
}
}

解决方法

我建议使用面料 – https://fabric.io,它有各种各样的libs,如twitter登录,crashlytics和alss,你需要设置与Android工作室的面料插件.发布您可以发布/检索推文,无论您想发布什么.

对于您的问题 – 检查’@’是特殊符号,其中改造导致问题.这些问题是我在不同场景中遇到的改造.

尝试使用Fabric进行Twitter登录/ oAuth

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...