- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 Twitter rest api,它是 ( https://api.twitter.com/1.1/ )。
首先,我使用 signpost 库来生成 oauth_signature。它运行良好。
上传状态端点 ( https://api.twitter.com/1.1/statuses/upload.json ) 运行良好,但如果 status 参数包含“@” 符号,则无法正常工作。所以这是我的代码
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, 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."}]}
但是,如果我将使用状态变量“just example”而不是“@example”(具体点是删除 @ 字符),那是可行的。只有“@”符号不起作用。
编辑
这是我通过 retrofit 拦截器手动创建 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, parameterString, "id");
parameterString = OAuthParams.addParam(request, parameterString, "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, parameterString, "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));
}
}
最佳答案
我建议选择 Fabric - https://fabric.io它有 twitter 各种库,如 twitter 登录、crashlytics 和 alss,你需要使用 android studio 设置 fabric 插件。发布你将能够发布/检索你的推文,无论你想发布什么。
对于您的问题 - 检查“@”是否为改造导致问题的特殊符号。我在不同的场景中遇到过这样的改造问题。
尝试使用 Fabric 进行 Twitter 登录/oAuth
关于android - Twitter OAuth Rest Api 状态参数 '@' 符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36743311/
我正在通读 Windows Phone 7.5 Unleashed,有很多代码看起来像这样(在页面的代码隐藏中): bool loaded; protected override void OnNav
在cgi服务器中,我这样返回 print ('Status: 201 Created') print ('Content-Type: text/html') print ('Location: htt
我正在查看 esh(easy shell)的实现,无法理解在这种情况下什么是 22 和 9 信号。理想情况下,有一个更具描述性的常量,但我找不到列表。 最佳答案 信号列表及其编号(包括您看到的这两个)
我的Oozie Hive Action 永远处于运行模式。 oozie.log文件中没有显示错误。
我正在编写一个使用 RFCOMM 通过蓝牙连接到设备的 Android 应用程序。我使用 BluetoothChat 示例作为建立连接的基础,大部分时间一切正常。 但是,有时由于出现套接字已打开的消息
我有一个云调度程序作业,它应该每小时访问我的 API 以更新一些价格。这些作业大约需要 80 秒才能运行。 这是它的作用: POST https://www.example.com/api/jobs/
我正在 Tomcat 上访问一个简单的 JSP 页面: 但是当我使用 curl 测试此页面时,我得到了 200 响应代码而不是预期的 202: $ curl -i "http://localhos
有时 JAR-RS 客户端会发送错误的语法请求正文。服务器应响应 HTTP status 400 (Bad Request) , 但它以 HTTP status 500 (Internal Serve
我正在尝试通过 response.send() 发送一个整数,但我不断收到此错误 express deprecated res.send(status): Use res.sendStatus(sta
我已经用 Excel 和 Java 做过很多次了……这次我需要用 Stata 来做,因为保存变量更方便'labels .如何将 dataset_1 重组为下面的 dataset_2? 我需要转换以下
我正在创建一个应用程序,其中的对象具有状态查找功能。为了提供一些上下文,让我们使用以下示例。 帮助台应用程序,其中创建作业并通过以下工作流程移动: 新 - 工作已创建但未分配 进行中 - 分配给工作人
我想在 Keras 中运行 LSTM 并获得输出和状态。在 TF 中有这样的事情 with tf.variable_scope("RNN"): for time_step in range
有谁知道 Scala-GWT 的当前状态 项目? 那里的主要作者 Grzegorz Kossakowski 似乎退出了这个项目,在 Spring 中从事 scalac 的工作。 但是,在 interv
我正在尝试编写一个 super 简单的 applescript 来启动 OneDrive App , 或确保打开,当机器的电源设置为插入时,将退出,或确保关闭,当电源设置为电池时。 我无法找到如何访问
目前我正在做这样的事情 link.on('click', function () { if (link.attr('href') !== $route.current.originalPath
是否可以仅通过查看用户代理来检测浏览器上是否启用/禁用 Javascript。 如果是,我应该寻找什么。如果否,检测用户浏览器是否启用/禁用 JavaScript 的最佳方法是什么 最佳答案 不,没有
Spring 和 OSGi 目前的开发状况如何? 最近好像有点安静了。 文档的最新版本 ( http://docs.spring.io/osgi/ ) 来自 2009 年。 我看到一些声明 Sprin
我正在从主函数为此类创建一个线程,但即使使用 Thread.currentThread().interrupt() 中断它,输出仍然包含“Still Here”行。 public class Writ
为了满足并发要求,我想知道如何在 Godog 中的多个步骤之间传递参数或状态。 func FeatureContext(s *godog.Suite) { // This step is ca
我有一个UIButton子类,它不使用UIImage背景,仅使用背景色。我注意到的一件事是,当您设置按钮的背景图像时,有一个默认的突出显示状态,当按下按钮时,该按钮会稍微变暗。 这是我当前的代码。
我是一名优秀的程序员,十分优秀!