Android开发实现QQ三方登录

本文分为两个部分:一是QQ的授权部分;二是获取用户的基本信息部分


一、授权部分


1.首先,先去腾讯开放平台获取APP ID和APP KEY(未注册腾讯开发者账号的可能需要先注册账号),获取的过程还是还是非常容易的(不用填写任何的应用程序信息)。

http://open.qq.com/



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。

        <!--QQ登录固定的-->
        <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"
            />
    </application>
    <!--QQ登录固定的-->

注意:上面<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 的实现类(BaseUiListener implements IUiListener)
    private BaseUiListener mListener;

        // 其中APP_ID是分配给第三方应用的appid,类型为String。
      mTencent = Tencent.createInstance(APP_ID, this.getApplicationContext());
      mListener = new BaseUiListener();

其中,BaseUiListener是IUiListener的实现类,其中的回调方法用来接收授权后的相关信息:

 class BaseUiListener implements IUiListener {
        @Override
        public void onComplete(Object o) {

            Log.e("hzq", "onComplete" + o.toString());

            JSONObject jsonObject = (JSONObject) o;

            //设置openid和token,否则获取不到下面的信息
            initOpenidAndToken(jsonObject);
            //获取QQ用户的各信息
            getUserInfo();
        }

        @Override
        public void onError(UiError UiError) {
            Log.e("hzq", "UiError" + UiError.errorMessage);
            Log.e("hzq", "UiError" + UiError.errorDetail);
            Log.e("hzq", "UiError" + UiError.errorCode);

        }

        @Override
        public void onCancel() {
            Log.e("hzq", "onCancel");

        }
    }

注意别忘了覆写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": "8E38FB320194A2920E2C7397E6E5A56B",
    "access_token": "8175AB49A2884507C4AC5A73CBCB9EE5",
    "pay_token": "C11B12C8F992F70E932E34C0B5666D78",
    "expires_in": 7776000,
    "pf": "desktop_m_qq-10000144-android-2002-",
    "pfkey": "b1aaa8cd223aac7d01f59396f18f12bd",
    "msg": "",
    "login_cost": 620,
    "query_authority_cost": 478,
    "authority_cost": 0
}

二、获取用户的基本信息部分。(有用到上一部分onComplete回调方法中传回来的Object对象)


上面只是实现了授权,并未拿到用户的基本信息,下面是这部分的实现


8.在第6步中的onComplete回调方法中添加以下语句

  @Override
        public void onComplete(Object o) {

            Log.e("hzq", "onComplete" + o.toString());

            JSONObject jsonObject = (JSONObject) o;

            //设置openid和token,否则获取不到下面的信息
            initOpenidAndToken(jsonObject);
            //获取QQ用户的各信息
            getUserInfo();
        }

{
    "ret": 0,
    "msg": "",
    "is_lost": 0,
    "nickname": "意志坚强",
    "gender": "男",
    "province": "广东",
    "city": "广州",
    "figureurl": "http://qzapp.qlogo.cn/qzapp/1106281035/8E38FB320194A2920E2C7397E6E5A56B/30",
    "figureurl_1": "http://qzapp.qlogo.cn/qzapp/1106281035/8E38FB320194A2920E2C7397E6E5A56B/50",
    "figureurl_2": "http://qzapp.qlogo.cn/qzapp/1106281035/8E38FB320194A2920E2C7397E6E5A56B/100",
    "figureurl_qq_1": "http://q.qlogo.cn/qqapp/1106281035/8E38FB320194A2920E2C7397E6E5A56B/40",
    "figureurl_qq_2": "http://q.qlogo.cn/qqapp/1106281035/8E38FB320194A2920E2C7397E6E5A56B/100",
    "is_yellow_vip": "0",
    "vip": "0",
    "yellow_vip_level": "0",
    "level": "0",
    "is_yellow_year_vip": "0"
}

其中,initOpenidAndToken 与 getUserInfo的实现如下

public 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();
        }
    }

    public 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;

                Log.e("hzq", "userInfoJson-->" + userInfoJson.toString());
                try {
                    String nickname = userInfoJson.getString("nickname");//直接传递一个昵称的内容过去
                mHandler.obtainMessage(0, nickname).sendToTarget();
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                //子线程 获取并传递头像图片,由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 = Utils.getbitmap(headUrl);
                            mHandler.obtainMessage(1, bitmapHead).sendToTarget();
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                        }
                    }
                }).start();

                try {
                    Object province = userInfoJson.get("province");
                    mHandler.obtainMessage(2, province).sendToTarget();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                //                handler.obtainMessage(what, getLinkstr(result))
                //                        .sendToTarget();
            }

            @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();
            }
        });
    }


其中,自定义的Utils类如下

public class Utils {
    public static String TAG="hzq";
    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": "http://qzapp.qlogo.cn/qzapp/1106281035/8E38FB320194A2920E2C7397E6E5A56B/30",
    "figureurl_1": "http://qzapp.qlogo.cn/qzapp/1106281035/8E38FB320194A2920E2C7397E6E5A56B/50",
    "figureurl_2": "http://qzapp.qlogo.cn/qzapp/1106281035/8E38FB320194A2920E2C7397E6E5A56B/100",
    "figureurl_qq_1": "http://q.qlogo.cn/qqapp/1106281035/8E38FB320194A2920E2C7397E6E5A56B/40",
    "figureurl_qq_2": "http://q.qlogo.cn/qqapp/1106281035/8E38FB320194A2920E2C7397E6E5A56B/100",
    "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) {
                Log.e("hzq", "获取昵称--->" + (CharSequence) msg.obj);

            } else if (msg.what == 1) {
               //获取头像
                Log.e("hzq", "获取头像--->" + (Bitmap) msg.obj);
                iv_head.setImageBitmap((Bitmap) msg.obj);
            } else if (msg.what == 2) {
                //获取省份
                Log.e("hzq", "获取省份--->" + msg.obj);
            }
        }
    };

源码下载:源码地址 http://download.csdn.net/download/hzqit520/9953507







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值