Facebook 的 Android 登录链接,其中包含了很多账号注册信息。这里贴出一些 facebook 登录中重点的代码,申请的 App 相关信息这里就不多介绍,Facebook 此网页支持中文。

项目的 build.gradle 中

repositories {mavenCentral()
}

模块下的 build.gradle 中

    implementation 'com.facebook.android:facebook-android-sdk:[4,5)'

按照官网的指示,strings.xml 中填写申请的两个 key

    <string name="facebook_app_id" translatable="false">填写自己申请的facebook_app_id</string><string name="fb_login_protocol_scheme" translatable="false">填写自己申请的fb_login_protocol_scheme</string>

这两个值在 AndroidManifest.xml 中使用,当然需要 INTERNET 权限

    <uses-permission android:name="android.permission.INTERNET" /><application...><meta-dataandroid:name="com.facebook.sdk.ApplicationId"android:value="@string/facebook_app_id" /><activityandroid:name=".ui.login.UserActivity"android:windowSoftInputMode="stateVisible|adjustResize"><intent-filter><data android:scheme="@string/fb_login_protocol_scheme" /></intent-filter></activity></application>

我所定义的登录 Activity 为 UserActivity

文档中提示

Mac

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

Windows

keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64

生成发布密钥散列

keytool -exportcert -alias YOUR_RELEASE_KEY_ALIAS -keystore YOUR_RELEASE_KEY_PATH | openssl sha1 -binary | openssl base64

openssl 可以去网上下载,这里暂不提供了。为方便使用这里提供一个 Java 工具方法直接获取 SIGNATURES ,之后将此 SIGNATURES 填写上去就可以了

    public static void getSignatures(Context context) {try {PackageInfo info = context.getPackageManager().getPackageInfo("您的包名", PackageManager.GET_SIGNATURES);for (Signature signature : info.signatures) {MessageDigest md = MessageDigest.getInstance("SHA");md.update(signature.toByteArray());Log.e(TAG, Base64.encodeToString(md.digest(), Base64.DEFAULT));}} catch (PackageManager.NameNotFoundException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}}

代码正式开始,Kotlin 编写

初始化,两者二选一,sdkInitialize 被标记过时

        FacebookSdk.sdkInitialize(this.getApplicationContext());AppEventsLogger.activateApp(this);

Facebook 自带了登录按钮,您可以查看源码去定义这些按钮,我这里是用的自己的图标。按钮为如下

        <com.facebook.login.widget.LoginButtonandroid:id="@+id/login_facebook"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginEnd="80dp"android:layout_marginBottom="40dp"app:layout_constraintBottom_toTopOf="@id/tvLogin"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent" />//我所用的为下面这个自定义 ImageView<ImageViewandroid:id="@+id/login_twitter"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="80dp"android:layout_marginBottom="40dp"android:src="@mipmap/ic_twitter"app:layout_constraintBottom_toTopOf="@id/tvLogin"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent" />

先定义回调接口 CallbackManager,在 onActivityResult 中注册

private val callbackManager = CallbackManager.Factory.create()override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)callbackManager.onActivityResult(requestCode, resultCode, data)}

正式的数据回调接口

        LoginManager.getInstance().registerCallback(callbackManager, object :FacebookCallback<LoginResult?> {override fun onSuccess(loginResult: LoginResult?) {Log.e("FACEBOOK", "onSuccess")}override fun onCancel() {Log.e("FACEBOOK", "onCancel")}/*SERVER_ERROR: [code] 1349195 [message]: 该密钥散列不匹配任何已存储的密钥散列。请前往 https://developers.facebook.com/docs/facebook-login/android 了解更多信息。 [extra]:*/override fun onError(exception: FacebookException) {Log.e("FACEBOOK", "onError " + exception.toString())}})

点击事件,也就是请求 Facebook app时,传入参数 public_profile 、email,其他的一些可参考官方文档,有些是需要用户给予权限

        login_facebook.setOnClickListener {LoginManager.getInstance().logInWithReadPermissions(this, listOf("public_profile", "email"))}

点击后如果成功,会在 onSuccess 的回调中获取 loginResult 。其中包含了 accessToken 可用作获取 Facebook 其他的一些信息使用,accessToken 中也包含一个重要属性 applicationId ,看你的业务逻辑如何使用了。

由返回的 accessToken 可以发起 GraphRequest 请求了

                    val newMeRequest =GraphRequest.newMeRequest(accessToken) { obj, _ ->XLog.e(obj)}val parameters = Bundle()parameters.putString("fields","id,age_range,birthday,email,first_name,last_name,gender,link,location,middle_name,name,apprequests,friends,permissions,picture")newMeRequest.setParameters(parameters)newMeRequest.executeAsync()

这里说明下请求的参数中 fields 中的几个主要的属性

id:应用程序用户的应用程序范围内的用户id。此id对于应用程序是唯一的,不能被其他应用程序使用。

age_range:此人的年龄段以最小和最大年龄表示。比如18岁以上,21岁以下。

birthday:固定格式的字符串,如 MM/DD/YYYY。但是,账户可以控制谁可以看到自己出生的年份,而不是月份和日期,因此这个字符串只能是年(YYYY)或月+日(MM/DD)。

email:向用户的个人资料中列出的主要电子邮件地址发送电子邮件。如果没有有效的电子邮件地址,则不会返回此字段。

first_name、last_name 不多解释,middle_name :此人的中间名,name 即全名。

gender:男性或女性。如果性别设置为自定义值,则此值将基于首选代词;如果首选代词为中性,则忽略此值

link:将链接链接到此人的时间轴。只有当点击链接的人登录到Facebook并且是其个人资料被查看者的朋友时,该链接才会被解析。

location:该人员在其个人资料中输入的当前位置。此字段需要用户“位置”权限。

friends:朋友。

permissions:用户授予此应用程序的权限。

picture:描绘此人的个人资料图片。

返回格式为 JSONObject ,可以解析此 json 得到以上的信息(由于一些信息可能用户未设置,所以获取不到,多注意判断)

此时第三方登录的标准流程已经实现,下来关注两个回调,更全面的了解 Facebook sdk

    private val accessTokenTracker = object : AccessTokenTracker() {override fun onCurrentAccessTokenChanged(oldAccessToken: AccessToken?,currentAccessToken: AccessToken?) {XLog.e("oldAccessToken $oldAccessToken  currentAccessToken $currentAccessToken")if (currentAccessToken == null) {LoginManager.getInstance().logOut()}}}private val profileTracker = object : ProfileTracker() {override fun onCurrentProfileChanged(oldProfile: Profile?,currentProfile: Profile?) {XLog.e("oldProfile $oldProfile  currentProfile $currentProfile")}}

定义 AccessTokenTracker、ProfileTracker,官方用蹩脚的中文解释说 " 如果您希望应用持续追踪当前访问口令和个人资料,您可以部署 AccessTokenTracker 和 ProfileTracker 类。 这些类将在访问口令或个人资料发生更改时调用您的代码。 在内部,它们使用接收器,因此您需要调用活动上的 stopTracking() 或调用代码片段的 onDestroy() 方法。 "

其实 AccessTokenTracker 就是请求访问令牌,如权限 "public_profile", "email" 等更改是回调,ProfileTracker 为配置文件更改时的通知。

使用方法也很简单

        //开启accessTokenTracker.startTracking()profileTracker.startTracking()//关闭accessTokenTracker.stopTracking()profileTracker.stopTracking()

facebook 提供了退出登录方法,再上面已看到 AccessTokenTracker 定义中已看到

                LoginManager.getInstance().logOut()

同时,它还可以查看是否已经登录

        val accessToken = AccessToken.getCurrentAccessToken()val isLoggedIn = accessToken != null && !accessToken.isExpired

目前所了解的就这些,最后附上代码

import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.fragment.app.Fragment
import com.elvishew.xlog.XLog
import com.facebook.*
import com.facebook.login.LoginManager
import com.facebook.login.LoginResult
import com.facebook.login.widget.LoginButton
import org.json.JSONObject/*** <pre>* @user : milanxiaotiejiang* @email : 765151629@qq.com* @version : 1.0* @date : 2020/8/1* @description : facebook工具类* </pre>*//**
email - 允许访问用户的首选邮箱信息。
user_likes - 允许访问用户点赞的内容列表。
user_photos - 允许您的应用获取用户已发布的照片。
appsecret_proof 参数签名,以降低被恶意软件和垃圾邮件发送者攻击的可能性。"email", "user_likes", "user_status", "user_photos", "user_birthday", "public_profile", "user_friends"*/
fun View.onFacebookLogin(fragment: Fragment) {setOnClickListener {LoginManager.getInstance().logInWithReadPermissions(fragment, listOf("public_profile", "email", "user_gender"))}
}fun LoginButton.onFacebookLogin(callbackManager: CallbackManager) {registerCallback(callbackManager, object : FacebookCallback<LoginResult?> {override fun onSuccess(loginResult: LoginResult?) {XLog.e("FACEBOOK onSuccess" + loginResult.toString())}override fun onCancel() {XLog.e("FACEBOOK onCancel")}override fun onError(exception: FacebookException) {XLog.e("FACEBOOK onError" + exception.toString())}})
}/**
如果您希望应用持续追踪当前访问口令和个人资料,您可以部署 AccessTokenTracker 和 ProfileTracker 类。
这些类将在访问口令或个人资料发生更改时调用您的代码。 在内部,它们使用接收器,因此您需要调用活动上的 stopTracking() 或调用代码片段的 onDestroy() 方法。*/
private val accessTokenTracker = object : AccessTokenTracker() {override fun onCurrentAccessTokenChanged(oldAccessToken: AccessToken?,currentAccessToken: AccessToken?) {XLog.e("oldAccessToken $oldAccessToken  currentAccessToken $currentAccessToken")if (currentAccessToken == null) {LoginManager.getInstance().logOut()}}
}private val profileTracker = object : ProfileTracker() {override fun onCurrentProfileChanged(oldProfile: Profile?, currentProfile: Profile?) {XLog.e("oldProfile $oldProfile  currentProfile $currentProfile")}
}fun facebookStartTracking() {if (AccessToken.getCurrentAccessToken() != null && !AccessToken.getCurrentAccessToken().isExpired) {accessTokenTracker.startTracking()profileTracker.startTracking()}
}fun facebookStopTracking() {accessTokenTracker.stopTracking()profileTracker.stopTracking()
}/**
id          The app user's App-Scoped User ID. This ID is unique to the app and cannot be used by other apps.
age_range   The age segment for this person expressed as a minimum and maximum age. For example, more than 18, less than 21.
birthday    The person's birthday. This is a fixed format string, like MM/DD/YYYY. However, people can control who can see the year they were born separately from the month and day so this string can be only the year (YYYY) or the month + day (MM/DD)
email       The User's primary email address listed on their profile. This field will not be returned if no valid email address is available.
first_name  The person's first name
gender      The gender selected by this person, male or female. If the gender is set to a custom value, this value will be based off of the preferred pronoun; it will be omitted if the preferred pronoun is neutral
last_name   The person's last name
link        A link to the person's Timeline. The link will only resolve if the person clicking the link is logged into Facebook and is a friend of the person whose profile is being viewed.
location    The person's current location as entered by them on their profile. This field requires the user_location permission.
middle_name The person's middle name
name        The person's full name
apprequests This person's pending requests from an appfriends     The person's friends
permissions The permissions that the person has granted this app
picture     The person's profile picture*/
fun facebookCallback(callbackManager: CallbackManager,block: (jSONObject: JSONObject) -> Unit
) {LoginManager.getInstance().registerCallback(callbackManager, object :FacebookCallback<LoginResult?> {override fun onSuccess(loginResult: LoginResult?) {if (loginResult != null) {loginResult.apply {//无效日志
//                    accessToken.apply {
//                        applicationId// 287891882425066
//                        dataAccessExpirationTime //Sun Oct 18 12:44:34 GMT+08:00 2020
//                        declinedPermissions /// {  }
//                        expires// Tue Sep 29 10:18:45 GMT+08:00 2020
//                        lastRefresh// Fri Jul 31 10:19:00 GMT+08:00 2020
//                        source.apply {
//                            name // FACEBOOK_APPLICATION_SERVICE
//                            ordinal // 3
//                        }
//                        token //EAAEF1g1iuuoBAPIWlNLeCMwKBZBIBC3Q8XZAGYI5FWg5YEmyNoU6yoP9ZCNrGj2BVqCjBGyhfdZAVy28iLHuZAzmDwldI5GgZAEwf5uvZAxCWSpTDAV1nsxvwroKjc8IQfcl7P5LzXwb1qdj1UU7AfH5A5pOlqKg6K4MQpWuqZC9NdbZBmHhTMYdzeHMcOkNUBD1sBuHbkcSJ4gARMzkZC77KdfJroNbZAF2jZBpCeFG515GrwZDZD
//                        userId //122057319574816
//                    }
//                    recentlyGrantedPermissions // { public_profile }
//                    recentlyDeniedPermissions // {   }val newMeRequest = GraphRequest.newMeRequest(accessToken) { obj, _ ->block(obj)}val parameters = Bundle()parameters.putString("fields","id,email,gender,name,picture")newMeRequest.parameters = parametersnewMeRequest.executeAsync()}} else {XLog.e("loginResult is null")}}override fun onCancel() {Log.e("FACEBOOK onCancel", "")}/*SERVER_ERROR: [code] 1349195 [message]: 该密钥散列不匹配任何已存储的密钥散列。请前往 https://developers.facebook.com/docs/facebook-login/android 了解更多信息。 [extra]:*/override fun onError(exception: FacebookException) {Log.e("FACEBOOK onError", exception.toString())}})
}

最新发现 AppEventsLogger.activateApp(this); 初始化 facebook 与极光推送冲突,可使用 FacebookSdk.sdkInitialize(this); 初始化即可。

Android 实现 Facebook 第三方登录相关推荐

  1. Android集成Facebook第三方登录,全流程

    首次接触海外项目,开发环节与测试流程刚开始搞得一头雾水,历时两周终于把登录和支付调通了,特此记录下: 不过总结下来,与国内流程不同的点,主要是测试流程,需要专门的测试账号与测试权限才能测通 首先打开开 ...

  2. 详细前后端分离实现facebook第三方登录的全过程(国内一般都是用Android和ios,并且资料稀少)

    实现facebook第三方登录全过程 需求 官方文档与校验工具 详细步骤 1.注册一个facebook的账号 2.登录https://developers.facebook.com/ 3.点击我的应用 ...

  3. Java实现Facebook第三方登录

    第一次接触Facebook第三方登录,可能有些地方做的并不全面,只是尝试着做了一个小demo,因为国内接入Facebook的项目并不多,并且多数都是Android或IOS的实现,所以资料也特别少,在此 ...

  4. Facebook第三方登录流程总结

    Facebook第三方登录流程总结 授权Facebook第三方登录流程 开发步骤 Facebook应用配置 前端授权 后端校验 授权Facebook第三方登录流程 有时候为了迅速获客,会在注册登录页支 ...

  5. 友盟社会化Android组件之第三方登录

    前段时间公司需要,逐步了新浪微博.腾讯qq.微信等授权登录验证的问题.如果要一个个申请,看文档写代码也是很多流程的.干脆用友盟社会化Android组件之第三方登录.友盟是集成了这些平台,还有其他主流的 ...

  6. 用 Flask 来写个轻博客 (23) — 应用 OAuth 来实现 Facebook 第三方登录

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 第三方登录流程 OAuth 应用 OAuth 实现 Face ...

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

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

  8. facebook第三方登录前后端分离

    facebook第三方登录三种实现方式:第三种我认为方便简单 1.js sdk 直接在官网看文档 直接调用他的sdk 官网:https://developers.facebook.com/docs/f ...

  9. Facebook第三方登录对接

    一.背景调研 1.什么是第三方登录? 第三方登录是基于用户在第三方平台上已有的账号和密码来快速完成己方应用的登录或者注册的功能.而这里的第三方平台,一般是已经拥有大量用户的平台,国外的比如Facebo ...

最新文章

  1. Java 二次MD5 32位小写加密算法与php页面加密结果相同
  2. Java和Android中一些常用的公共方法
  3. 几款优秀的jQuery 插件
  4. Windows server 2008系统各类版本的优缺点比较,Windows2008系统标准版 企业版 数据中心版 WEB版等...
  5. 使用Firefox或Chrome的雇员表现更好不频繁跳槽
  6. Javascript异步操作的异常处理
  7. activemq消息丢失_基于Redis实现消息队列的典型方案
  8. mysql 面试知识点笔记(三)联合索引的最左匹配原则
  9. 信息化为五万教学点带来“优质教师”
  10. C++ BMP转JPG方法三
  11. 在CentOS7虚拟机中安装mysql5.7
  12. Android ImageView视图的七种图片缩放类型
  13. 西南交大计算机绘图b,网络大学西南交大离线作业计算机绘图B
  14. C++ 模板函数的使用
  15. Android 查询设备信息c/c++常用方法
  16. (转)走进全球CTA领导者:元盛资本(Winton CapitalManagement)
  17. 计算机专业如何发sci期刊
  18. UOJ147 斗地主
  19. SAP中利润中心清单输出请求处理实例
  20. PC安装黑苹果 (macOS Sierra 10.12.6)上篇

热门文章

  1. 安卓应用提供64位原生的支持
  2. 【 chrom 】搜索引擎设置为百度浏览器
  3. 迎战算力黄金时代,惠普Z系列工作站焕新升级
  4. excle转xml文件
  5. linux 获取phy状态,Linux PHY几个状态的跟踪
  6. selinux的关闭
  7. C语言提高篇——程序环境和预处理
  8. 厦门哪里有培训python
  9. MRO工业品怎么做好供应链?
  10. 3 个开源日志聚合工具