实现qq第三方登录:
1、布局文件
首先说AndroidManifest.xml文件。 要想通过代码弹出qq的登陆界面,要在AndroidManifest.xml中声明两个Activity,这两个Activity不需要我们编写代码,是在qq需要的两个jar包中写好的,我们只需要声明就可以了。既然提到需要的jar包就提供下载地址 http://wiki.open.qq.com/wiki/mobile/SDK%E4%B8%8B%E8%BD%BD,这个文件中有jar包,示例程序,文档等。 下面附上AndroidManifest.xml代码
<!-- qq登陆 -->
<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" />
<!--android:scheme是用来控制跳转到别的页面的
这里的tencent是必须的后面接你在官网申请的app_id -->
<data android:scheme="tencent1105990943" />
<!-- 100380359 100381104 222222 -->
</intent-filter>
</activity>
<activity
android:name="com.tencent.connect.common.AssistActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="behind"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
</application>
其余的就是设置一个登陆的按键这个就不写了。
我的环境框架是
这里注意jar包一定要放到libs里,之后再添加到路径,否则会找不到上面的两个Activity
2、java文件
首先设置点击监听
qqloginButton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Log.i("qqdl","进去qqclick");
//这里的APP_ID请换成你应用申请的APP_ID,我这里使用的是DEMO中官方提供的测试APP_ID 222222
mAppid = "1105990943";//这里不用加tencent
Log.i("qqdl","完成赋值");
//第一个参数就是上面所说的申请的APPID,第二个是全局的Context上下文,这句话实现了调用QQ登录
mTencent = Tencent.createInstance(mAppid,getApplicationContext());
/**通过这句代码,SDK实现了QQ的登录,这个方法有三个参数,第一个参数是context上下文,第二个参数SCOPO 是一个String类型的字符串,表示一些权限
* 官方文档中的说明:应用需要获得哪些API的权限,由“,”分隔。例如:SCOPE = “get_user_info,add_t”;所有权限用“all”
* 第三个参数,是一个事件监听器,IUiListener接口的实例,这里用的是该接口的实现类 */
mTencent.login(LoginActivity.this,"all", qqListener);
Log.i("qqdl","登陆成功");
}
});
到这里就可以实现qq登陆了,但官方文档写的是低版本手机比较垃圾不能调出登陆界面,需要加几行代码才能调出。但我觉得这个怎么看都是回调函数。反正我是加了··
//没有这个不能实现qq的回调
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i("qqdl", "-->onActivityResult " + requestCode + " resultCode=" + resultCode);
if (requestCode == Constants.REQUEST_LOGIN ||
requestCode == Constants.REQUEST_APPBAR) {
//qqlistener是一个IUiListener用来监听qq是不是登陆成功了
Tencent.onActivityResultData(requestCode,resultCode,data,qqListener);
}
super.onActivityResult(requestCode, resultCode, data);
}
只是登陆没有用,要得到用户信息才有用
下面就看怎么读取用户信息
注意到上面的mTencent.login(LoginActivity.this,"all",qqlistener)这条语句中的qqlistener了么,这个是一个监听,可以监听qq登陆是否成功,如果成功我们就可以读取用户信息啦
下面是如何设置监听
/**当自定义的监听器实现IUiListener接口后,必须要实现接口的三个方法,
* * onComplete onCancel onError
* *分别表示第三方登录成功,取消 ,错误。*/
private class BaseUiListener implements IUiListener {
@Override
public void onCancel() {
// TODO Auto-generated method stub
}
@Override
public void onComplete(Object response) {
}
@Override
public void onError(UiError arg0) {
// TODO Auto-generated method stub
}
}
private IUiListener qqListener = new BaseUiListener(){
@Override
public void onComplete(Object response) {
Log.i("qqdl","进入qqiui监听");
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "登录成功", 0).show();
try {
//获得的数据是JSON格式的,获得你想获得的内容
//如果你不知道你能获得什么,看一下下面的LOG
Log.i("qqdl", "response-------------"+response.toString());
openidString = ((JSONObject) response).getString("openid");
Log.i("qqdl", "openid-------------"+openidString);
//access_token= ((JSONObject) response).getString("access_token"); //expires_in = ((JSONObject) response).getString("expires_in");
try {
if (((JSONObject) response).getInt("ret")==0) {
String token = ((JSONObject) response).getString(Constants.PARAM_ACCESS_TOKEN);
String expires = ((JSONObject) response).getString(Constants.PARAM_EXPIRES_IN);
String openID = ((JSONObject) response).getString(Constants.PARAM_OPEN_ID);
//**下面这两步设置很重要,如果没有设置,返回为空**
mTencent.setOpenId(openID);
mTencent.setAccessToken(token, expires);
qqInfo = new UserInfo(LoginActivity.this,mTencent.getQQToken());
qqInfo.getUserInfo(getQQinfoListener);
}
} catch (JSONException e) {
e.printStackTrace();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
一旦登陆成功,qq会回调到这个监听的onComplete()方法并返回一个response对象,这是一个JSONObject对象,里面有很多信息,其中我们单独取出openid这个参数,为了之后再服务端为客户自动注册,之后我们通过qqInfo(一个UserInfo的实例,直接用就行,它会提示你通过刚才导入的jar包import)就可以得到用户信息了。
qqInfo里有设置了一个监听,代码如下
/**
* 获取用户信息
*/
private IUiListener getQQinfoListener = new IUiListener() {
@Override
public void onComplete(Object response) {
try {
JSONObject jsonObject = (JSONObject) response;
Log.i("qqdl",jsonObject.toString());
//处理自己需要的信息
regeditQqUser(jsonObject);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onError(UiError uiError) {
}
@Override
public void onCancel() {
}
};
好了到这里的response就是我们取出来的用户信息啦!到此就可以往服务端数据库导入了,怎么将数据发送到数据库呢?
看到regeditQqUser()方法了吗?这个就是
public void regeditQqUser(JSONObject jsonObject){
Log.i("qqdl","进入注册方法");
try {
nickName=(String) jsonObject.get("nickname");
gender=(String) jsonObject.get("gender");
location=(String) jsonObject.get("province");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Thread (new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Log.i("qqdl","即将网络连接"+urlRegeditAction);
HttpClient httpClient =new DefaultHttpClient();
HttpPost httpPost=new HttpPost(urlRegeditAction);
Log.i("qqdl","连接设置完成");
List<NameValuePair> params=new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("whatuser","qq"));
params.add(new BasicNameValuePair("nickname",nickName));
params.add(new BasicNameValuePair("gender",gender));
params.add(new BasicNameValuePair("location",location));
params.add(new BasicNameValuePair("openid",openidString));
Log.i("qqdl","构造数据完成");
UrlEncodedFormEntity entity;
try {
entity = new UrlEncodedFormEntity(params,"utf-8");
httpPost.setEntity(entity);
Log.i("qqdl","设置数据完成");
HttpResponse response=httpClient.execute(httpPost);
Log.i("qqdl","发送成功");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
Intent intent2=new Intent();
intent2.setClass(getApplicationContext(),WelcomeActivity.class);
intent2.putExtra("userName", openidString);
startActivity(intent2);
}
注意http操作要在线程中完成,不然不能访问。之后跳转到你下面的流程就行啦。
数据库的用户名就用openid就行,他是每一个用户的唯一标识不会重复的,密码也用这个就行。