關於QQ互聯第三方登錄的界面交互筆記

OAuth: OAuth(開放受權)是一個開放標準,容許用戶受權第三方網站訪問他們存儲在另外的服務提供者上的信息,而不須要將用戶名和密碼提供給第三方網站或分享他們數據的全部內容。android

QQ登陸OAuth2.0:對於用戶相關的OpenAPI(例如獲取用戶信息,動態同步,照片,日誌,分享等),爲了保護用戶數據的安全和隱私,第三方網站訪問用戶數據前都須要顯式的向用戶徵求受權。git

這篇文章說的不是OAuth2.0的內容,也不是如何接入QQ登錄sdk的文章,只是界面交互的一些筆記。安全

本篇是安卓使用筆記。app

用過QQ互聯sdk的都知道引入sdk後須要配置一些東西,如權限,聲明一些Activity等,剛開始的時候,沒有深刻研究,覺得受權界面是集成在sdk裏的,但實際上是集成在QQ裏的,sdk只是啓動了QQ內置的一個受權界面。ide

受權登錄本質上是兩個A應用間通信的問題,剛一開始覺得用的是AIDL,但想了一下QQ互聯sdk的操做流程,感受受權過程仍是兩個頁面的交互,後來看了一下代碼,發現界面交互原理其實很簡單。網站

既然受權頁面是集成在QQ應用自己的,那麼是否能夠不使用第三方sdk直接啓動QQ內置的受權頁面?固然是能夠,並且還很簡單。this

try {
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("com.tencent.mobileqq","com.tencent.open.agent.AgentActivity"));
    intent.putExtra("key_action","action_login");
    intent.putExtra("appid","222222");
    intent.putExtra("key_request_code","10086");
    Bundle bundle = new Bundle();
    bundle.putString("mParcelledData.dataSize","500");
    intent.putExtra("key_params",bundle);
    startActivityForResult(intent,10086);

}catch (ActivityNotFoundException nfe) {
    nfe.printStackTrace();
    Toast.makeText(this,"應用未安裝",Toast.LENGTH_SHORT).show();
}catch (Exception e) {
    Toast.makeText(this,"e:"+e.getMessage(),Toast.LENGTH_SHORT).show();
}

只用上面幾句代碼就能夠了,固然只是啓動了Activity,認證是不成功的,因此想接入QQ登錄的,仍是老老實實的使用QQ的sdk。spa

QQ受權頁面的幾個關鍵地方是,提供受權的頁面須要作如下配置.net

<activity
    android:name=".AgentActivity"
    android:configChanges="orientation|keyboardHidden"
    android:exported="true"
    android:process=":openSdk"
    android:screenOrientation="portrait">

關鍵兩句日誌

android:exported="true" (當前Activity是否能夠被另外一個Application的組件啓動

android:process=":openSdk"

網上解釋:

1,能夠設置Android:process屬性使APP的組件運行在不一樣的進程上;

2,能夠設置android:process以使不一樣應用的組件們能夠運行於同一個進程—假如這些應用共享同一個用戶ID而且有相同的數字證書;

 

而後集成sdk的應用,就是經過下面兩個方法進行兩個應用間的通信,通信都是單向的。

startActivityForResult
protected void onActivityResult(int requestCode, int resultCode, Intent data)

下面是精簡版的,模仿QQ登錄的回調方法

Tencent.getInstance().login(this, new IUiListener() {
    @Override
    public void onComplete(Object returnValue) {
        Toast.makeText(MainActivity.this,"onComplete:"+returnValue,Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onError(UiError e) {
        Toast.makeText(MainActivity.this,"onError:"+e,Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onCancel() {
        Toast.makeText(MainActivity.this,"onCancel",Toast.LENGTH_SHORT).show();
    }
});

 

public synchronized void login(Activity activity, IUiListener listener) {
    if(!Util.hasInstalledAgentApp(activity)) {
        String msg = "未安裝受權應用";
        UiError error = new UiError(0,msg,msg);
        listener.onError(error);
        return;
    }
    if(mListener != null) {
        mListener.clear();
    }
    mListener = new WeakReference(listener);
    activity.startActivity(new Intent(activity,TransferActivity.class));
}

 

public class TransferActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startActivityForResult(Util.makeAgentActivityIntent(this),10086);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        IUiListener listener = Tencent.getInstance().getListener();
        if(listener == null) {
            finish();
            return;
        } else if(resultCode == RESULT_CANCELED) {
            listener.onCancel();
            finish();
        }else if(resultCode == RESULT_OK) {
            //處理數據,區分onComplete onError,暫時都用onComplete
            listener.onComplete(data);
        }

        Tencent.getInstance().clearListener();
        finish();
    }
}

 

完整代碼請查看https://git.oschina.net/null_979_4294/QQConnectProject

相關文章
相關標籤/搜索