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




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