Android 实现QQ、微信、新浪微博和百度第三方登陆

前言: 
对于大多数的APP都有第三方登陆这个功能,本身也作过几回,最近又有一个新项目用到了第三方登陆,因此特地总结了一下关于第三方登陆的实现,并拿出来与你们一同分享;html

各大开放平台注册帐户获取AppKey和AppSecret 
Mob开放平台地址:http://www.mob.com/#/index 
QQ开放平台地址:http://open.qq.com/ 
新浪微博开放平台地址:http://open.weibo.com/ 
微信开放平台地址:https://open.weixin.qq.com/ 
百度开放平台地址:http://apps.bdimg.com/android

注: 
1、关于各大开放平台的开发者用户注册和建立应用获取AppKey、AppSecret我就很少说了,对于你们来讲这都so easy; 
2、Eclipse在建立应用填写包名应该是manifest里面的packpage: 
这里写图片描述 
studio的则是build.gradle里面的applicationId: 
这里写图片描述 
通常状况下,studioapplicationIdmanifest下的包名是一致的,可是applicationId是手动改变的,因此注意在建立应用的时候,要使用applicationIdjson

新浪微博第三方登陆实现:api

在作新浪微博第三方登陆的时候,参考他们的api文档,感受他们的api文档写的特别的乱,而且下载的Demo运行还报错,以致于浪费了我大半天的时间,去网上搜了几篇关于第三方登陆的文章,写的并不全,时代也比较久远,而且基本没有相关Demo下载,有的就是拷贝的新浪微博的开放平台的原文,我也是醉了….. 
因为时间比较紧迫,因此并无再继续深究下去。你们应该都知道有许多平台把例如分享、登陆等功能集成好了,实现功能十分简单,这一次我是利用的Mob移动开发平台http://www.mob.com/#/index 实现的新浪微博第三方登陆,感受还不错实现起来比较简单。服务器

1、下载Mob平台的SDK 
首先下载SDK,获得咱们须要的资源微信

SDK地址(http://www.mob.com/#/downloadDetail/ShareSDK/android),下载下来发现没法解压(大家能够试一下),联系他们客服,他们说:上传错误,就给我发了一个。我把它和个人Dmeo放在一块儿,可供下载。 
找到ShareSDK for Android包下的QuickIntegrater.jar文件双击: 
这里写图片描述
感受还不错,各大平台都有,只须要选择新浪微博就能够(我感受仍是没包装过的比较好,因此另外三种登陆方式没采用这种方法),解压以后生成一个Sample文件: 
这里写图片描述
咱们须要把里面的东西所有拿到咱们的studio项目中,libs、res和src里面的所有拷贝复制就能够,studio新建assets的方法和Eclipse不同,因此给你们发个图: 
这里写图片描述
点击建立就能够了,再把assets下的ShareSDK.xml拷贝就去;网络

其次配置ShareSDK 
把ShareSDK拷贝进去以后,咱们须要把ShareSDK.xml文件中关于Mob(ShareSDK)和新浪微博(SinaWeibo)的Appkey、AppSecret和RedirectUrl替换成咱们申请的值,以下图: 
这里写图片描述app

把红箭头中的ShareSDK中的AppKey换成咱们在Mob后台申请的AppKey; 
红框框中的SinaWeibo中的AppKey、AppSecret和RedirectUrl换成咱们在新浪微博后台申请的对应的值; 
RedirectUrl这个字段的值就是咱们后台项目中的应用信息——>高级信息——>OAuth2.0 受权设置中的受权回调页这个字段,须要咱们填写一个有效的地址就能够,例以下图:ide

这里写图片描述
注:若是RedirectUrl这个字段不填或填写不对会报如下错误: 
这里写图片描述测试

2、配置AndroidManifest.xml 
添加activity信息

<activity
     android:name="com.mob.tools.MobUIShell"
     android:theme="@android:style/Theme.Translucent.NoTitleBar"
     android:configChanges="keyboardHidden|orientation|screenSize"
     android:screenOrientation="portrait"
     android:windowSoftInputMode="stateHidden|adjustResize" >
 </activity>

2、添加代码 

首先是Mob的受权,在程序的入口处添加受权代码:

//Mob平台受权
ShareSDK.initSDK(this);

其次直接调用thirdSinaLogin()方法就能够了:

 
//-----------------------------------------------------新浪微博受权相关--------------
    /** 新浪微博受权、获取用户信息页面 */
    private void thirdSinaLogin() {
        //初始化新浪平台
        Platform pf = ShareSDK.getPlatform(MainActivity.this, SinaWeibo.NAME);
        pf.SSOSetting(true);
        //设置监听
        pf.setPlatformActionListener(MainActivity.this);
        //获取登录用户的信息,若是没有受权,会先受权,而后获取用户信息
        pf.authorize();
    }
    /** 新浪微博受权成功回调页面 */
    @Override
    public void onComplete(Platform platform, int action, HashMap<String, Object> hashMap) {
        /** res是返回的数据,例如showUser(null),返回用户信息,对其解析就行
         *   http://sharesdk.cn/androidDoc/cn/sharesdk/framework/PlatformActionListener.html
         *
         */
        Message msg = new Message();
        msg.what = MSG_ACTION_CCALLBACK;
        msg.arg1 = 1;
        msg.arg2 = action;
        msg.obj = platform;
        UIHandler.sendMessage(msg, this);
    }
    /** 取消受权 */
    @Override
    public void onCancel(Platform platform, int action) {
        Message msg = new Message();
        msg.what = MSG_ACTION_CCALLBACK;
        msg.arg1 = 3;
        msg.arg2 = action;
        msg.obj = platform;
        UIHandler.sendMessage(msg, this);
    }
    /** 受权失败 */
    @Override
    public void onError(Platform platform, int action, Throwable t) {
        t.printStackTrace();
        t.getMessage();
        Message msg = new Message();
        msg.what = MSG_ACTION_CCALLBACK;
        msg.arg1 = 2;
        msg.arg2 = action;
        msg.obj = t;
        UIHandler.sendMessage(msg, this);
    }

    @Override
    public boolean handleMessage(Message msg) {
        switch(msg.what) {
            case MSG_TOAST: {
                String text = String.valueOf(msg.obj);
                Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
            }
            break;
            case MSG_ACTION_CCALLBACK: {
                switch (msg.arg1) {
                    case 1: {
                        // 成功, successful notification
                        //受权成功后,获取用户信息,要本身解析,看看oncomplete里面的注释
                        //ShareSDK只保存如下这几个通用值
                        Platform pf = ShareSDK.getPlatform(MainActivity.this, SinaWeibo.NAME);
                        Log.e("sharesdk use_id", pf.getDb().getUserId()); //获取用户id
                        Log.e("sharesdk use_name", pf.getDb().getUserName());//获取用户名称
                        Log.e("sharesdk use_icon", pf.getDb().getUserIcon());//获取用户头像
                        mThirdLoginResult.setText("受权成功"+"\n"+"用户id:" + pf.getDb().getUserId() + "\n" + "获取用户名称" + pf.getDb().getUserName() + "\n" + "获取用户头像" + pf.getDb().getUserIcon());
                        //mPf.author()这个方法每一次都会调用受权,出现受权界面
                        //若是要删除受权信息,从新受权
                        //mPf.getDb().removeAccount();
                        //调用后,用户就得从新受权,不然下一次就不用受权
                        }
                    break;
                    case 2: {
                        mThirdLoginResult.setText("登陆失败");
                    }
                    break;
                    case 3: {
                        // 取消, cancel notification
                        mThirdLoginResult.setText("取消受权");
                    }
                    break;
                }
            }
            break;
            case MSG_CANCEL_NOTIFY: {
                NotificationManager nm = (NotificationManager) msg.obj;
                if (nm != null) {
                    nm.cancel(msg.arg1);
                }
            }
            break;
        }
        return false;
    }

最后退出登陆

 Platform mPf = ShareSDK.getPlatform(MainActivity.this, SinaWeibo.NAME);
    //若是要删除受权信息,从新受权
    mPf.getDb().removeAccount();

到这里关于新浪微博第三方登陆的就基本结束了,咱们获取到了用户的id、昵称、头像地址等信息,使用惟一值id再结合本身服务器的接口,即可实现第三方登陆了.效果图以下: 
这里写图片描述 
这里写图片描述 
这里写图片描述

注意:若是你想修改受权的登陆页面,能够参考 
这个连接里面的第11条

QQ第三方登陆实现:

注意 
1、我不建议你们去看QQ开放平台关于获取我的信息那部分的文档,由于他们的文档已通过时了,我当时按照文档作过,可是一直报错,后来问客服,他告诉我他们的文档它久远了,已经不能用了<当时我就醉了、、>,而是给了我一份Demo,我会把Demo放在里面供你们下载。 
2、你们使用的测试机必定要是自动获取的网络时间,不然得不到信息,而且也没有错误信息,我研究了半天的时间,也没找到到底为何,一问客服才知道,服务器时间和请求时间戳要相同才能够<我又是醉了、、、>。 
3、你们要打包APP再进行测试。

QQ第三方登陆的步骤分为: 
1.先登陆成功获取token和openid 
2.再经过token和openid获取用户的信息。

1、导入SDK的jar文件 
把这两个jar文件导入项目中 
这里写图片描述

2、配置AndroidManifest

 
<!-- 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" />

        <data android:scheme="tencent你的APPId" />
    </intent-filter>
</activity>
<activity android:name="com.tencent.connect.common.AssistActivity"
    android:theme="@android:style/Theme.Translucent.NoTitleBar"
    android:configChanges="orientation|keyboardHidden|screenSize"
    />
 <!-- QQ第三方登陆相关结束 -->

scheme这个字段输入你申请的appid,tencent不要删掉。

3、添加代码 
首先在程序入口添加:

Tencent mTencent = Tencent.createInstance(你的AppId, this.getApplicationContext());

剩下的调用loginQQ方法即可以:

/** ------------------------QQ第三方登陆-------------------- */
    public void loginQQ(){
        /** 判断是否登录过 */
        if (!mTencent.isSessionValid()){
            mTencent.login(this, "all",loginListener);
        }/** 登录过注销以后在登陆 */
        else {
            mTencent.logout(this);
            mTencent.login(this, "all",loginListener);
        }
    }
    IUiListener loginListener = new BaseUiListener() {
        @Override
        protected void doComplete(JSONObject values) {
            initOpenidAndToken(values);
            updateUserInfo();
        }
    };
    /** QQ登陆第二步:存储token和openid */
    public static void initOpenidAndToken(JSONObject jsonObject) {
        try {
            String token = jsonObject.getString(Constants.PARAM_ACCESS_TOKEN);
            String expires = jsonObject.getString(Constants.PARAM_EXPIRES_IN);
            String openId = jsonObject.getString(Constants.PARAM_OPEN_ID);
            if (!TextUtils.isEmpty(token) && !TextUtils.isEmpty(expires) && !TextUtils.isEmpty(openId)) {
                mTencent.setAccessToken(token, expires);
                mTencent.setOpenId(openId);
            }
        } catch(Exception e) {
        }
    }
    /** QQ登陆第三步:获取用户信息 */
    private void updateUserInfo() {
        if (mTencent != null && mTencent.isSessionValid()) {
            IUiListener listener = new IUiListener() {
                @Override
                public void onError(UiError e) {
                    Message msg = new Message();
                    msg.obj = "把手机时间改为获取网络时间";
                    msg.what = 1;
                    mHandler.sendMessage(msg);
                }

                @Override
                public void onComplete(final Object response) {
                    Message msg = new Message();
                    msg.obj = response;
                    msg.what = 0;
                    mHandler.sendMessage(msg);
                }
                @Override
                public void onCancel() {
                    Message msg = new Message();
                    msg.obj = "获取用户信息失败";
                    msg.what = 2;
                    mHandler.sendMessage(msg);
                }
            };
            mInfo = new UserInfo(this, mTencent.getQQToken());
            mInfo.getUserInfo(listener);
        } else {

        }
    }
    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
        /** 获取用户信息成功 */
            if (msg.what == 0) {
                JSONObject response = (JSONObject) msg.obj;
                if (response.has("nickname")) {
                    try {
                        log("获取用户信息成功,返回结果:"+response.toString());
                        mThirdLoginResult.setText("登陆成功\n"+"用户id:"+openid+"\n昵称:"+response.getString("nickname")+"\n头像地址:"+response.get("figureurl_qq_1"));
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }else if(msg.what == 1){
                mThirdLoginResult.setText(msg+"");
            }else if(msg.what == 2){
                mThirdLoginResult.setText(msg+"");
            }
        }

    };
    /** QQ登陆第一步:获取token和openid */
    private class BaseUiListener implements IUiListener {
        @Override
        public void onComplete(Object response) {
            if (null == response) {
                mToast("登陆失败");
                return;
            }
            JSONObject jsonResponse = (JSONObject) response;
            if (null != jsonResponse && jsonResponse.length() == 0) {
                mToast("登陆失败");
                return;
            }
            log("QQ登陆成功返回结果-" + response.toString());
            doComplete((JSONObject)response);
        }
        protected void doComplete(JSONObject response) {}
        @Override
        public void onError(UiError e) {
            Util.toastMessage(MainActivity.this, "onError: " + e.errorDetail);
            Util.dismissDialog();
        }
        @Override
        public void onCancel() {
            Util.toastMessage(MainActivity.this, "onCancel: ");
            Util.dismissDialog();
            if (isServerSideLogin) {
                isServerSideLogin = false;
            }
        }
    }
    /** -------------------------QQ第三方登陆结束-------------------- */

代码有注释,你们看一下应该很容易明白。

QQ能够得到如下相关信息: 
你们只要response.getString(“字段名”)就能够获得数据了:

{
    "is_yellow_year_vip": "0",
    "ret": 0,
    "figureurl_qq_1": "http://q.qlogo.cn/qqapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/40",
    "figureurl_qq_2": "http://q.qlogo.cn/qqapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/100",
    "nickname": "小罗",
    "yellow_vip_level": "0",
    "msg": "",
    "figureurl_1": "http://qzapp.qlogo.cn/qzapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/50",
    "vip": "0",
    "level": "0",
    "figureurl_2": "http://qzapp.qlogo.cn/qzapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/100",
    "is_yellow_vip": "0",
    "gender": "",
    "figureurl": "http://qzapp.qlogo.cn/qzapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/30"
}

最后退出登陆:

mTencent.logout(this);

给你们看一下截图: 
这里写图片描述

微信第三方登陆 
微信平台仍是作得挺不错的,你们能够看一下他们的文档,只不过咱们须要本身写网络请求(衰衰衰衰衰)

微信第三方登陆分为: 
1.获取code 
2.根据code获取token 
3.根据token获取用户信息 
在第2、三步须要咱们本身去写网络请求,我也是醉了。。。。

1、导入SDK的libammsdk.jar文件,我就很少说了 
2、配置AndroidManifest 
在你的build.gradle的applicationId相应目录下新建一个wxapi目录,在该wxapi目录下新增一个WXEntryActivity类,该类继承自Activity(例如应用程序build.gradle的applicationId为com.aohuan.jinghai_lifee,则新添加的类以下图所示) 
这里写图片描述
并在manifest文件里面加上exported属性,设置为true,例如:

<activity
   android:name="com.aohuan.jinghai_lifee.wxapi.WXEntryActivity"
    android:exported="true"
    android:label="@string/app_name" >
</activity>

3、添加代码

 
/** -------------------------微信第三方登陆---------------------- */
    /**
     *
     * 微信平台应用受权登陆接入代码示例
     *
     * */
    private void regToWx(){
        // 经过WXAPIFactory工厂,得到IWXAPI的实例
        api = WXAPIFactory.createWXAPI(MainActivity.this, AllApk.WEIXIN_APP_ID, true);
        // 将应用的appid注册到微信
        api.registerApp(AllApk.WEIXIN_APP_ID);
    }
    //获取微信访问getCode
    private void getCode(){
        final SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "carjob_wx_login";
        api.sendReq(req);
    }
    /** -------------------------微信第三方登陆结束-------------------- */

首先在onCreate()方法里面调用regToWx()方法实现微信平台的注册; 
其次第一步获取code 
调用getCode()方法发送获取code的请求,接受code则是在WXEntryActivity这个类里面的onResp(): 
这里写图片描述

第二步使用AsyncTask获取token: 
这里写图片描述

/** 微信登陆第二步:获取token */
    class AsynctaskToken extends AsyncTask<Object , Object , Object> {
        @Override
        protected Object doInBackground(Object... params) {
            HttpGet httpRequest = new HttpGet(params[0].toString());
            try{
                HttpClient httpClient = new DefaultHttpClient();
                HttpResponse httpResponse = httpClient.execute(httpRequest);
                if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                    BaseActivity.log("请求我的信息成功");
                    String strResult = EntityUtils.toString(httpResponse.getEntity());
                    return strResult;
                }
                else{
                    BaseActivity.log("请求我的信息失败");
                    return "请求出错";
                }
            }
            catch(ClientProtocolException e){
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
        }
        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
            Object obj = null;
            try {
                obj = JsonUtil.toObjectByJson(o.toString(), WeiXinLoginGetTokenBean.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
            WeiXinLoginGetTokenBean bean = (WeiXinLoginGetTokenBean)obj;
            BaseActivity.log("获取token成功:\n" + "token:"+bean.getAccess_token()+"\nopenid"+bean.getOpenid());
            String url = "https://api.weixin.qq.com/sns/userinfo?"+"access_token="+bean.getAccess_token()+"&openid="+bean.getOpenid();
            new AsynctaskInfo().execute(url);
        }
        @Override
        protected void onProgressUpdate(Object... values) {
            super.onProgressUpdate(values);
        }
    }

第三步获取用户信息:

 
/** 微信登陆第三步:获取用户信息 */
    class AsynctaskInfo extends AsyncTask<Object , Object , Object> {
        @Override
        protected Object doInBackground(Object... params) {
            HttpGet httpRequest = new HttpGet(params[0].toString());
            try{
                HttpClient httpClient = new DefaultHttpClient();
                HttpResponse httpResponse = httpClient.execute(httpRequest);
                if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                    BaseActivity.log("请求我的信息成功");
                    String strResult = EntityUtils.toString(httpResponse.getEntity());
                    return strResult;
                }
                else{
                    BaseActivity.log("请求我的信息失败");
                    return "请求出错";
                }
            }
            catch(ClientProtocolException e){
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
        }
        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
            Object obj = null;
            try {
                obj = JsonUtil.toObjectByJson(o.toString(), WeiXinLoginGetUserinfoBean.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
            WeiXinLoginGetUserinfoBean bean = (WeiXinLoginGetUserinfoBean)obj;
            BaseActivity.log("获取用户信息成功:\n" + "昵称:"+bean.getNickname()+"\n头像路径"+bean.getHeadimgurl());
            Toast.makeText(mContext,"获取用户信息成功:\n"+"昵称:"+bean.getNickname() + "\n头像路径:"+bean.getHeadimgurl(),Toast.LENGTH_LONG).show();
            finish();
        }
        @Override
        protected void onProgressUpdate(Object... values) {
            super.onProgressUpdate(values);
        }
    }

微信第三方登陆就结束了,相对来讲不算太复杂: 
这里写图片描述

注:测试微信登陆的时候,也须要打包测试,不然得不到数据;

百度第三方登陆 
百度第三方登陆,相对来讲就比较简单了

第一步:导入Baidu-Frontia-Full-Debug-2.0.6.jar包 
这里写图片描述

第二步:配置AndroidManifest.xml 
这里写图片描述
添加android:name=”com.baidu.frontia.ForntiaApplication”

第三步:添加代码 
在程序入口初始化Fronta” 

Frontia.init(this.getApplicationContext(),你的AppKey);

注册百度:

//注册百度
FrontiaAuthorization mAuthorization = Frontia.getAuthorization();

主要代码直接调用baiduLogin()方法就能够:

 
/**
     * 百度第三方登陆相关
     */
    protected void baiduLogin() {
        ArrayList<String> scope = new ArrayList<String>();
        scope.add(Scope_Basic);
        scope.add(Scope_Netdisk);
        mAuthorization.authorize(this, FrontiaAuthorization.MediaType.BAIDU.toString(), scope, new FrontiaAuthorizationListener.AuthorizationListener() {
            @Override
            public void onSuccess(FrontiaUser result) {
                if (null != mThirdLoginResult) {
                    mThirdLoginResult.setText("social id: " + result.getId() + "\n" + "token: " + result.getAccessToken() + "\n" + "expired: " + result.getExpiresIn());
                }
            }
            @Override
            public void onFailure(int errCode, String errMsg) {
                if (null != mThirdLoginResult) {
                    mThirdLoginResult.setText("errCode:" + errCode + ", errMsg:" + errMsg);
                }
            }
            @Override
            public void onCancel() {
                if (null != mThirdLoginResult) {
                    mThirdLoginResult.setText("cancel");
                }
            }
        });
    }

退出登陆调用baiduExit()方法就能够:

/**
* 百度第三方退出相关
*/
protected void baiduExit() {
   boolean result = mAuthorization.clearAuthorizationInfo(FrontiaAuthorization.MediaType.BAIDU.toString());
   if (result) {
       mThirdLoginResult.setText("百度退出成功");
   } else {
       mThirdLoginResult.setText("百度退出失败");
   }
}

百度登陆,挺简单的吧 
这里写图片描述

1.四种登陆方式已经整理好了,若是有什么地方写错了或者漏掉的,请查看个人Demo或者提出来。 
2.因为这是第一次写博客,因此确定有写的很差的地方,你们有什么意见能够提出来,相互交流沟通,共同进步。 
3.因为个人源代码里面涉及到客户的信息,因此AppKey、AppSecret等信息,被我删掉了,若是想看个人Demo效果,须要修改小部分个人代码: 
第一:把我com.aohuan.jinghai_lifee.wxapi换成你的applicationId(对应的包名).wxapi 
这里写图片描述
第二:修改ShareSDK.xml里面对应的信息: 
这里写图片描述 
第三:修改manifest.xml里面对应的信息: 
这里写图片描述
第四:修改AllApk里面对应的信息: 
这里写图片描述
这样就能够了!!!

相关文章
相关标签/搜索