Android开发实现QQ三方登录 标签: android开发qq三方登录
本文分为两个部分:一是QQ的授权部分;二是获取用户的基本信息部分
一、授权部分
1.首先,先去腾讯开放平台获取APP ID和APP KEY(未注册腾讯开发者账号的可能需要先注册账号),获取的过程还是还是非常容易的(不用填写任何的应用程序信息)。
2.下载SDK(http://wiki.open.qq.com/wiki/mobile/SDK%E4%B8%8B%E8%BD%BD)
3.下载好SDK后,将其中的两个jar包(mta-sdk-1.6.2.jar、open_sdk_r5276.jar)引入到工程当中。
4.在AndroidManifest.xml的application标签中添加一下两个activity。
<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="tencent*********" /> </intent-filter> </activity> <activity android:name="com.tencent.connect.common.AssistActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:configChanges="orientation|keyboardHidden|screenSize" />
注意:上面<data android:scheme="tencent*********" />中的*****要替换成自己一开始获取到的APP ID(假设APP ID是123456,则替换后为:scheme="tencent123456")。
5.添加访问网络的权限。
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
6.Java实现:接下来需要两个对象(布局文件和控件的初始化自行另外解决)
//需要腾讯提供的一个Tencent类 private Tencent mTencent; //还需要一个IUiListener 的实现类(LogInListener implements IUiListener) private LogInListener mListener; //首先需要用APP ID 获取到一个Tencent实例 mTencent = Tencent.createInstance(QQ_APP_ID, this.getApplicationContext()); //初始化一个IUiListener对象,在IUiListener接口的回调方法中获取到有关授权的某些信息 // (千万别忘了覆写onActivityResult方法,否则接收不到回调) mListener = new LogInListener();
其中,LogInListener是IUiListener的实现类,其中的回调方法用来接收授权后的相关信息:
private class LogInListener implements IUiListener { @Override public void onComplete(Object o) { Toast.makeText(MainActivity.this, "授权成功!", Toast.LENGTH_LONG).show(); System.out.println("o.toString() -------------------------> " + o.toString()); } @Override public void onError(UiError uiError) { Toast.makeText(MainActivity.this, "授权出错!", Toast.LENGTH_LONG).show(); } @Override public void onCancel() { Toast.makeText(MainActivity.this, "授权取消!", Toast.LENGTH_LONG).show(); } }
注意:别忘了覆写onActivityResult方法,否则接收不到回调
//确保能接收到回调 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Tencent.onActivityResultData(requestCode, resultCode, data, mListener); }
7.登录与登出
//调用QQ登录,用IUiListener对象作参数(点击登录按钮时执行以下语句) if (!mTencent.isSessionValid()) { mTencent.login(MainActivity.this, "all", mListener); } //登出比较简单 mTencent.logout(MainActivity.this);
如此整个授权的流程就ok了,我们可以在onComplete回调方法中获取到授权的信息。
顺便提一下,上面IUiListener的onComplete回调方法参数Object对象的格式为:
{ "ret": 0, "openid": "19E8D43EB75ED256CAC70C02953F188A", "access_token": "65A5A933F116085E051F39CAD65084EF", "pay_token": "BA387A1679483A4C8585BE268C7C4128", "expires_in": 7776000, "pf": "desktop_m_qq-10000144-android-2002-", "pfkey": "2c7171fb052154f89e9d439e17e18c11", "msg": "", "login_cost": 442, "query_authority_cost": 322, "authority_cost": 0 }
二、获取用户的基本信息部分。(有用到上一部分onComplete回调方法中传回来的Object对象)
上面只是实现了授权,并未拿到用户的基本信息,下面是这部分的实现
8.在第6步中的onComplete回调方法中添加以下语句
@Override public void onComplete(Object o) { Toast.makeText(MainActivity.this, "授权成功!", Toast.LENGTH_LONG).show(); System.out.println("o.toString() -------------------------> " + o.toString()); JSONObject jsonObject = (JSONObject) o; //设置openid和token,否则获取不到下面的信息 initOpenidAndToken(jsonObject); //获取QQ用户的各信息 getUserInfo(); }
其中,initOpenidAndToken 与 getUserInfo的实现如下
private void initOpenidAndToken(JSONObject jsonObject) { try { String openid = jsonObject.getString("openid"); String token = jsonObject.getString("access_token"); String expires = jsonObject.getString("expires_in"); mTencent.setAccessToken(token, expires); mTencent.setOpenId(openid); } catch (JSONException e) { e.printStackTrace(); } } private void getUserInfo() { //sdk给我们提供了一个类UserInfo,这个类中封装了QQ用户的一些信息,我么可以通过这个类拿到这些信息 QQToken mQQToken = mTencent.getQQToken(); UserInfo userInfo = new UserInfo(MainActivity.this, mQQToken); userInfo.getUserInfo(new IUiListener() { @Override public void onComplete(final Object o) { JSONObject userInfoJson = (JSONObject) o; Message msgNick = new Message(); msgNick.what = 0;//昵称 try { msgNick.obj = userInfoJson.getString("nickname");//直接传递一个昵称的内容过去 } catch (JSONException e) { e.printStackTrace(); } mHandler.sendMessage(msgNick); //子线程 获取并传递头像图片,由Handler更新 new Thread(new Runnable() { @Override public void run() { Bitmap bitmapHead = null; if (((JSONObject) o).has("figureurl")) { try { String headUrl = ((JSONObject) o).getString("figureurl_qq_2"); bitmapHead = Util.getbitmap(headUrl); } catch (JSONException e) { e.printStackTrace(); } Message msgHead = new Message(); msgHead.what = 1; msgHead.obj = bitmapHead; mHandler.sendMessage(msgHead); } } }).start(); } @Override public void onError(UiError uiError) { Log.e("GET_QQ_INFO_ERROR", "获取qq用户信息错误"); Toast.makeText(MainActivity.this, "获取qq用户信息错误", Toast.LENGTH_SHORT).show(); } @Override public void onCancel() { Log.e("GET_QQ_INFO_CANCEL", "获取qq用户信息取消"); Toast.makeText(MainActivity.this, "获取qq用户信息取消", Toast.LENGTH_SHORT).show(); } } ); }
其中,自定义的Util类如下
public class Util { public static String TAG="UTIL"; public static Bitmap getbitmap(String imageUri) { Log.v(TAG, "getbitmap:" + imageUri); // 显示网络上的图片 Bitmap bitmap = null; try { URL myFileUrl = new URL(imageUri); HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection(); conn.setDoInput(true); conn.connect(); InputStream is = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(is); is.close(); Log.v(TAG, "image download finished." + imageUri); } catch (IOException e) { e.printStackTrace(); Log.v(TAG, "getbitmap bmp fail---"); return null; } return bitmap; } }
顺便提一下,虽然这里也是一个IUiListener的回调,但是onComplete的参数o的json数据内容与获取权限时的那个不一样,如下:
{ "ret": 0, "msg": "", "is_lost": 0, "nickname": "", "gender": "", "province": "", "city": "", "figureurl": "", "figureurl_1": "", "figureurl_2": "", "figureurl_qq_1": "", "figureurl_qq_2": "", "is_yellow_vip": "0", "vip": "0", "yellow_vip_level": "0", "level": "0", "is_yellow_year_vip": "0" }
也可参照官方文档: http://wiki.open.qq.com/wiki/v3/user/get_info
9.Handler部分(这里我只拿了头像和昵称,若要获得其他信息,对照上面这个json数据取相应的值就可以了)
//显示获取到的头像和昵称 private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 0) {//获取昵称 tvNickName.setText((CharSequence) msg.obj); } else if (msg.what == 1) {//获取头像 headerLogo.setImageBitmap((Bitmap) msg.obj); } } };