友盟第三方登录实现QQ和微信登录

来源:互联网 发布:高考网络应用服务平台 编辑:程序博客网 时间:2024/06/06 02:21

前言

市面上的app大部分都可以使用qq,微信这些第三方平台的账号来登录,这样可以提高用户体验,避免手工输入账号和密码的麻烦。那么第三方登录的原理到底是什么,以及使用友盟这个平台怎样实现qq和微信的联合登录?下面就来开始本片文章的正文。

原理

使用第三方登录,通过访问第三方平台,拿到QQ、微信的用户id,拿着第三方平台平台(QQ、微信)返回uid或者openid这些用户的唯一标识,然后拿着这些唯一标识访问自己APP的后台服务,如果已经在后台注册则直接登录返回用户信息。若没有登录会直接后台创建新的用户,并返回用户信息。下载再使用这个账号登录就可以直接登录了。这是一般APP第三方登录的流程。

流程图:

这里写图片描述

但是对于一些商城类的APP就不可以这么搞了,需要去绑定已经存在的用户。

流程图:

这里写图片描述

前期准备

  • 友盟后台申请AppKey

    这里写图片描述

    这里写图片描述

  • 微信开发者平台申请AppID,AppSecret
    链接:https://open.weixin.qq.com/
    申请微信的appId是比较麻烦的,首先需要在微信开发者平台上申请一个开发者账号,并进行开发者资质认证(花钱的)
    这里写图片描述

    认证完成后,点击移动应用,并按照要求一步一步填写信息,创建应用
    这里写图片描述

    这里写图片描述
    注意填写平台信息的时候需要填写一个应用签名,这个签名是和签名文件相对应的,一个签名文件对应一个签名。

  • 腾讯开发平台注册账号,申请appid和appkey
    链接: http://open.qq.com/
    申请QQ的appid没有像微信那么麻烦了,直接注册了账号就可以创建应用了
    这里写图片描述

接入步骤

官方文档:http://dev.umeng.com/social/android/quick-integration

  • 下载sdk

    根据需求下载对应平台的sdk,对于QQ,微信,新浪微博都有完整版和精简版的区别,这里自行选择。精简版的就可以实现第三方登录了。根据要实现的功能下载具体的版本。
    这里写图片描述

  • 拷贝资源(jar,res)到工程中

    拷贝jar和res有如下两种形式

    a .将main文件夹以及platform(选择你想使用的平台即可)文件下,对应的资源文件和jar放入你的工程

    这里写图片描述
    b.如果不想像a方式一样一个个拷贝,可以使用集成工具umeng_integrate_tool.jar

    双击点开这个工具,如下图所示:
    这里写图片描述

    选择你想使用的平台,以及你所使用的开发工具,点击ok 会在当前目录下生成一个新的文件夹umeng_integratetool_result
    只需将该文件夹下生成的对应文件对应放入你的工程中即可 这里注意如果使用了新浪微博精简版,或者豆瓣人人腾讯微博,需要加入umeng_social_shareview.jar及其对应的资源文件,如果没有使用这些平台可以不加 如果您的程序不想使用我们的分享面板,想自定义UI分享UI界面,umeng_social_shareboard.jar以及对应的资源文件也可以不用加 如果您使用了我们的分享面板,您的工程已经依赖的v4,可以不使用我们的umeng_shareboard_widget.jar

  • 添加对应的回调Activity

    使用微信分享或者登陆功能

    在包名目录下创建wxapi文件夹,新建一个名为WXEntryActivity的activity继承WXCallbackActivity。这里注意一定是包名路径下,例如我的包名是com.umeng.soexample,则配置如下:(需要注意,如果使用精简版WXCallbackActivity的路径为com.umeng.weixin.callback.WXCallbackActivity,如果使用完整版路径是com.umeng.socialize.weixin.view.WXCallbackActivity)
    这里写图片描述

    同理需要建立回调的平台还有支付宝与易信,支付宝是需要建立一个apshare的文件夹,然后建立一个ShareEntryActivity的类,继承ShareCallbackActivity。易信是需要建立一个yxapi的文件夹,建立一个YXEntryActivity的类继承YXCallbackActivity。如果不使用这两个平台可以不用建立。 同理新浪微博也需要一个回调的Activity,与微信不同的是它只需要在包名目录下建立一个名为WBShareActivity类即可,不用建立文件夹,该类继承WBShareCallBackActivity,如下图所示(注意看目录结构)
    这里写图片描述

  • 修改AndroidManiFest

    • 首先需要添加权限:

      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
    • 然后加入sdk中需要的Activity:

      新浪:

      <activity            android:name=".WBShareActivity"            android:configChanges="keyboardHidden|orientation"            android:screenOrientation="portrait" >            <intent-filter>                <action android:name="com.sina.weibo.sdk.action.ACTION_SDK_REQ_ACTIVITY" />                <category android:name="android.intent.category.DEFAULT" />            </intent-filter>        </activity>

      微信:

      <activity        android:name=".wxapi.WXEntryActivity"        android:configChanges="keyboardHidden|orientation|screenSize"        android:exported="true"        android:screenOrientation="portrait"        android:theme="@android:style/Theme.Translucent.NoTitleBar" />

      支付宝:

          <activity        android:name=".apshare.ShareEntryActivity"        android:configChanges="keyboardHidden|orientation|screenSize"        android:exported="true"        android:screenOrientation="portrait"        android:theme="@android:style/Theme.Translucent.NoTitleBar" />

      qq精简版:

          <activity            android:name="com.umeng.qq.tencent.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="tencent100424468" />            </intent-filter>    </activity>    <activity            android:name="com.umeng.qq.tencent.AssistActivity"            android:screenOrientation="portrait"            android:theme="@android:style/Theme.Translucent.NoTitleBar"            android:configChanges="orientation|keyboardHidden|screenSize"/>

      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="tencent100424468" />            </intent-filter>    </activity>    <activity            android:name="com.tencent.connect.common.AssistActivity"            android:screenOrientation="portrait"            android:theme="@android:style/Theme.Translucent.NoTitleBar"            android:configChanges="orientation|keyboardHidden|screenSize"/>

      添加友盟key:

          <meta-data            android:name="UMENG_APPKEY"            android:value="561cae6ae0f55abd990035bf" >    </meta-data>
  • 修改build.gradle文件

    • 将文件夹中的签名文件放入到工程中,例如我的签名文件是appKey.jks
      这里写图片描述

    • 然后增加签名文件的密码:

        signingConfigs {        debug {            storeFile file('../appKey.jks')            storePassword "******"            keyAlias "******"            keyPassword "******"        }    }
    • 然后在buildTypes中将这个signingConfigs配置进去,如下图所示:

      buildTypes {        release {            minifyEnabled false            signingConfig signingConfigs.debug            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }        debug {            minifyEnabled false            signingConfig signingConfigs.debug            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }
  • 配置各个平台的appkey

    • 在application文件中配置对应平台的key:

      {        PlatformConfig.setWeixin("wxbec65736501d0564", "82bc1e49bbb56cdded05cc8875d02ea79");        PlatformConfig.setQQZone("1105979137", "jODSgRir417714vY");    }
    • 在application中初始化sdk,这个初始化最好放在application的程序入口中,防止意外发生:

        UMShareAPI.get(this);

    以上以精简版的为例,如果是完整版的就需要把完整版的jar和res拷贝到工程中,在清单文件中配置完整版的activity。

  • 混淆文件

        -dontusemixedcaseclassnames    -dontshrink    -dontoptimize    -dontwarn com.google.android.maps.**    -dontwarn android.webkit.WebView    -dontwarn com.umeng.**    -dontwarn com.tencent.weibo.sdk.**    -dontwarn com.facebook.**    -keep public class javax.**    -keep public class android.webkit.**    -dontwarn android.support.v4.**    -keep enum com.facebook.**    -keepattributes Exceptions,InnerClasses,Signature    -keepattributes *Annotation*    -keepattributes SourceFile,LineNumberTable    -keep public interface com.facebook.**    -keep public interface com.tencent.**    -keep public interface com.umeng.socialize.**    -keep public interface com.umeng.socialize.sensor.**    -keep public interface com.umeng.scrshot.**    -keep class com.android.dingtalk.share.ddsharemodule.** { *; }    -keep public class com.umeng.socialize.* {*;}    -keep class com.facebook.**    -keep class com.facebook.** { *; }    -keep class com.umeng.scrshot.**    -keep public class com.tencent.** {*;}    -keep class com.umeng.socialize.sensor.**    -keep class com.umeng.socialize.handler.**    -keep class com.umeng.socialize.handler.*    -keep class com.umeng.weixin.handler.**    -keep class com.umeng.weixin.handler.*    -keep class com.umeng.qq.handler.**    -keep class com.umeng.qq.handler.*    -keep class UMMoreHandler{*;}    -keep class com.tencent.mm.sdk.modelmsg.WXMediaMessage {*;}    -keep class com.tencent.mm.sdk.modelmsg.** implements   com.tencent.mm.sdk.modelmsg.WXMediaMessage$IMediaObject {*;}    -keep class im.yixin.sdk.api.YXMessage {*;}    -keep class im.yixin.sdk.api.** implements im.yixin.sdk.api.YXMessage$YXMessageData{*;}    -keep class com.tencent.mm.sdk.** {     *;    }    -keep class com.tencent.mm.opensdk.** {   *;    }    -dontwarn twitter4j.**    -keep class twitter4j.** { *; }    -keep class com.tencent.** {*;}    -dontwarn com.tencent.**    -keep public class com.umeng.com.umeng.soexample.R$*{    public static final int *;    }    -keep public class com.linkedin.android.mobilesdk.R$*{    public static final int *;        }    -keepclassmembers enum * {    public static **[] values();    public static ** valueOf(java.lang.String);    }    -keep class com.tencent.open.TDialog$*    -keep class com.tencent.open.TDialog$* {*;}    -keep class com.tencent.open.PKDialog    -keep class com.tencent.open.PKDialog {*;}    -keep class com.tencent.open.PKDialog$*    -keep class com.tencent.open.PKDialog$* {*;}    -keep class com.sina.** {*;}    -dontwarn com.sina.**    -keep class  com.alipay.share.sdk.** {       *;    }    -keepnames class * implements android.os.Parcelable {    public static final ** CREATOR;    }    -keep class com.linkedin.** { *; }    -keepattributes Signature
  • 调用代码:友盟官方有两种方式,一种直接获取用户资料,另外一种是先去授权,获取accesstoken后再去回去用户资料,对于安全性要求高的话可以使用第二种方式。这里以第一种为例:

    • UMShareAPI.get(this).getPlatformInfo(this, SHARE_MEDIA.WEIXIN, authListener);
    • 其中umAuthListener为授权回调,构建如下,其中授权成功会回调onComplete,取消授权回调onCancel,授权错误回调onError,对应的错误信息可以用过onError的Throwable参数来打印

      private UMAuthListener umAuthListener = new UMAuthListener() { @Override    public void onStart(SHARE_MEDIA platform) {       //授权开始的回调    }    @Override    public void onComplete(SHARE_MEDIA platform, int action, Map<String, String> data) {        Toast.makeText(getApplicationContext(), "Authorize succeed", Toast.LENGTH_SHORT).show();    }    @Override    public void onError(SHARE_MEDIA platform, int action, Throwable t) {        Toast.makeText( getApplicationContext(), "Authorize fail", Toast.LENGTH_SHORT).show();    }    @Override    public void onCancel(SHARE_MEDIA platform, int action) {        Toast.makeText( getApplicationContext(), "Authorize cancel", Toast.LENGTH_SHORT).show();    }};
    • 最后在登录所在的Activity里复写onActivityResult方法,注意不可在fragment中实现,如果在fragment中调用登录,在fragment依赖的Activity中实现,如果不实现onActivityResult方法,会导致登录或回调无法正常进行

      @Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    super.onActivityResult(requestCode, resultCode, data);    UMShareAPI.get(this).onActivityResult(requestCode, resultCode, data);}
  • 登录成功后,第三方平台会将用户资料传回, 全部会在Map data中返回 ,由于各个平台对于用户资料的标识不同,因此为了便于开发者使用,我们将一些常用的字段做了统一封装,开发者可以直接获取,不再需要对不同平台的不同字段名做转换,这里列出封装的字段及含义
    这里写图片描述

  • 用户资料与各平台的对应关系:

    • QQ

      name:name(6.2以前用screen_name)

      用户id:uid

      accesstoken: accessToken (6.2以前用access_token)

      过期时间:expiration (6.2以前用expires_in)

      性别:gender

      头像:iconurl(6.2以前用profile_image_url)

      是否黄钻:is_yellow_year_vip

      黄钻等级:yellow_vip_level

      城市:city

      省份:province

    • 微信

      微信返回的openID和unionID都可以实现用户标识的需求,二者的区别在于,unionID可以实现同一个开发者账号下的应用之间账号打通的需求

      openid:openid

      unionid:(6.2以前用unionid)用户id

      accesstoken: accessToken (6.2以前用access_token)

      refreshtoken: refreshtoken: (6.2以前用refresh_token)

      过期时间:expiration (6.2以前用expires_in)

      name:name(6.2以前用screen_name)

      城市:city

      省份:prvinice

      国家:country

      性别:gender

      头像:iconurl(6.2以前用profile_image_url)

效果:

QQ
这里写图片描述

返回的信息

这里写图片描述

微信

这里写图片描述

返回的信息

这里写图片描述

拿到对应平台的信息后,用uid或openid请求服务器,进行后续的操作。每个app的产品定义可能会有一定的差别。这里就不在说,大体流程在上面已经说过。

0 0
原创粉丝点击