最近接触的项目要实现Twitter,Facebook,Email的分享功能。当然Android可以简单的用Intent调用第三方App实现这些功能。但是如果需求变态需要你自己写一个分享功能呢?
先介绍一下Twitter的分享:
Twiter这里我使用了twitter4j-core-android-2.2.6.jar这个是给android用的twitter4j的精简包,体积小。
授权(Oauth)流程如下:
1) 注册申请Twitter的开发者,创建App,获得开发者的Key和Secret,即consumer_key & consumer_secret
2) 用Http通过Twitter提供的Api url + 参数consumer_key & consumer_secret到Twitter的服务器获取request_token
3) 用Http通过Twitter提供的Api url + 参数request_token到Twitter服务器请求授权
4) 授权确认后页面跳转到由你之前注册时填写的callback_url为地址前缀的的一个新网址(页面),并获取到oauth_verifer
5) 最后,再发送request_token & oauth_verifer到Twitter服务器换取access_token & access_token_secret, 有了这两个值就可以通过它们进行各种Twitter操作。
以上是授权的一个通用过程,但是在实现中需要考虑一些问题,因此有以下流程:
1\ 从手机的文件存储中读取access_token & access_token_secret,,如果没有继续2\,有就直接设置它们到twitter对象中,然后到5\
2\ 进行授权,前提是要已经设置consumer_key & consumer_secret到了twitter对象中,向服务器获取request_token(代码实现中是要求传递call_back_url作为参数)
3\ 获取到request_token后将request_token作为参数传递并开启一个有WebView的Activity,然后自己用浏览器处理获取oauth_verifer,并将其作为参数传回给之前的那个Activity
这里说一下用一个带WebView 的Activity处理的好处,一个是在有多个第三方浏览器的时候直接用Intent会没办法关闭第三方浏览器,不过其实最关键的是我在使用系统自带的浏览器的获取oauth_verifierr时,虽然XML有写回调数据的处理(<data android:scheme="http" android:host="app.com"),但是没有效果,于是我就在webview 的 onPageFinished()回调方法中自己获取它callback_url后面带的oauth_verifer参数值
4\ 在之前的Activity里用接收到的oauth_verifer继续处理,向服务器获取access_token & access_token_secret,并且设置到twitter对象中,并且把它存入文件
5\ 用twitter对象进行一些twitter操作
注意:在5\ 中操作时会遇到如果用户撤销了授权的一些情况,这个时候就会抛出异常,此时就需要从2\开始再一次进行授权。
关键的代码:
在onCreate()里初始化以及设置组件:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_twitter); mPrefs = App.getInstance().getAppPrefs(); //获得操作文件系统的对象 InitializeTwitter(); //初始化Twitter对象 Intent intent = getIntent(); if (intent != null) { preview_url = intent.getStringExtra("preview_url"); //Intent传过来的一个字符串,把它作为推文 } String accessToken = mPrefs.getTwitterAccessToken(); String accessTokenSecret = mPrefs.getTwitterAccessTokenSecret(); if (accessToken == null || accessTokenSecret == null) { //从文件系统里读取的access_token 和 access_token_secret的判断 reOauth(); //验证以及出问题的重复验证都会用这个函数 } else { twitter.setOAuthAccessToken(new AccessToken(accessToken, accessTokenSecret)); } close = (Button)findViewById(R.id.btn_close); send = (Button)findViewById(R.id.btn_send); content = (EditText)findViewById(R.id.edit_content); //在这个Activity上用于显示推文内容 close.setOnClickListener(closeListener); //关闭,调用finish() send.setOnClickListener(sendListner); //发布推文 }
private void InitializeTwitter() { ConfigurationBuilder builder = new ConfigurationBuilder(); builder.setOAuthConsumerKey(AppConstants.TWITTER_CONSUMER_KEY); //consumer_key builder.setOAuthConsumerSecret(AppConstants.TWITTER_CONSUMER_SECRET); //consumer_secret Configuration conf = builder.build(); twitter = new TwitterFactory(conf).getInstance(); twitter.setOAuthAccessToken(null); }
private void reOauth() { try { twitter.setOAuthAccessToken(null); requestToken = twitter.getOAuthRequestToken(AppConstants.TWITTER_CALLBACK_URL); //获取requestToken } catch (TwitterException e) { Log.d("TEST", e.getMessage()); } if (requestToken != null) { Intent i = new Intent(this, WebsiteActivity.class); i.putExtra(AppConstants.EXTRA_URL, requestToken.getAuthenticationURL()); startActivityForResult(i, TITTER_OAUTH); //开启一个带webview的Activity处理,名字为WebsiteActivity } }
private class MyWebViewClient extends WebViewClient { //要求是可以点击其他超练级继续浏览网页的,因此继承WebViewClient实现 @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } @Override public void onPageFinished(WebView view, String url) { //在网页加载结束后,对callback_url带回的参数进行获取。并关闭这个activity super.onPageFinished(view, url); progressbar.setVisibility(View.GONE); if (url != null && url.startsWith(AppConstants.TWITTER_CALLBACK_URL)) { String oauthVerifer = Uri.parse(url). getQueryParameter(AppConstants.TWITTER_OAUTH_VERIFIER); Intent i = new Intent(); i.putExtra(AppConstants.TWITTER_OAUTH_VERIFIER, oauthVerifer); setResult(RESULT_OK, i); //把获取的oauth_verifer finish(); } } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); progressbar.setVisibility(View.VISIBLE); } }
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.d("TEST", "Twitter onActivityResult()"); if (requestCode == TITTER_OAUTH) { if (resultCode == Activity.RESULT_OK) { oauthVerifier = data.getStringExtra(AppConstants.TWITTER_OAUTH_VERIFIER); try { AccessToken at = twitter.getOAuthAccessToken(requestToken, oauthVerifier); String accessToken = at.getToken(); String accessTokenSecret = at.getTokenSecret(); twitter.setOAuthAccessToken(at); //这里要设置access_token mPrefs.setTwitterAccessToken(accessToken); //记得存入文件系统 mPrefs.setTwitterAccessTokenSecret(accessTokenSecret); } catch (TwitterException e) { Log.d("TEST", e.getMessage()); } } } }
private View.OnClickListener sendListner = new View.OnClickListener() { @Override public void onClick(View v) { try { twitter.updateStatus(content.getText().toString() + preview_url); } catch (TwitterException e) { reOauth(); //在用户撤销授权或者删除app的时候,会抛出异常,这里就可以再次重新授权 Log.d("TEST", e.getMessage()); } } };