项目中不泛使用第三方登录 常用的有QQ、新浪微博、微信等

原理基本都是一样的,就是客户端通过按钮去点击 吊起第三方应用AIDL等用第三方账号密码授权 确认授权后返回token/code等唯一标识(证明这个这个第三方账号是你本人)的字符串,把字符串在客户端按type区分,如:手机登录type=0,qq登录type=1,微信登录type=2……

然后把这个唯一标识和type发给服务器去校验 服务器获取第三方账号的个人信息(头像/昵称等)存到数据库,分配应用内唯一的uid,然后返回表明注册成功的json(如

{ret:true,user:{用户信息}}

),客户端解析后确认登录成功,把用户信息存到本地,这样下次客户端再登录的时候就不用去重新登录了。。当然token是有有效期的,主要看服务器怎么去处理,当然一般都不会去处理。。。

下面直接贴代码,主要讲解QQ,新浪微博,微信的客户端操作,因为主要是说明实际操作方法 像友盟,ShareSDK集成好的直接看文档就行,这里说的是没集成过的原生第三方。

首先就是导入jar包,微信是libammsdk.jar/QQ是open_sdk_XXXX.jar/微博是weibosdkcore_xxxx.jar

同时微信需要在项目主包内导入wxapi.WXEntryActivity

首先需要处理清单文件

[html]  view plain copy
  1. <activity
  2. android:name="com.tencent.tauth.AuthActivity"
  3. android:launchMode="singleTask"
  4. android:noHistory="true" >
  5. <intent-filter>
  6. <action android:name="android.intent.action.VIEW" />
  7. <category android:name="android.intent.category.DEFAULT" />
  8. <category android:name="android.intent.category.BROWSABLE" />
  9. <data android:scheme="'tencent'+在腾讯开发者平台获取的tencentid,如tencent12345678" />
  10. </intent-filter>
  11. </activity>
  12. <activity
  13. android:name="com.tencent.connect.common.AssistActivity"
  14. android:configChanges="orientation|keyboardHidden"
  15. android:screenOrientation="portrait"
  16. android:theme="@android:style/Theme.Translucent.NoTitleBar" />
  17. <!-- 必须注册在微博授权,分享微博时候用到 -->
  18. <activity
  19. android:name="com.sina.weibo.sdk.component.WeiboSdkBrowser"
  20. android:configChanges="keyboardHidden|orientation"
  21. android:exported="false"
  22. android:windowSoftInputMode="adjustResize" />
  23. <span style="white-space:pre">    </span><activity
  24. android:name=".wxapi.WXEntryActivity"
  25. android:configChanges="keyboardHidden|orientation|screenSize"
  26. android:exported="true"
  27. android:screenOrientation="portrait"
  28. android:theme="@android:style/Theme.Translucent.NoTitleBar" />

然后写两个工具类 Settings和Global ,Settings存储SharePreference对象 用户用户的读取

比如saveUser() getUser() saveCurrentUser() getCurrentUser()这个方法就不多说了 主要看自己的实现
然后是初始化操作 比如首先进入MainActivity 在onCreate里初始化IWXAPI对象 然后调用getCurrentUser() 如果获取为null或者为-1(以uid存储)那么就直接跳转到登录页

如果登录后有操作就startActivityResult或者发广播..

基本原理就是这样

----------------------------

然后建立一个与账号操作相关的基类Activity(为什么与账号相关?因为应用内有可能不只登录会用到这个类 有可能会有账号绑定等页面 这时候就省的去重复写方法了。。)

[java]  view plain copy
  1. public class AuthenticatorActivity extends BaseActivity implements WeiboAuthListener, IUiListener {
  2. public static final int EXISTED_USER_ERROR = 2005;
  3. private static final String TAG = AuthenticatorActivity.class.getName();
  4. protected static final int VALUE_APP = 1;
  5. protected static final int VALUE_SINA = 2;
  6. protected static final int VALUE_QQ = 3;
  7. protected static final int VALUE_WECHAT = 4;
  8. protected static final String KEY_TOKEN = "token";
  9. protected static final String KEY_OPEN_ID = "openid";
  10. protected static final String KEY_USERNAME = "username";
  11. protected static final String KEY_PASSWORD = "password";
  12. protected static final String KEY_EMAIL = "email";
  13. protected static final int REQUEST_CODE_BIND_OR_REGISTER = 1;
  14. protected static final int REQUEST_CODE_COMPLETE_INFO = 2;
  15. protected AuthInfo mWeiboAuth;
  16. protected Oauth2AccessToken accessToken;
  17. protected SsoHandler mSsoHandler;
  18. protected Tencent mTencent;
  19. private String errorMsg;
  20. //使用广播操作微信登录 注意下面的WXEntryActivity代码,授权成功返回code值当做唯一标识<span style="font-family: Arial, Helvetica, sans-serif;">   </span><span style="font-family: Arial, Helvetica, sans-serif;"> </span>
[java]  view plain copy
  1. BroadcastReceiver mReciver = new BroadcastReceiver() {
  2. @Override
  3. public void onReceive (Context context, Intent intent){
  4. if (intent.getBooleanExtra("result", false)) {
  5. String code = intent.getStringExtra("code");
  6. afterLogin(VALUE_WECHAT, code, code);
  7. } else {
  8. Toast.makeText(AuthenticatorActivity.this, getString(R.string.log_in_failed), Toast.LENGTH_SHORT).show();
  9. }
  10. }
  11. };
  12. @Override
  13. protected void onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. initTencent();
  16. initWeibo();
  17. initWechat();
  18. }
  19. @Override
  20. protected void onDestroy() {
  21. super.onDestroy();
  22. LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
  23. lbm.unregisterReceiver(mReciver);
  24. }
  25. protected void initTencent() {
  26. try {
  27. mTencent = Tencent.createInstance(Constants.TencentAppId, getApplicationContext());
  28. } catch (Throwable e) {
  29. e.printStackTrace();
  30. }
  31. }
  32. protected void initWeibo() {
  33. mWeiboAuth = new AuthInfo(this, Constants.SinaAppKey, Constants.SinaAppRedirectURI,
  34. Constants.SinaScope);
  35. mSsoHandler = new SsoHandler(this, mWeiboAuth);
  36. }
  37. protected void initWechat() {
  38. LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
  39. lbm.registerReceiver(mReciver, new IntentFilter(Constants.ACTION_WECHAT_LOGIN));
  40. }
  41. //QQ登录成功回调方法 返回access_token和openid
  42. @Override
  43. public void onComplete(Object o) {
  44. JSONObject object = (JSONObject) o;
  45. try {
  46. LogUtils.d(TAG, "onTencentComplete, object is " + object.toString());
  47. String token = object.optString("access_token");
  48. String openId = object.optString("openid");
  49. String expireTime = object.optString("expires_in");
  50. Oauth2AccessToken qqAccessToken = new Oauth2AccessToken(token, expireTime);
  51. if (qqAccessToken.isSessionValid()) {
  52. String date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new java.util.Date
  53. (qqAccessToken
  54. .getExpiresTime()));
  55. LogUtils.d(TAG, "QQ log in, expire date is " + date);
  56. }
  57. afterLogin(VALUE_QQ, openId, token);
  58. } catch (Exception e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. @Override
  63. public void onError(UiError uiError) {
  64. LogUtils.d(TAG,
  65. "onError, uiError is " + uiError.errorDetail + ", " + uiError.errorMessage);
  66. Toast.makeText(this,
  67. TextUtils.isEmpty(uiError.errorMessage) ? getString(R.string.qq_log_in_failed)
  68. : uiError.errorMessage, Toast.LENGTH_SHORT).show();
  69. }
  70. //新浪登录成功回调方法 返回accessToken对象
  71. @Override
  72. public void onComplete(Bundle bundle) {
  73. try {
  74. accessToken = Oauth2AccessToken.parseAccessToken(bundle);
  75. LogUtils.d(TAG,
  76. "onComplete, accessToken is " + accessToken.getUid() + ":" + accessToken
  77. .getToken() + ", expireTime is " + accessToken.getExpiresTime());
  78. if (accessToken.isSessionValid()) {
  79. String date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
  80. .format(new java.util.Date(accessToken.getExpiresTime()));
  81. LogUtils.d(TAG, "weibo log in, expire date is " + date);
  82. afterLogin(VALUE_SINA, accessToken.getUid(), accessToken.getToken());
  83. }
  84. } catch (Exception e) {
  85. e.printStackTrace();
  86. Toast.makeText(this, getString(R.string.log_in_failed), Toast.LENGTH_SHORT).show();
  87. }
  88. }
  89. @Override
  90. public void onWeiboException(WeiboException e) {
  91. LogUtils.d(TAG, "e.message is " + e.getLocalizedMessage());
  92. e.printStackTrace();
  93. Toast.makeText(this, String.format(getString(R.string.weibo_error), e.getMessage()),
  94. Toast.LENGTH_LONG).show();
  95. }
  96. @Override
  97. public void onCancel() {
  98. }
  99. @Override
  100. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  101. super.onActivityResult(requestCode, resultCode, data);
  102. if ((requestCode == REQUEST_CODE_BIND_OR_REGISTER
  103. || requestCode == REQUEST_CODE_COMPLETE_INFO) && resultCode == RESULT_OK) {
  104. setResult(RESULT_OK);
  105. finish();
  106. return;
  107. }
  108. // sso 授权回调
  109. try {
  110. if (mSsoHandler != null) {
  111. mSsoHandler.authorizeCallBack(requestCode, resultCode, data);
  112. }
  113. } catch (Exception e) {
  114. e.printStackTrace();
  115. }
  116. }
  117. //子类需要重写的方法 在上方三种登录授权成功都会回调这个方法 将type uid token发送给服务器验证
  118. protected void afterLogin(int type, String uid, String token) {
  119. }
  120. //保存用户信息方法LoginResponse就是一个Bean 内部包含User对象,字段为data, Settings为SharePerference工具类该方法存储user对象json
[java]  view plain copy
  1. //Global为全局变量 在运行时内存中存储当前用户对象
  2. protected void saveUserInfo(LogInResponse result) {
  3. Settings.saveUser(result.data);
  4. Global.currentUser = result.data;
  5. }
  6. }

然后就是子类的实现了 ,登录页的登录事件代码

[java]  view plain copy
  1. <span style="white-space:pre">    </span>case R.id.weibo_log_in_button:
  2. mSsoHandler.authorize(this);
  3. break;
  4. case R.id.qq_log_in_button:
  5. if (mTencent == null) {
  6. Utils.showToast(R.string.qq_not_installed);
  7. return;
  8. }
  9. mTencent.login(this, "get_user_info", this);
  10. break;
  11. case R.id.weixin_log_in_button:
[java]  view plain copy
  1. //这个mWxApi已经在MainActivity中初始化了 注意
  2. if (Global.mWxApi.isWXAppInstalled() && Global.mWxApi.isWXAppSupportAPI()) {
  3. final SendAuth.Req req = new SendAuth.Req();
  4. req.scope = "snsapi_userinfo";
  5. req.state = "none";
  6. Global.mWxApi.sendReq(req);
  7. } else {
  8. Utils.showToast(R.string.weixin_oauth_failed);
  9. }
  10. break;

也就是说 当我们点击之后 如果授权成功 最终会调用afterLogin方法,里面有三个参数 type uid token,当然 直接登录成功也可以调用这个方法 uid = username,token=password..

然后在这个方法里向我们自己的服务器发请求就可以 服务器返回成功地指示后我们再调用子类重写的saveUserInfo()

[java]  view plain copy
  1. @Override
  2. protected void saveUserInfo(LogInResponse result) {
[java]  view plain copy
  1. //父类存储用户信息 全局变量里有user
  2. super.saveUserInfo(result);
[java]  view plain copy
  1. //子类存储当前的UID信息 当应用退出后下次重进直接通过uid去getUser 这样就不用重复登录了
  2. Settings.setCurrentUid(result.data.uid);
  3. }

这样就基本实现第三方登录了

接下来是微信的WXEntryActivity 因为我们使用的是LocalBroadCastRecevier,因此我们在微信登录成功后需要发送广播给实现基类的登录页Activity

[java]  view plain copy
  1. public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. Global.mWxApi.handleIntent(getIntent(), this);
  6. }
  7. @Override
  8. protected void onNewIntent(Intent intent) {
  9. super.onNewIntent(intent);
  10. Global.mWxApi.handleIntent(intent, this);
  11. }
  12. @Override
  13. public void onReq(BaseReq baseReq) {
  14. }
  15. @Override
  16. public void onResp(BaseResp baseResp) {
  17. if (baseResp instanceof SendAuth.Resp) {
[java]  view plain copy
  1. //发送广播
  2. LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
  3. Intent intent = new Intent(Constants.ACTION_WECHAT_LOGIN);
  4. intent.putExtra("result", baseResp.errCode == BaseResp.ErrCode.ERR_OK);
  5. intent.putExtra("code", ((SendAuth.Resp) baseResp).code);
  6. lbm.sendBroadcast(intent);
  7. finish();
  8. }else {
  9. int result = 0;
  10. switch (baseResp.errCode) {
  11. case BaseResp.ErrCode.ERR_OK:
  12. result = R.string.errcode_success;
  13. break;
  14. case BaseResp.ErrCode.ERR_USER_CANCEL:
  15. result = R.string.errcode_cancel;
  16. break;
  17. case BaseResp.ErrCode.ERR_AUTH_DENIED:
  18. result = R.string.errcode_deny;
  19. break;
  20. default:
  21. result = R.string.errcode_unknown;
  22. break;
  23. }
  24. Toast.makeText(this, getString(result), Toast.LENGTH_LONG).show();
  25. finish();
  26. }
  27. }
  28. }

这样就基本完成登录和登录后避免再次登录了,接下来还有一些问题,

1.微信登录需要将apk打包签名 并通过微信的一个校验apk在里面输入包名 生成一个校验码粘贴到开发者平台才能够使用 而且费用300一年

2.微博也需要校验包名

3.每次重复签名很麻烦 又懒得换成测试版的签名 如果使用as或者idea的话 可以在build.gradle里输入

4.微信登录在开发者平台弄好之后不是马上就能用 有1个小时左右的延迟

[html]  view plain copy
  1. signingConfigs {
  2. myConfig {
  3. storeFile file("你的keystore文件,相对路径")
  4. storePassword 库密码
  5. keyAlias alias
  6. keyPassword 密码
  7. }
  8. }
  9. buildTypes {
[html]  view plain copy
  1. //release版本
  2. release {
[html]  view plain copy
  1. //是否混淆
  2. minifyEnabled true
[html]  view plain copy
  1. //混淆规则
  2. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
[html]  view plain copy
  1. //调用上面的签名方法
  2. signingConfig signingConfigs.myConfig
  3. }
[html]  view plain copy
  1. //debug版本
  2. debug {
[html]  view plain copy
  1. //调用上面的签名方法
  2. signingConfig signingConfigs.myConfig
  3. }
  4. }

Android第三方登录相关推荐

  1. Android第三方登录详解2

    接着Android第三方登录详解1讲 1.找到友盟  文档中心 2.找到 3.将 UMSocialService mController = UMServiceFactory.getUMSocialS ...

  2. Facebook android 第三方登录

    Facebook android 第三方登录 android平台使用Facebook账号登录自己的app - 前期准备 - 注册Facebook开发者账号,添加自己的应用,按照官方文档的指引完成需要的 ...

  3. android 第三方登录界面,Android App集成第三方登录与换肤指南

    Android App集成第三方登录与换肤指南 文档编辑 概述 本文主要是介绍了如何通过开源框架快速支持QQ和微信登录,并介绍了如何实现app快速换肤 QQ登录接入 APP要支持QQ登录,需要先到腾讯 ...

  4. Android 第三方登录 QQ提示需要最新版问题的解决办法

    问题: android 12 的手机上QQ是最新的.在使用app调用QQ的第三方登录时提示需要更新版本. 解决: targetSdkVersion版本30及以上的需要在AndroidManifest中 ...

  5. Android第三方登录——微博

    一.在官网注册开发账号:http://open.weibo.com 二.创建应用,授权回调必须写上,取消授权回调页可以不用填. 三.导入jar包和so文件(so文件跟jar要对应上,否则会出现问题:最 ...

  6. 试用友盟SDK实现Android第三方登录(以QQ登录为例)

    虽然自己在日常工作中用不到第三方登录,但是它的重要性无可厚非. 废话不多说,接下来跟着步骤走,轻松集成第三方登陆. 一,在友盟注册应用 注册好友盟账户后,在http://www.umeng.com/s ...

  7. android第三方登录appid,AndroidQQ第三方登录

    集成QQ登录 在lib导入该open_sdk_r5886_lite.jar包 AndroidManifest.xml android:name="com.tencent.tauth.Auth ...

  8. android 第三方登录和分享(5)

    使用share SDK实现第三方授权登录.分享综合(2.x版本) StartActivity: package com.home.testshare; import android.app.Activ ...

  9. android qq登录分析,Android第三方登录之QQ登录

    1. 在腾讯开放平台创建应用,申请Appkey qqdenglu.PNG 2. 下载sdk ,导入jar包 3.配置AndroidManifest android:name="com.ten ...

最新文章

  1. R读取excel文件乱码 read.xlsx() 解决方法
  2. React Native 环境搭建步骤
  3. 32位处理器的寄存器介绍
  4. android考勤系统,Android端实现考勤管理系统
  5. 某信道的波特率为1000Baud,若令其数据传输速率达到4kb/s,则一个信号码元所取的有效离散值个数为( )
  6. java 命令行读取_Java:从控制台(console,命令行)读取字符 | 学步园
  7. 1.struts1.x基本action的配置与使用
  8. python定时任务框架_Python定时任务框架APScheduler
  9. 数据结构之链式队列的优化
  10. [javax.validation]验证
  11. 两台电脑之间串口传输文件
  12. Android云手机平台搭建-2020圈钱热潮
  13. yxylxt的python容器
  14. Navicat for mysql的相关教程
  15. 移动群智感知应用学习
  16. 本人开始提供NOD32 相关升级及咨询服务
  17. undefined reference to `cv::imread(std::__cxx11::basic_string<char, std::char_traits<char>, std::all
  18. QT + FFmpeg 5.x + x264 + x265 + SDL2 音视频播放器
  19. ubuntu安装matlab,创建matlab快捷方式 ,解决快捷方式打不开
  20. 689页27万字智慧冷库农产品冷链物流大数据信息化系统集成方案

热门文章

  1. vuecli添加和移除插件_iZotope Neutron 3 Advanced——智能中子混音插件包
  2. Symfony2学习笔记之数据库操作
  3. 辨析BI、数据仓库、数据湖和数据中台内涵及差异点
  4. 2022 虎年除夕,苏生不惑送现金红包来了
  5. 团体程序设计天梯赛 L1-014 简单题
  6. 英文吵架必备100句
  7. UML2面向对象分析与设计(第2版) 谭火彬 杂记
  8. 企业IT战略规划方案参考
  9. 2023软件测试金三银四常见的软件测试面试题-【职业规划篇】
  10. 常用的8种字符串处理函数