Android Twitter分享,即Twitter授权Oauth然后推文

最近接触的项目要实现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); //发布推文
	}


初始化Twitter对象的代码:

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


reOauth 验证函数

	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

		}
	}


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

对返回的oauth_verifer进行处理,并与request_token一起去获取access_token & access_token_secret:

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

最后就可以用twitter发布推文了,Send按钮事件:
	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());
			}
		}
	};




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章