转载注明出处哈,欢迎大家关注~ :http://blog.csdn.net/enbandarix
译者注:原文中使用Twitter4j3.0.3,由于官方api的不断更新,该版本使用起来会有问题,就像原文评论当中提到的nullpointerexception。我测试最新的4.0.1没有问题,我会将该压缩包的下载地址附在文章最后。
首先让我们谢谢原作者。
原文链接:http://hintdesk.com/how-to-tweet-in-twitter-within-android-client/comment-page-1/#comment-22392
------------------------------------------------------------------------------------------------------------------------------------------
接入社交网络没准儿会让你的应用程序显得别具一格。今天我将和大家分享一个在Android应用中接入Twitter的demo。demo当中我们使用oAuth协议让用户对Twitter授权,如果授权成功,用户可以通过我们的demo发布tweet。首先你得在Twitter上面注册一个应用,打开https://dev.twitter.com/apps,登录并创建一个应用如下图所示:
由于我们将要在android应用当中集成Twitter,所以callback URL你大可以随便填写,当然,你的应用主页会是一个不错的主意。然后到设置页面修改权限为“Read, Write and Access direct messages”,具体路径为“Application Type –> Access section”。这些选项必须激活,这样你的手机才可以直接发布消息。请千万确认刚刚的设置确实已经成功,因为我设置了3次才搞定,伤不起。
如果你读过我的上一篇博文“Google Cloud Messaging, ASP.NET Web Api and Android client”,你就会知道我们需要一个key来完成一系列的接入工作。Twitter的工作方式也非常类似,我们也需要一个key,你懂的。那么到applications –> Details 下面找到你的Consumer key和secret,记下来,待会儿你就知道怎么回事了。
(译者注:我在测试的时候看到的是api key和api secret,进入你创建的应用之后,你可以在api keys选项卡下面看到这些内容。
)
好的,现在就是万事具备,只欠东风了。你可以将Twitter的api封装成一个Library,不过为了节省时间,我决定使用http://twitter4j.org/en/提供的开源库Twitter4j来调用Twitter的api。Twitter4j并不是官方Library,所以做好思想准备哈。
With Twitter4J, you can easily integrate your Java application with the Twitter service.
Twitter4J is featuring:
✔ 100% Pure Java – works on any Java Platform version 5 or later
✔ Android platform and Google App Engine ready
✔ Zero dependency : No additional jars required
✔ Built-in OAuth support
✔ Out-of-the-box gzip support
✔ 100% Twitter API 1.1 compatible (From twitter4j.org)
下载,并把Twitterrj-core-3.0.3.jar拷到libs目录下面(译者:你需要把它引入你的buildpath,不过目测eclipse可以自动帮你把这件事搞定)。我们只是想发布一个tweet,所以core Library就足够了,如果你有更多的需求,请看Twitter4j的其他jar包。
我们的demo只有两个简单的activity,MainActivity只有一个按钮“Log in to Twitter”
另一个是TwitterActivity,这个Activity是用来发tweet的。
在主界面当中,当你启动你的app,程序会检查你的网络可用性(译者:其实国内还需要科学上网,你懂的),并且检查你的consumer key和secret。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (!OSUtil.IsNetworkAvailable(getApplicationContext())) {
AlertMessageBox.Show(MainActivity.this, "Internet connection", "A valid internet connection can't be established", AlertMessageBox.AlertMessageBoxIcon.Info);
return;
}
if (StringUtil.isNullOrWhitespace(ConstantValues.TWITTER_CONSUMER_KEY) || StringUtil.isNullOrWhitespace(ConstantValues.TWITTER_CONSUMER_SECRET)) {
AlertMessageBox.Show(MainActivity.this, "Twitter oAuth infos", "Please set your twitter consumer key and consumer secret", AlertMessageBox.AlertMessageBoxIcon.Info);
return;
}
initializeComponent();
}
还要给权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
如果前面的检查一切ok,你就可以看到“login with Twitter”的按钮,点击这个按钮时,程序会检查用户是否已经登录授权,如果是,就直接跳转到TwitterActivity,你就可以发tweet了;如果不是,对不起,请授权先。授权时会启动浏览器(或者一个具有浏览器功能的页面),用户在该页面中登录授权,成功之后则会转回TwitterActivity,后面的事儿你都知道了。
Login with Twitter的click listener长得就像这个样子:
private View.OnClickListener buttonLoginOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
if (!sharedPreferences.getBoolean(ConstantValues.PREFERENCE_TWITTER_IS_LOGGED_IN,false))
{
new TwitterAuthenticateTask().execute();
}
else
{
Intent intent = new Intent(MainActivity.this, TwitterActivity.class);
startActivity(intent);
}
}
};
上面的代码其实先检查程序的内部设置(也就是Sharedpreferences),如果PREFERENCE_TWITTER_IS_LOGGED_IN已经有值,说明程序已经授权成功了。如果没有设置,用户就需要先授权,这个过程需要执行TwitterAuthenticateTask()。
class TwitterAuthenticateTask extends AsyncTask<String, String, RequestToken> {
@Override
protected void onPostExecute(RequestToken requestToken) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(requestToken.getAuthenticationURL()));
startActivity(intent);
}
@Override
protected RequestToken doInBackground(String... params) {
return TwitterUtil.getInstance().getRequestToken();
}
}
TwitterAuthenticateTask会创建request token,并从中获得授权页面的地址。请注意打开Twitter授权链接的intent的构造,它需要一个Action叫做Intent.ACTION_VIEW。
(关于ACTION_VIEW的详细内容请参见Android api)
That is an activity action to display the data to the user. This is the most common action performed on data — it is the generic action you can use on a piece of data to get the most reasonable thing to occur. For example, when used on a contacts entry it will view the entry; when used on a mailto: URI it will bring up a compose window filled with the information supplied by the URI; when used with a tel: URI it will invoke the dialer (From Google).
在我们的程序当中,浏览器将会处理这个请求。(译者:其实我们可以自己实现一个webview,然后把url传给这个webview来完成这个工作。)
点击授权应用(Authorize app),你将需要输入用户名和密码。登录,如果成功,Twitter将会跳转回你的app;如果不成功,对不起,成人了(哈哈,原文不是这么说的)。
看起来非常简单。不过request code是如何生成的,以及Twitter又是怎么知道要跳转到哪个Activity的呢?接着看代码。在TwitterUtil.class当中,你就会看到我用单例模式完成了所有的工作,比如setOAuthConsumerKey,setOAuthConsumerSecret以及getRequestToken。。。
public final class TwitterUtil {
private RequestToken requestToken = null;
private TwitterFactory twitterFactory = null;
private Twitter twitter;
public TwitterUtil() {
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.setOAuthConsumerKey(ConstantValues.TWITTER_CONSUMER_KEY);
configurationBuilder.setOAuthConsumerSecret(ConstantValues.TWITTER_CONSUMER_SECRET);
Configuration configuration = configurationBuilder.build();
twitterFactory = new TwitterFactory(configuration);
twitter = twitterFactory.getInstance();
}
public TwitterFactory getTwitterFactory()
{
return twitterFactory;
}
public void setTwitterFactory(AccessToken accessToken)
{
twitter = twitterFactory.getInstance(accessToken);
}
public Twitter getTwitter()
{
return twitter;
}
public RequestToken getRequestToken() {
if (requestToken == null) {
try {
requestToken = twitterFactory.getInstance().getOAuthRequestToken(ConstantValues.TWITTER_CALLBACK_URL);
} catch (TwitterException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
return requestToken;
}
static TwitterUtil instance = new TwitterUtil();
public static TwitterUtil getInstance() {
return instance;
}
public void reset() {
instance = new TwitterUtil();
}
}
这个类是唯一需要你设置Consumer Key和Consumer Secret的地方。callback URL也是必须的,因为Twitter正是通过它在认证成功之后跳转指定的Activity的。在我的demo当中,我希望能够跳到TwitterActivity当中,所以TWITTER_CALLBACK_URL的值就像这个样子:
public static String TWITTER_CALLBACK_URL = "oauth://com.hintdesk.Twitter_oAuth";
咦,这看起来也跟TwitterActivity没得撒子关系嘛。对的,活还没有干完呢。在AndroidManifest.xml当中:
<activity android:name=".TwitterActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="oauth" android:host="com.hintdesk.Twitter_oAuth" />
</intent-filter>
</activity>
我们声称TwitterActivity可以被浏览器以“oauth://com.hintdesk.Twitter_oAuth”这样的数据格式唤起。所以认证成功结束之后,后面的事儿你们又都知道了。当TwitterActivity被唤起之后,你一定迫不及待的要发tweet了。呃,别着急,接着干活----不过只需要再坚持一下,当TwitterActivity启动之后,从intent当中拿到access token之后你就可以发tweet了。
private void initControl() {
Uri uri = getIntent().getData();
if (uri != null && uri.toString().startsWith(ConstantValues.TWITTER_CALLBACK_URL)) {
String verifier = uri.getQueryParameter(ConstantValues.URL_PARAMETER_TWITTER_OAUTH_VERIFIER);
new TwitterGetAccessTokenTask().execute(verifier);
} else
new TwitterGetAccessTokenTask().execute("");
}
如果有了access token,果断开始发tweet:
if (!StringUtil.isNullOrWhitespace(accessTokenString) && !StringUtil.isNullOrWhitespace(accessTokenSecret)) {
AccessToken accessToken = new AccessToken(accessTokenString, accessTokenSecret);
twitter4j.Status status = TwitterUtil.getInstance().getTwitterFactory().getInstance(accessToken).updateStatus(params[0]);
return true;
}
这个access token只有在Twitter授权成功之后,并跳转到我们的app之后才可以使用。不过一旦你拿到这个access token,你就可以把它存起来,并一直使用而不再需要任何授权了。
try {
AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, params[0]);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(ConstantValues.PREFERENCE_TWITTER_OAUTH_TOKEN, accessToken.getToken());
editor.putString(ConstantValues.PREFERENCE_TWITTER_OAUTH_TOKEN_SECRET, accessToken.getTokenSecret());
editor.putBoolean(ConstantValues.PREFERENCE_TWITTER_IS_LOGGED_IN, true);
editor.commit();
return twitter.showUser(accessToken.getUserId()).getName();
} catch (TwitterException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
params[0]就是“oauth_verifier”的值。你可以在之前给出的initControl函数当中看到。
好的,非常完美。
希望这个demo能够帮助你的应用接入Twitter并使你拓展出更多更丰富的功能。
源码代码下载地址:“Connect to Twitter in Android Phone“
------------------------------------------------------------------------------------------------------------------------------------
哇,翻译结束。话说自从去年做完科技新闻的翻译之后就再也没干过这种事儿了,我并不享受翻译这个过程,不过我觉得好的文章有必要分享给大家。
另外,由于原文所用的Twitter4j3.0.3似乎已经过时,所以我附上我用的4.0.1的下载地址:http://pan.baidu.com/s/1o6jVXGm
或到Twitter4j的官网瞅瞅:http://twitter4j.org/en/index.html (需要科学上网哦~)