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

前言

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

原理

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

流程图:

友盟第三方登录实现QQ和微信登录_第1张图片

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

流程图:

友盟第三方登录实现QQ和微信登录_第2张图片

前期准备

  • 友盟后台申请AppKey

    友盟第三方登录实现QQ和微信登录_第3张图片

    友盟第三方登录实现QQ和微信登录_第4张图片

  • 微信开发者平台申请AppID,AppSecret
    链接:https://open.weixin.qq.com/
    申请微信的appId是比较麻烦的,首先需要在微信开发者平台上申请一个开发者账号,并进行开发者资质认证(花钱的)
    友盟第三方登录实现QQ和微信登录_第5张图片

    认证完成后,点击移动应用,并按照要求一步一步填写信息,创建应用
    友盟第三方登录实现QQ和微信登录_第6张图片

    友盟第三方登录实现QQ和微信登录_第7张图片
    注意填写平台信息的时候需要填写一个应用签名,这个签名是和签名文件相对应的,一个签名文件对应一个签名。

  • 腾讯开发平台注册账号,申请appid和appkey
    链接: http://open.qq.com/
    申请QQ的appid没有像微信那么麻烦了,直接注册了账号就可以创建应用了
    友盟第三方登录实现QQ和微信登录_第8张图片

接入步骤

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

  • 下载sdk

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

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

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

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

    友盟第三方登录实现QQ和微信登录_第10张图片
    b.如果不想像a方式一样一个个拷贝,可以使用集成工具umeng_integrate_tool.jar

    双击点开这个工具,如下图所示:
    友盟第三方登录实现QQ和微信登录_第11张图片

    选择你想使用的平台,以及你所使用的开发工具,点击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)
    友盟第三方登录实现QQ和微信登录_第12张图片

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

  • 修改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:

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

    • 将文件夹中的签名文件放入到工程中,例如我的签名文件是appKey.jks
      友盟第三方登录实现QQ和微信登录_第14张图片

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

        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 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方法,会导致登录或回调无法正常进行

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

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

    • 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
友盟第三方登录实现QQ和微信登录_第16张图片

返回的信息

友盟第三方登录实现QQ和微信登录_第17张图片

微信

友盟第三方登录实现QQ和微信登录_第18张图片

返回的信息

友盟第三方登录实现QQ和微信登录_第19张图片

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

你可能感兴趣的:(友盟第三方登录实现QQ和微信登录)