在APP开发过程中,时常会用到第三方账号登录体系。
下面,简要说明QQ的第三方登录体系在Android平台上的运用。
申请APPID
进入QQ互联的官网,http://connect.qq.com/
在管理中心中创建移动应用。
创建完成后,可以得到APPID。
并在下方的协作者测试号中,填写控应用测试用的QQ号码。
导入Jar包
将下载得到的Jar包导入工程,并在AndroidManifest.xml文件中进行注册。
<activity
android:name="com.tencent.tauth.AuthActivity"
android:noHistory="true"
android:launchMode="singleTask" >
<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="tencent100546930" />
</intent-filter>
</activity>
其中,<data android:scheme="tencent100546930" />中的数字需要替换成自己申请得到的APPID。
创建登录接口
所有的SDK接口调用,都会传入一个回调,用以接收SDK返回的调用结果。回调的主要接口有两种:
(1) IUiListener:调用SDK已经封装好的接口时,例如:登录、快速支付登录、应用分享、应用邀请等接口。
(2) IRequestListener:使用requestAsync、request等通用方法调用sdk未封装的接口时,例如上传图片、查看相册等。
在这里创建IUiListener接口实现相应的登录授权操作: private void onClickLogin() {
if (!mTencent.isSessionValid()) {
IUiListener listener = new IUiListener() {
/** 授权失败的回调*/
@Override
public void onError(UiError arg0) {
// TODO Auto-generated method stub
Toast.makeText(LoginActivity.this, "授权失败", 1000).show();
Message msg = new Message();
msg.arg1 = 2;
handler.sendMessage(msg);
}
/** 授权成功的回调*/
@Override
public void onComplete(JSONObject arg0) {
// TODO Auto-generated method stub
Toast.makeText(LoginActivity.this, "授权成功", 1000).show();
Message msg = new Message();
msg.what = 2;
msg.arg1 = 1;
msg.obj = arg0;
handler.sendMessage(msg);
}
/** 取消授权的回调*/
@Override
public void onCancel() {
// TODO Auto-generated method stub
Toast.makeText(LoginActivity.this, "取消授权", 1000).show();
Message msg = new Message();
msg.arg1 = 3;
handler.sendMessage(msg);
}
};
mTencent.login(this, SCOPE, listener);
} else {
mTencent.logout(this);
}
}
其中,mTencent为QQSDK主要实现类Tencent类的实例。
// Tencent类是SDK的主要实现类,开发者可通过Tencent类访问腾讯开放的OpenAPI。
// 其中APP_ID是分配给第三方应用的appid,类型为String。
mTencent = Tencent.createInstance(APP_ID, this.getApplicationContext());
将handler进行实例化
handler = new Handler(this);
并将类实现Callback接口,即可对上述类进行Handler的处理操作。
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.arg1) {
case 1: { // 成功
JSONObject object = (JSONObject) msg.obj;
try {
openid = object.getString("openid").toString();
sBuilder.append("openid为:"+openid+"\n");
access_token = object.getString("access_token").toString();
url = url + "?access_token="+access_token+"&oauth_consumer_key="+APP_ID+
"&openid="+openid+"&format=json";
new MyUrlThread(url.toString(), 2,sHandler).start();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break;
case 2: { // 失败
Toast.makeText(this, "", Toast.LENGTH_SHORT).show();
return false;
}
case 3: { // 取消
Toast.makeText(this, "", Toast.LENGTH_SHORT).show();
return false;
}
}
return false;
}
如果授权成功,即可得到返回的Openid。
从而,可以根据Openid调用腾讯所提供的官方接口,实现需要的操作。
接收回调
//应用调用Andriod_SDK接口时,使能成功接收到回调
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
应用实例代码
package com.test.wotao;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.json.JSONException;
import org.json.JSONObject;
import com.tencent.plus.TouchView;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;
import com.test.util.MyApplication;
import com.test.util.MyThread;
import com.test.util.MyUrlThread;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.os.StrictMode;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.BaseInputConnection;
import android.widget.Button;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
/**
* 创建时间:2013-10-30
APP ID:100546930
APP KEY:6ff068cfbae8fa0b53f9a3c27f1af321
* @author 402-9
*
*/
public class LoginActivity extends Activity implements OnClickListener,Callback{
private Button login_qq;
private TextView nickname;
private ImageView image;
private Tencent mTencent;
private String imageurl;
String url_qqlogin;
private String openid;
private String access_token;
private String SCOPE = "get_simple_userinfo,add_topic";
private static final String APP_ID = "100546930";
private String url = "https://graph.qq.com/user/get_user_info";
private Handler handler;
private StringBuilder sBuilder = new StringBuilder();
private Handler sHandler = new Handler(){
public void handleMessage(Message msg) {
if (msg.what == 2) {
String result = msg.obj.toString();
JSONObject data;
try {
data = new JSONObject(result);
String ret = data.getString("ret");
String messsage = data.getString("msg");
if (Integer.valueOf(ret) == 0) {
String name = data.getString("nickname");
sBuilder.append("nickname为:"+name+"\n");
String gender = data.getString("gender");
sBuilder.append("gender为:"+gender+"\n");
imageurl = data.getString("figureurl_1");
sBuilder.append("imageurl为:"+imageurl+"\n");
// image.setImageDrawable(Drawable.createFromStream(new URL(imageurl).openConnection()
// .getInputStream(), "src"));
url_qqlogin = "jiekou.php?code=qq_user&nickname="+name+"&email="+name+
"@qq.com&figureurl="+imageurl+"&sex="+gender+
"&openid="+openid+"&accesstoken="+access_token;
System.out.println("url_qqlogin----"+url_qqlogin);
new MyThread(url_qqlogin.toString(), 1,qqHandler).start();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("sBuilder---"+sBuilder);
nickname.setText(sBuilder);
}
};
};
private Handler qqHandler = new Handler(){
public void handleMessage(Message msg) {
if (msg.what==1) {
String result = msg.obj.toString();
JSONObject data;
try {
data = new JSONObject(result);
String nickname = data.getString("nickname");
String message = data.getString("msg");
sBuilder.append("QQ的nickname为:"+nickname+"\n");
sBuilder.append("QQ的message为:"+message+"\n");
System.out.println("333==="+sBuilder);
Toast.makeText(LoginActivity.this, message, 1000).show();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
nickname.setText(sBuilder);
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.login_qq);
handler = new Handler(this);
// Tencent类是SDK的主要实现类,开发者可通过Tencent类访问腾讯开放的OpenAPI。
// 其中APP_ID是分配给第三方应用的appid,类型为String。
mTencent = Tencent.createInstance(APP_ID, this.getApplicationContext());
login_qq = (Button) findViewById(R.id.login_qq);
login_qq.setOnClickListener(this);
nickname = (TextView) findViewById(R.id.nickname);
image = (ImageView) findViewById(R.id.image);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.login_qq:
onClickLogin();
break;
}
}
//应用调用Andriod_SDK接口时,使能成功接收到回调
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
mTencent.onActivityResult(requestCode, resultCode, data);
}
private void onClickLogin() {
if (!mTencent.isSessionValid()) {
IUiListener listener = new IUiListener() {
/** 授权失败的回调*/
@Override
public void onError(UiError arg0) {
// TODO Auto-generated method stub
Toast.makeText(LoginActivity.this, "授权失败", 1000).show();
Message msg = new Message();
msg.arg1 = 2;
handler.sendMessage(msg);
}
/** 授权成功的回调*/
@Override
public void onComplete(JSONObject arg0) {
// TODO Auto-generated method stub
Toast.makeText(LoginActivity.this, "授权成功", 1000).show();
Message msg = new Message();
msg.what = 2;
msg.arg1 = 1;
msg.obj = arg0;
handler.sendMessage(msg);
}
/** 取消授权的回调*/
@Override
public void onCancel() {
// TODO Auto-generated method stub
Toast.makeText(LoginActivity.this, "取消授权", 1000).show();
Message msg = new Message();
msg.arg1 = 3;
handler.sendMessage(msg);
}
};
mTencent.login(this, SCOPE, listener);
} else {
mTencent.logout(this);
}
}
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.arg1) {
case 1: { // 成功
JSONObject object = (JSONObject) msg.obj;
try {
openid = object.getString("openid").toString();
sBuilder.append("openid为:"+openid+"\n");
access_token = object.getString("access_token").toString();
url = url + "?access_token="+access_token+"&oauth_consumer_key="+APP_ID+
"&openid="+openid+"&format=json";
new MyUrlThread(url.toString(), 2,sHandler).start();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break;
case 2: { // 失败
Toast.makeText(this, "", Toast.LENGTH_SHORT).show();
return false;
}
case 3: { // 取消
Toast.makeText(this, "", Toast.LENGTH_SHORT).show();
return false;
}
}
return false;
}
}