1. 程式人生 > >Android實現新浪微博和QQ登陸並獲取使用者的資訊

Android實現新浪微博和QQ登陸並獲取使用者的資訊

首先在新浪微博和騰訊的開發平臺下載相應的SDK,這裡不作介紹,直接上程式碼:

LoginActivity.java

package com.qingning.share;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONObject;

import com.qingning.share.util.Constant;
import com.sina.weibo.sdk.auth.AuthInfo;
import com.sina.weibo.sdk.auth.Oauth2AccessToken;
import com.sina.weibo.sdk.auth.WeiboAuthListener;
import com.sina.weibo.sdk.auth.sso.SsoHandler;
import com.sina.weibo.sdk.exception.WeiboException;
import com.tencent.connect.UserInfo;
import com.tencent.connect.auth.QQToken;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.Toast;

public class LoginActivity extends Activity {
	private Context mContext;
	private Window mWindow;
	
	/** 新浪微博登陸相關 **/
	private AuthInfo mAuthInfo;
	/** 注意:SsoHandler 僅當 SDK 支援 SSO 時有效 */
	private SsoHandler mSsoHandler;
    private AuthListener mAuthListener;
	/** 封裝了 "access_token","expires_in","refresh_token",並提供了他們的管理功能  */
    private Oauth2AccessToken mAccessToken;
	
	/** QQ登陸相關 **/
	private Tencent mTencent;
	private BaseUiListener mBaseUiListener;
	private QQToken mQQToken;
	private UserInfo mUserInfo;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setFinishOnTouchOutside(false);  //點選區域外不消失
		setContentView(getResources().getIdentifier("dialog_login", "layout", getPackageName()));
		
		//進入的動畫
		mWindow = getWindow();
		mWindow.setGravity(Gravity.CENTER);
		mWindow.setWindowAnimations(getResources().getIdentifier("dialog", "style", getPackageName()));
		
		final ImageButton btnClose = (ImageButton) findViewById(getResources().getIdentifier("dialog_close", "id", getPackageName()));
		final ImageButton btnWeixin = (ImageButton) findViewById(getResources().getIdentifier("weixin_login", "id", getPackageName()));
		final ImageButton btnWeibo = (ImageButton) findViewById(getResources().getIdentifier("weibo_login", "id", getPackageName()));
		final ImageButton btnQQ = (ImageButton) findViewById(getResources().getIdentifier("qq_login", "id", getPackageName()));
		final Button btnPhone = (Button) findViewById(getResources().getIdentifier("phone_login", "id", getPackageName()));
	
		mContext = this;
		
		OnClickListener onClickListener = new OnClickListener() {
			@Override
			public void onClick(View view) {
				if (view == btnClose) {
					finish();
					//退出的動畫
					finishAnimation();
				} else if (view == btnWeixin) {
					
				} else if (view == btnWeibo) {
					if (!isAppInstalled(Constant.SINA_PACKAGE_NAME)) {
						Toast.makeText(mContext, String.format(getString(getResources().getIdentifier("please_install_first", "string", getPackageName())), getString(getResources().getIdentifier("dialog_weibo_login", "string", getPackageName()))), Toast.LENGTH_LONG).show();
						return;
					}
					//建立微博例項
					mAuthInfo = new AuthInfo(mContext, Constant.SINA_APP_KEY, Constant.SINA_REDIRECT_URL, Constant.SINA_SCOPE);
					mSsoHandler = new SsoHandler(LoginActivity.this, mAuthInfo);
					mAuthListener = new AuthListener();
					mSsoHandler.authorizeClientSso(mAuthListener);
				} else if (view == btnQQ) {
					if (!isAppInstalled(Constant.TENCENT_PACKAGE_NAME)) {
						Toast.makeText(mContext, String.format(getString(getResources().getIdentifier("please_install_first", "string", getPackageName())), getString(getResources().getIdentifier("dialog_qq_login", "string", getPackageName()))), Toast.LENGTH_LONG).show();
						return;
					}
					//初始化騰訊物件
					mTencent = Tencent.createInstance(Constant.TENCENT_APP_ID, mContext);
					mBaseUiListener = new BaseUiListener();
					mTencent.login(LoginActivity.this, Constant.TENCENT_SCOPE, mBaseUiListener);
				} else if (view == btnPhone) {
					finish();
					//退出的動畫
					finishAnimation();
				}
			}
		};
		
		btnClose.setOnClickListener(onClickListener);
		btnWeixin.setOnClickListener(onClickListener);
		btnWeibo.setOnClickListener(onClickListener);
		btnQQ.setOnClickListener(onClickListener);
		btnPhone.setOnClickListener(onClickListener);
	}
	
	@Override
	protected void onPause() {
		mWindow.setWindowAnimations(-1);
		super.onPause();
	}
	
	//退出的動畫
	private void finishAnimation() {
		overridePendingTransition(getResources().getIdentifier("dialog_enter", "anim", getPackageName()), getResources().getIdentifier("dialog_exit", "anim", getPackageName()));
	}
	
	//攔截返回鍵,實現自定義的退出動畫
	@Override
	public void onBackPressed() {
		finish();
		finishAnimation();
	}
	
	/**
     * 微博認證授權回撥類。
     * 1. SSO 授權時,需要在 {@link #onActivityResult} 中呼叫 {@link SsoHandler#authorizeCallBack} 後,
     *    該回調才會被執行。
     * 2. 非 SSO 授權時,當授權結束後,該回調就會被執行。
     *    當授權成功後,請儲存該 access_token、expires_in、uid 等資訊到 SharedPreferences 中。
     */
    private class AuthListener implements WeiboAuthListener {
        @Override
        public void onComplete(Bundle values) {
            //從 Bundle 中解析 Token
            mAccessToken = Oauth2AccessToken.parseAccessToken(values);
            if (mAccessToken != null && mAccessToken.isSessionValid()) {
                Toast.makeText(mContext, getString(getResources().getIdentifier("authorize_success", "string", getPackageName())), Toast.LENGTH_SHORT).show();

                String nickname = values.getString("com.sina.weibo.intent.extra.NICK_NAME");
                String access_token = values.getString("access_token");
                String uid = values.getString("uid");
                
                //GET請求獲取使用者的資訊
                try {
                	URL url = new URL("https://api.weibo.com/2/users/show.json?access_token=" + access_token + "&uid=" + uid);
                	HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                	conn.setConnectTimeout(5000);
                	conn.setRequestMethod("GET");
                	conn.setDoInput(true);
                	int code = conn.getResponseCode();
                	ByteArrayOutputStream baos = new ByteArrayOutputStream();
                	byte[] buffer = new byte[1024];
                	int length = 0;
                	if (code == 200) {
                		InputStream is = conn.getInputStream();
                		while ((length = is.read(buffer)) != -1) {
                			baos.write(buffer, 0, length);
                		}
                	}
                	String jsonString = new String(baos.toByteArray());
                	JSONObject jsonObject = new JSONObject(jsonString);
                	String icon = jsonObject.getString("profile_image_url");
                	
                	Intent intent = new Intent();
    				intent.putExtra("nickname", nickname);
    				intent.putExtra("icon", icon);
                    setResult(Constant.LOGIN_RESULT_OK, intent);
                    finish();
                    finishAnimation();
                } catch (Exception e) {
                	Log.d("chengcj1", e.getMessage());
                }
            } else {
                // 以下幾種情況,您會收到 Code:
                // 1. 當您未在平臺上註冊的應用程式的包名與簽名時;
                // 2. 當您註冊的應用程式包名與簽名不正確時;
                // 3. 當您在平臺上註冊的包名和簽名與您當前測試的應用的包名和簽名不匹配時。
                String code = values.getString("code");
                String message = getString(getResources().getIdentifier("authorize_fail", "string", getPackageName()));
                if (!TextUtils.isEmpty(code)) {
                    message = message + "\n Obtained the code: " + code;
                }
                Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();
            }
        }

        @Override
        public void onCancel() {
            Toast.makeText(mContext, getString(getResources().getIdentifier("authorize_cancel", "string", getPackageName())), Toast.LENGTH_LONG).show();
        }

        @Override
        public void onWeiboException(WeiboException e) {
            Toast.makeText(mContext,  "WeiboException : " + e.getMessage(), Toast.LENGTH_LONG).show();
        }
    }
	
	private class BaseUiListener implements IUiListener {
		@Override
		public void onError(UiError e) {
			Toast.makeText(mContext, getString(getResources().getIdentifier("login_fail", "string", getPackageName())) + e.errorMessage, Toast.LENGTH_LONG).show();
		}

		@Override
		public void onComplete(Object response) {
			// 獲得的資料是JSON格式的,獲得你想獲得的內容
			JSONObject responseJsonObject = (JSONObject) response;
		    int  ret = responseJsonObject.optInt("ret");
		    if (ret == 0) { //登陸成功
		    	Toast.makeText(mContext, getString(getResources().getIdentifier("login_success", "string", getPackageName())), Toast.LENGTH_LONG).show();
		    	// 用於唯一標識使用者身份(每一個openid與QQ號碼對應)
		    	String openID = responseJsonObject.optString("openid");
		    	//使用者進行應用邀請、分享、支付等基本業務請求的憑據
                final String accessToken = responseJsonObject.optString("access_token");
                //access_token的有效時間,在有效期內可以發起業務請求,過期失效
                String expires = responseJsonObject.optString("expires_in");  
                mTencent.setOpenId(openID);  
                mTencent.setAccessToken(accessToken, expires);
                
                //QQ登陸成功,獲取使用者的資訊,如我們還想獲取一些QQ的基本資訊,比如暱稱,頭像什麼的
				mQQToken = mTencent.getQQToken();
				mUserInfo = new UserInfo(mContext, mQQToken);
				mUserInfo.getUserInfo(new IUiListener() {
					
					@Override
					public void onError(UiError  e) {
					}
					
					@Override
					public void onComplete(Object response) {
						JSONObject responseJsonObject = (JSONObject) response;
						//獲取暱稱
						String nickname = responseJsonObject.optString("nickname");
						//獲取使用者頭像
						String icon = responseJsonObject.optString("figureurl_qq_2");
						
						Intent intent = new Intent();
						intent.putExtra("nickname", nickname);
						intent.putExtra("logo", icon);
		                setResult(Constant.LOGIN_RESULT_OK, intent);
		                finish();
		                finishAnimation();
					}
					
					@Override
					public void onCancel() {
					}
				});
		    }
		}

		@Override
		public void onCancel() {
			Toast.makeText(mContext, getString(getResources().getIdentifier("login_cancel", "string", getPackageName())), Toast.LENGTH_LONG).show();
		}
	}
	
	/**
	 * 應用呼叫Android_SDK介面時,如果要成功接收到回撥,需要再呼叫介面的Activity的onActivityResult方法中增加如下程式碼
	 * http://wiki.open.qq.com/wiki/mobile/SDK下載
	 * http://open.weibo.com/wiki/SDK
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		Tencent.onActivityResultData(requestCode, resultCode, data, mBaseUiListener);
		// SSO 授權回撥
        // 重要:發起 SSO 登陸的 Activity 必須重寫 onActivityResult
		if (mSsoHandler != null) {
			mSsoHandler.authorizeCallBack(requestCode, resultCode, data);
		}
	}
	
	/**
	 * 檢測手機上是否安裝相應的平臺
	 * @param packageName 包名
	 * @return
	 */
	private boolean isAppInstalled(String packageName) {
		try {
			getPackageManager().getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
			return true;
		} catch (Exception e) {
			return false;
		}
	}
	
}