zoukankan      html  css  js  c++  java
  • Android 实现QQ、微信、新浪微博和百度第三方登录

    前言: 
    对于大多数的APP都有第三方登录这个功能,自己也做过几次,最近又有一个新项目用到了第三方登录,所以特意总结了一下关于第三方登录的实现,并拿出来与大家一同分享;

    各大开放平台注册账户获取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/

    注: 
    一、关于各大开放平台的开发者用户注册和创建应用获取AppKey、AppSecret我就不多说了,对于大家来说这都so easy; 
    二、Eclipse在创建应用填写包名应该是manifest里面的packpage: 
    这里写图片描述 
    studio的则是build.gradle里面的applicationId: 
    这里写图片描述 
    一般情况下,studioapplicationIdmanifest下的包名是一致的,但是applicationId是手动改变的,所以注意在创建应用的时候,要使用applicationId

    新浪微博第三方登录实现:

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

    一、下载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替换成我们申请的值,如下图: 
    这里写图片描述

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

    这里写图片描述
    注:如果RedirectUrl这个字段不填或填写不对会报以下错误: 
    这里写图片描述

    二、配置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>

    二、添加代码 

    首先是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("授权成功"+"
    "+"用户id:" + pf.getDb().getUserId() + "
    " + "获取用户名称" + pf.getDb().getUserName() + "
    " + "获取用户头像" + 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第三方登录实现:

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

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

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

    二、配置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不要删掉。

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

    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("登录成功
    "+"用户id:"+openid+"
    昵称:"+response.getString("nickname")+"
    头像地址:"+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获取用户信息 
    在第二、三步需要我们自己去写网络请求,我也是醉了。。。。

    一、导入SDK的libammsdk.jar文件,我就不多说了 
    二、配置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>

    三、添加代码

     
    /** -------------------------微信第三方登录---------------------- */
        /**
         *
         * 微信平台应用授权登录接入代码示例
         *
         * */
        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成功:
    " + "token:"+bean.getAccess_token()+"
    openid"+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("获取用户信息成功:
    " + "昵称:"+bean.getNickname()+"
    头像路径"+bean.getHeadimgurl());
                Toast.makeText(mContext,"获取用户信息成功:
    "+"昵称:"+bean.getNickname() + "
    头像路径:"+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() + "
    " + "token: " + result.getAccessToken() + "
    " + "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里面对应的信息: 
    这里写图片描述
    这样就可以了!!!

  • 相关阅读:
    1接口编程
    EXCEL读写NPOI--导出功能
    EXCEL读写NPOI
    多条件查询
    基础数据管理
    C#经典入门第22章XML-1
    数据访问C#入门经典第21章-监控文件系统
    数据访问C#入门经典第21章-读写压缩数据
    Tensorflow笔记(基础):池化函数
    4.2 Tensorflow笔记:池化函数
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/7231682.html
Copyright © 2011-2022 走看看