QQ原生SDK第三方登錄

在新進的項目中,原先使用SharedSDK做第三方登錄。在近期的數據統計分析中,發現會存在獲取openid成功,而獲取QQ用戶信息不成功的情形。除卻在獲取信息失敗情形下添加條件攔截外,使用QQ SDK直接實現第三方登錄是另一個選擇。


一、資源查看與下載

度娘還是很好用的啦,信息渠道的擴展,極大地縮小了信息搜索的難度,增加了信息獲取的公平性。

這裏是QQ官方文檔,用於引導開發者使用並達到功能實現。

這篇博客描述也是相當詳細


二、功能實現

1,官方渠道註冊

保存並獲取APPID。

在新建項目中,導入下載的QQ 登錄註冊等相關jar包。

ps:QQ sdk 在3.2.1版本中添加基礎包,有最基本的功能。【正在完善APP中只需要登錄功能,遂換成基礎包】


2,項目代碼實現  -- 清單文件添加權限

   <!-- QQ登錄授權所需權限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

3,項目代碼實現  -- 聲明Activity

<!-- 註冊SDKActivity -->
        <activity
            android:name="com.tencent.tauth.AuthActivity"
            android:launchMode="singleTask"
            android:noHistory="true" >
            <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="tencentAppID" /> <!-- 開放平臺獲取的APPID -->
            </intent-filter>
        </activity>
        <activity android:name="com.tencent.connect.common.AssistActivity"
            android:theme="@android:style/Theme.Translucent.NoTitleBar"
            android:screenOrientation="portrait"/>
ps:有些博客中沒有聲明AssistActivity,會導致創建Tencent對象爲空的情形。

AppID爲之前官方渠道註冊所得,前面tencent字符串不可省不可改。

4,項目代碼實現 ---  IUiListener接口實現

/**
 * qq登錄監聽器
 */

public class BaseUiListener implements IUiListener {

    protected void doComplete(Object values) {

    }

    @Override
    public void onComplete(Object response) {
        doComplete(response);
    }

    @Override

    public void onError(UiError e) {


    }

    @Override

    public void onCancel() {


    }

}
doComplete()方法在不同版本中傳參可能不一樣,並不影響使用。另一種傳參爲JsonObject。在實際的數據解析中,都會轉換成爲JSonObject從而獲取需要的值。

5,項目代碼實現 ---  創建Tencent實例

mTencent = Tencent.createInstance("AppID", this.getApplicationContext());


AppID爲QQ官方註冊所得,此處不添加其他任何字符串。
當清單文件沒有AssistActivity聲明,會導致獲取對象爲空。


6,項目代碼實現 ---  登錄事件觸發

在頁面實現的QQ點擊進行第三方登陸的onClick()事件下添加:

                if (!mTencent.isSessionValid()) {
                       mTencent.login(this, "all", new BaseUiListener());
                }

7,項目代碼實現 ---  回調監聽

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (mTencent != null) {
            mTencent.handleLoginData(data, new BaseUiListener() {
                @Override
                protected void doComplete(Object values) {
                    String expires_in = "";
                    try {
                        qq_id = new JSONObject(values.toString()).getString("openid");
                        qq_token = new JSONObject(values.toString()).getString("access_token");
                        expires_in = new JSONObject(values.toString()).getString("expires_in");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

		    //依據回調回來的值修改原有默認值
                    mTencent.setOpenId(qq_id);
                    mTencent.setAccessToken(qq_token, expires_in);


                    QQToken qqToken = mTencent.getQQToken();
                    UserInfo info = new UserInfo(LoginMainActivity.this, qqToken);

		    //獲取用戶基本信息
                    info.getUserInfo(new BaseUiListener() {
                        @Override
                        protected void doComplete(Object values) {
                            try {
                                JSONObject jsonObject = new JSONObject(values.toString());

                                qq_name = jsonObject.getString("nickname");
                                qq_icon = jsonObject.getString("figureurl_qq_2");

                                /**
                                 * 增加QQ信息獲取不完整攔截
                                 */
                                if (qq_name == null || qq_name.length() <= 0
                                        || qq_icon == null || qq_icon.length() <= 0
                                        || qq_id == null || qq_id.length() <= 0) {
                                    CustomProgressDialog.getInstance().dismiss();
                                    ToastView.showToast(LoginMainActivity.this, R.string.network_bad, ToastView.LENGTH_SHORT);//工具類,展示信息獲取不完整
                                    return;
                                }

                    		//登錄到客戶端服務器

                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }
            });
        }
    }
注意:

(1)QQToken qqToken = mTencent.getQQToken();

                  獲取前需要依據返回值設置數據,否則在之後的用戶信息獲取下會出現傳參錯誤。


(2)用戶信息獲取的方法模式封裝好

                 info.getUserInfo(new BaseUiListener() {});回調方法裏面處理詳細細節


        (3)獲取到用戶信息,openid之後,需要與客戶端本身的服務器關聯,實現真正的登錄。


三、細節注意

1,APPID的兩處使用,清單文件中攜帶tencent的字符串,代碼中獲取Tencent對象不加任何其他字符;

2,獲取用戶信息前,需要重新設置Tencent對象的值;

3,mTencent.isSessionValid()是否使用:

(1)使用:需要在和APP登錄成功後,註銷掉QQ登錄,使其失效。否則會出現APP退出再進行登錄無效。

【原因:QQ已經是登陸狀態,還沒有失效,下次不會重新獲取,觸發登錄流程】

mTencent.logout(this);
能夠註銷登錄。

(2)不使用

每次點擊事件都相當於觸發登錄事件,走登錄流程。

客戶端會有連續快速點擊,需要做快速點擊防止!

4,無QQ客戶端添加攔截

在客戶端處理沒有QQ客戶端攔截,不允許登錄或者提示安裝QQ客戶端再登錄。否則會有:WebAuthorizeActivity錯誤:

java.lang.NoSuchMethodError: cn.sharesdk.framework.authorize.e.disableScreenCapture
	at cn.sharesdk.framework.authorize.e.onCreate(WebAuthorizeActivity.java:125)
	at com.mob.tools.MobUIShell.onCreate(MobUIShell.java:89)
	at android.app.Activity.performCreate(Activity.java:5350)
	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2430)
	at android.app.ActivityThread.access$800(ActivityThread.java:151)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
	at android.os.Handler.dispatchMessage(Handler.java:110)
	at android.os.Looper.loop(Looper.java:193)
	at android.app.ActivityThread.main(ActivityThread.java:5334)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:515)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:829)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:645)
	at dalvik.system.NativeStart.main(Native Method)



小小的自我提醒:

在追求任何知識和技能的過程中,最頂端的最後一小段路的邊際成本是最高的,關山修阻,難以成行。但是邊際理論只能帶你到那裏,最後一段路上請你務必忘記它。


發佈了121 篇原創文章 · 獲贊 32 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章