OAuth: OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容。
QQ登录OAuth2.0:对于用户相关的OpenAPI(例如获取用户信息,动态同步,照片,日志,分享等),为了保护用户数据的安全和隐私,第三方网站访问用户数据前都需要显式的向用户征求授权。
这篇文章说的不是OAuth2.0的内容,也不是如何接入QQ登陆sdk的文章,只是界面交互的一些笔记。
本篇是安卓使用笔记。
用过QQ互联sdk的都知道引入sdk后需要配置一些东西,如权限,声明一些Activity等,刚开始的时候,没有深入研究,以为授权界面是集成在sdk里的,但其实是集成在QQ里的,sdk只是启动了QQ内置的一个授权界面。
授权登陆本质上是两个A应用间通讯的问题,刚一开始以为用的是AIDL,但想了一下QQ互联sdk的操作流程,感觉授权过程还是两个页面的交互,后来看了一下代码,发现界面交互原理其实很简单。
既然授权页面是集成在QQ应用本身的,那么是否可以不使用第三方sdk直接启动QQ内置的授权页面?当然是可以,而且还很简单。
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。
QQ授权页面的几个关键地方是,提供授权的页面需要做以下配置
<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