facebook-android-sdk 实战指南:FBLoginSample 示例中的 Facebook 登录、权限管理与发帖实现
移动开发认证鉴权社交【免费下载链接】facebook-android-sdkUsed to integrate Android apps with Facebook Platform.项目地址https://gitcode.com/gh_mirrors/fa/facebook-android-sdk点击查看免费下载导读FBLoginSample 是 facebook-android-sdk 仓库中的一个官方示例应用samples/FBLoginSample它用一个完整的 Android App 演示了如何在应用中集成 Facebook Login从放置 Login with Facebook 登录按钮、发起 Graph API 请求获取登录用户信息到登录时授予权限、登录后追加权限、撤销权限以及向 Facebook 时间线发布帖子。读完本文你将掌握这套登录与权限流的完整调用链并能在自己的 Android 项目中复刻同样的实现。示例应用定位与工程结构该示例应用位于 samples/FBLoginSample其 READMEsamples/FBLoginSample/README.md明确了它演示如何与 Facebook Login 集成。整个 App 围绕一条登录链路组织为 5 个 Activity外加独立的请求封装层MainActivity应用入口负责登录状态检测、页面跳转与退出登录FacebookLoginActivity承载 LoginButton 的登录页ProfileActivity展示当前登录用户的资料PermissionsActivity权限开关页演示追加与撤销权限PostFeedActivity发帖页演示读取时间线帖子与发布帖子requests/callbacks/entities三个包分别封装 GraphRequest、响应回调和 JSON 到数据模型的转换。对应的 Kotlin 源码位于 samples/FBLoginSample/src/main/java/com/facebook/fbloginsample布局文件位于 samples/FBLoginSample/src/main/res/layout。README 覆盖的核心概念清单README 明确列出该示例覆盖的概念本文会逐一展开实现一个 Login with Facebook 按钮使用GraphRequest调用 Facebook Graph API获取当前登录用户的信息在登录时授予权限登录后追加权限撤销权限向 Facebook Timeline 发布基础帖子。运行前置条件与启动步骤README 给出的前置条件只有两条Android SDKAndroid Studio 或其他支持 Gradle 的构建系统。启动步骤同样简单下载或 clone 本仓库到本机用 Android Studio 打开并运行FBLoginSample模块首次构建时可能需要通过 Android SDK Manager 下载与工程匹配的 Gradle 版本和 Android Build Tools。从工程配置samples/FBLoginSample/build.gradle看该示例使用com.android.application与kotlin-android插件compileSdkVersion/targetSdkVersion为 31namespace为com.facebook.fbloginsample直接依赖仓库内的:facebook聚合模块并引入 Fresco用于图片加载FBLoginSampleApp中通过Fresco.initialize(this)初始化与 Material 组件库。配置 App ID 与 Client Token运行前的必经步骤示例把 Facebook 应用凭证放在字符串资源中samples/FBLoginSample/src/main/res/values/strings.xmlstring nameapp_nameFB Login Sample/string string namefacebook_app_idENTER_YOUR_FB_APP_ID_HERE/string !-- The client token is available in Settings Advanced Security section of the app dashboard. -- string namefacebook_client_tokenENTER_YOUR_FB_CLIENT_TOKEN_HERE/string string namefb_login_protocol_schemefb{ENTER_YOUR_FB_APP_ID_HERE}/string !-- keep the fb prefix and remove braces--三个占位符必须替换为真实值facebook_app_id、facebook_client_token可在 App 控制台的 Settings Advanced Security 中找到以及fb_login_protocol_scheme保留fb前缀并去掉花括号如fb1234567890。这些字符串随后在 samples/FBLoginSample/src/main/AndroidManifest.xml 中通过 meta-data 注入 SDKmeta-data android:namecom.facebook.sdk.ApplicationId android:valuestring/facebook_app_id / meta-data android:namecom.facebook.sdk.ClientToken android:valuestring/facebook_client_token /值得注意的是MainActivity在启动时会校验这两个配置是否仍是默认占位符MainActivity.kt若未替换会弹出AlertDialog提示用户先填入 App ID 与 Client Token 再重启应用。其中关于 Client Token 的提示特别说明在 Facebook SDK v13.0 及以上版本所有 Graph API 调用都必须带有有效的 client token——这正是示例在 Manifest 中单独声明com.facebook.sdk.ClientToken的原因。实现 Login with Facebook 按钮与登录回调登录页 FacebookLoginActivity.kt 是整个登录链路的核心逻辑非常精简val loginButton: LoginButton findViewById(R.id.login_button) // Set the initial permissions to request from the user while logging in loginButton.permissions listOf(EMAIL, USER_POSTS) // email, user_posts loginButton.authType AUTH_TYPE // rerequest loginButton.registerCallback( callbackManager, object : FacebookCallbackLoginResult { override fun onSuccess(result: LoginResult) { setResult(RESULT_OK) finish() } override fun onCancel() { setResult(RESULT_CANCELED) finish() } override fun onError(error: FacebookException) { // Handle exception } })要点拆解布局文件 activity_facebook_login.xml 中直接声明了 SDK 自带的com.facebook.login.widget.LoginButton控件这是Login with Facebook按钮的标准用法无需自定义 ViewloginButton.permissions指定登录时一次性请求的权限示例请求email与user_posts两个读权限loginButton.authType rerequest表示当用户此前拒绝过权限时再次以重新请求模式弹出授权registerCallback把CallbackManager与FacebookCallbackLoginResult绑定登录成功返回LoginResult内部携带AccessToken。CallbackManager 的角色示例在 Activity 内创建CallbackManagerCallbackManager.Factory.create()并在onActivityResult中转发结果override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { super.onActivityResult(requestCode, resultCode, data) callbackManager.onActivityResult(requestCode, resultCode, data) }这是 Facebook 登录回调机制的固定套路登录流程可能跳转到 Facebook App 或 WebView返回结果后必须交给CallbackManager.onActivityResult分发给FacebookCallback。PermissionsActivity与PostFeedActivity也采用同样的注册方式LoginManager.getInstance().registerCallback(callbackManager, this)。登录状态恢复retrieveLoginStatusMainActivity启动时调用LoginManager的retrieveLoginStatus来恢复会话MainActivity.ktgetInstance().retrieveLoginStatus( this, object : LoginStatusCallback { override fun onCompleted(accessToken: AccessToken) { // 用户已登录弹出 Snackbar 提示 } override fun onFailure() { // 若本地无 token则跳转登录页 if (getCurrentAccessToken() null) { val loginIntent Intent(thisMainActivity, FacebookLoginActivity::class.java) startActivity(loginIntent) } } override fun onError(exception: Exception) { // Handle exception } })该方法会尝试与 Facebook 官方 App 通信以获取用户登录状态若设备上 Facebook App 中已登录同款应用的用户可直接复用其会话并返回 AccessToken无需再走完整登录流程。其底层实现在 facebook-common/src/main/java/com/facebook/login/LoginManager.kt内部通过LoginStatusClient发起请求并支持自定义 toast 展示时长。退出登录logOutMainActivity 的 Logout 按钮直接调用LoginManager.getInstance().logOut()然后回到登录页。SDK 层面的logOut()实现LoginManager.kt会依次清空当前 AccessToken、AuthenticationToken、当前 Profile 并重置 Express Login 状态从而完成本地会话清理。使用 GraphRequest 获取登录用户信息登录之后示例通过GraphRequest发起 Graph API 调用。请求封装在 requests/UserRequest.ktobject UserRequest { private const val ME_ENDPOINT /me fun makeUserRequest(callback: GraphRequest.Callback?) { val params Bundle() params.putString(fields, picture,name,id,email,permissions) val request GraphRequest(getCurrentAccessToken(), ME_ENDPOINT, params, GET, callback) request.executeAsync() } }要点请求目标是 Graph API 的/me端点携带当前AccessToken通过fields参数精确控制返回字段picture、name、id、email、permissions避免拉取无关数据executeAsync()异步执行结果通过GraphRequest.Callback回调。响应解析在 callbacks/GetUserCallback.kt先取 JSON 根对象再解析picture.data.url作为头像、name、id、可选的email并遍历permissions.data数组拼出权限名: 状态的展示文本最终构造 entities/User.kt 数据对象交给ProfileActivity渲染头像用 Fresco 的SimpleDraweeView显示邮箱缺失时显示Email permission not granted红色提示。登录时授予权限与登录后追加权限登录时授权登录时请求的权限通过两条途径设置效果等价LoginButton.permissions listOf(email, user_posts)示例登录页的做法LoginManager.logInWithReadPermissions(activity, listOf(...))。两者最终都汇聚到LoginManager的登录实现。从源码看logInWithReadPermissions(Activity, permissions)LoginManager.kt会先调用validateReadPermissions(permissions)校验请求的是否为合法读权限再封装为LoginConfiguration发起登录。登录后追加权限PermissionsActivity用一组 Switch 演示了登录后按需追加权限PermissionsActivity.kt// 请求追加 email 读权限 if (isChecked permissions?.contains(EMAIL) false) { LoginManager.getInstance().logInWithReadPermissions(thisPermissionsActivity, listOf(EMAIL)) } // 请求追加发布权限 if (isChecked permissions?.contains(PUBLISH_ACTIONS) false) { LoginManager.getInstance() .logInWithPublishPermissions(thisPermissionsActivity, listOf(PUBLISH_ACTIONS)) }布局文件 activity_permissions.xml 把权限分成两组展示无需 FB 审核的读权限email、整个应用登录public_profile与需要 FB 审核的权限user_posts、publish_actions。这里需要特别说明publish_actions的底层行为logInWithPublishPermissionsLoginManager.kt内部同样先做validatePublishPermissions校验再构建LoginConfiguration发起登录流程。每次权限状态变化后示例会调用AccessToken.refreshCurrentAccessTokenAsync(this)刷新本地缓存的 token并在AccessTokenRefreshCallback.OnTokenRefreshed中重新渲染 Switch 状态若刷新失败token 失效则自动logOut()并跳回登录页。撤销权限PermissionsActivity中关闭某个 Switch 时会调用 requests/PermissionRequest.kt 的makeRevokePermRequest撤销对应权限object PermissionRequest { private const val PERMISSIONS_ENDPOINT /me/permissions private const val APP app JvmStatic fun makeRevokePermRequest(permission: String, callback: GraphRequest.Callback?) { val graphPath if (permission APP) { PERMISSIONS_ENDPOINT } else { $PERMISSIONS_ENDPOINT/$permission } val request newGraphPathRequest(getCurrentAccessToken(), graphPath, callback) request.httpMethod HttpMethod.DELETE request.executeAsync() } }实现原理撤销单个权限向/me/permissions/{permission}发送DELETE请求例如撤销email即请求/me/permissions/email撤销整个应用的全部授权向/me/permissions发送DELETE请求即permission app分支。回调通过 callbacks/PermissionCallback.kt 透传GraphResponse若response.error非空则用 Toast 展示错误信息随后同样刷新 AccessToken 以同步最新权限。读取与发布帖子Basic Posting to Facebook TimelinePostFeedActivity与PostsRequest共同演示了 Facebook Timeline 的读与写。读取时间线requests/PostsRequest.kt 中的makeGetPostsRequest向/me/feed发起GET请求fun makeGetPostsRequest(callback: GraphRequest.Callback) { val params Bundle() params.putString(fields, message,created_time,id,picture,story,from) val request GraphRequest(AccessToken.getCurrentAccessToken(), FEED_ENDPOINT, params, GET, callback) request.executeAsync() }callbacks/GetPostsCallback.kt 解析data数组逐条提取message、created_time、id、picture、story、from.name、from.id构造 entities/Post.kt 列表交给PostAdapter渲染到ListView布局见 activity_post_feed.xml。发布纯文本帖子makePublishPostRequest(message, callback)向/me/feed发送POST请求params中携带message字段。发布按钮的点击逻辑在 PostFeedActivity.kt先检查当前 token 是否已包含publish_actions权限若没有则先调用logInWithPublishPermissions引导用户授权成功后再真正发帖——这是先检查权限、再执行发布的典型时序。发布带图片的帖子makePublishPostRequest(attachmentUri, callback)演示了通过ShareApi发布图片内容val photo SharePhoto.Builder().setImageUrl(attachmentUri).build() val content SharePhotoContent.Builder().addPhoto(photo).build() ShareApi.share(content, callback)这里使用ShareApi而非 GraphRequest的原因是图片等媒体内容需要先上传到 FacebookShareApi.share会封装这一过程并通过FacebookCallbackSharer.Result回传发布结果成功/取消/错误。图片的来源由PostFeedActivity通过系统ACTION_GET_CONTENT图片选择器获取选中后在onActivityResult中记录UrimakePost()根据是否有附件决定走文本发布还是图片发布分支。底层调用链小结把整个示例串起来可以看到一条清晰的 SDK 调用链底层实现在 facebook-common/src/main/java/com/facebook/login/LoginManager.kt初始化配置AndroidManifest.xml的 meta-data 提供ApplicationId与ClientTokenSDK 启动时读取发起登录LoginButton.registerCallback或LoginManager.logInWithReadPermissions / logInWithPublishPermissionsSDK 内部校验权限集合validateReadPermissions/validatePublishPermissions后构建LoginConfiguration走登录流程结果回传CallbackManager.onActivityResult分发给FacebookCallbackLoginResult会话管理AccessToken.getCurrentAccessToken()读取当前 tokenAccessToken.refreshCurrentAccessTokenAsync刷新LoginManager.logOut()清空会话retrieveLoginStatus恢复会话数据读写GraphRequest面向/me、/me/feed、/me/permissions端点执行 GET/POST/DELETEShareApi处理图片上传。这套模式同样适用于接入其他模块例如facebook-share、facebook-gamingservices等均依赖AccessToken与LoginManager建立的会话因此掌握 FBLoginSample 的登录链路是深入使用 facebook-android-sdk 各模块的起点。参与贡献与许可说明README 同时说明示例应用接受社区贡献提交前请遵循 samples/FBLoginSample/CONTRIBUTING.md 的指引并提交到dev分支便于官方合并进入下一次发布。除特别注明外FBLoginSample 使用 samples/FBLoginSample/LICENSE 中的 Facebook Platform License 授权除非法律要求或书面同意软件按 AS IS 基础分发不附带任何明示或暗示的保证。关于 Facebook Login 的更多官方说明、Bug 反馈与开发者社区讨论方式可参考仓库根目录的 README.md 与 CONTRIBUTING.md 获取项目级指引。赞分享移动开发认证鉴权社交【免费下载链接】facebook-android-sdkUsed to integrate Android apps with Facebook Platform.项目地址https://gitcode.com/gh_mirrors/fa/facebook-android-sdk点击查看免费下载相关推荐打造WPF任务管理器HandyControl数据网格应用打造WPF任务管理器HandyControl数据网格应用 你是否还在为WPF原生 DataGrid 控件功能单一、样式陈旧而烦恼是否需要一个既能高效展示系统移动开发认证鉴权社交如何使用 hello.js 实现 Facebook 登录完整代码示例如何使用 hello.js 实现 Facebook 登录完整代码示例 想要为你的网站快速添加 Facebook 社交登录功能吗hello.js 是一个强大的认证鉴权前端Symfony Notifier Facebook Page Bridge 实战指南通过 Graph API 向 Facebook 主页发帖Symfony Notifier Facebook Page Bridge 实战指南通过 Graph API 向 Facebook 主页发帖 导读 本文基于后端Web框架上一篇Coding WebIDE 项目推荐下一篇ReportPortal 项目推荐创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

无线传播路径建模从入门到实战:自由空间损耗与链路预算全解析

无线传播路径建模从入门到实战:自由空间损耗与链路预算全解析

做无线覆盖、物联网部署和系统集成的朋友,大概都经历过这样一个场景:现场信号测了几十轮,数据总比仿真预测低一截,设备商说天线没问题,集成商说现场环境太复杂,最后谁也没给出一个能复用的结论。要走出这种…

2026/10/15 20:15:48 阅读更多 →
大麦网抢票脚本 3 步跑通:Selenium + Requests 混合架构实践

大麦网抢票脚本 3 步跑通:Selenium + Requests 混合架构实践

大麦网抢票脚本 3 步跑通:Selenium Requests 混合架构实践 【免费下载链接】Automatic_ticket_purchase 大麦网抢票脚本 项目地址: https://gitcode.com/GitHub_Trending/au/Automatic_ticket_purchase 倒计时归零,页面弹出一行"库存不足&q…

2026/10/15 20:15:48 阅读更多 →
Module Federation + TypeScript Monorepo 实战:类型流式共享与 Jest 单元测试(typescript-react-monorepo-test 深度解析)

Module Federation + TypeScript Monorepo 实战:类型流式共享与 Jest 单元测试(typescript-react-monorepo-test 深度解析)

示例工程 【免费下载链接】module-federation-examples Implementation examples of module federation , by the creators of module federation 项目地址: https://gitcode.com/gh_mirrors/mo/module-federation-examples 点击查看 免费下载 本文以 module-feder…

2026/10/15 20:15:48 阅读更多 →

最新新闻

Agent落地三要素:记忆、目标与执行力的工程闭环

Agent落地三要素:记忆、目标与执行力的工程闭环

连着做了几个Agent项目之后,我越来越确定一件事:决定Agent上限的是模型本身,但决定它下限的,是记忆、目标与执行力这三块骨架。之前在做一个内部知识库问答项目时,最开始的版本就是把大模型接上对话接口,结…

2026/10/16 2:50:57 阅读更多 →
AlphaFin的Stock-Chain如何实现30.8%年化收益?多空回测与FinGPT对比深度拆解

AlphaFin的Stock-Chain如何实现30.8%年化收益?多空回测与FinGPT对比深度拆解

【免费下载链接】AlphaFin 项目地址: https://gitcode.com/gh_mirrors/alp/AlphaFin 点击查看 免费下载 AlphaFin 是一个面向金融分析的开源基准项目,其核心 Stock-Chain 框架通过检索增强(RAG) 微调大模型的方式完成股票趋势预测…

2026/10/16 2:50:57 阅读更多 →
3 步装回 Win10 经典任务栏:ExplorerPatcher 免费上手笔记

3 步装回 Win10 经典任务栏:ExplorerPatcher 免费上手笔记

3 步装回 Win10 经典任务栏:ExplorerPatcher 免费上手笔记 【免费下载链接】ExplorerPatcher This project aims to enhance the working environment on Windows 项目地址: https://gitcode.com/GitHub_Trending/ex/ExplorerPatcher Windows 11 升级后&…

2026/10/16 2:50:57 阅读更多 →
AI笔记工具实战:创始人如何用语音速记和自动整理打造高效工作流

AI笔记工具实战:创始人如何用语音速记和自动整理打造高效工作流

我见过太多创始人的手机备忘录:一百多段语音躺在输入框里,四十几张聊天截图堆在相册,还有一堆只有自己看得懂的缩写关键词。问他们上周和客户聊了什么,回答通常是——"我记了,但找不到了。"这句话才是创始人…

2026/10/16 2:50:57 阅读更多 →
ET6238驱动详解:I2C接口LED显示与按键扫描的C源码实现

ET6238驱动详解:I2C接口LED显示与按键扫描的C源码实现

简介:ET6238驱动是一份基于I2C总线协议的LED显示控制源码,采用C语言编写,目标芯片为ET6238,适用于驱动十六行八列的LED矩阵。资源面向嵌入式开发者、单片机学习者及需要实现信息显示功能的相关从业者,可帮助快速构建数…

2026/10/16 2:50:57 阅读更多 →
建筑改造项目的表计难题:拆不了换不动,水电气数据怎么远程拿?

建筑改造项目的表计难题:拆不了换不动,水电气数据怎么远程拿?

建筑改造项目做到水电配套这一步,表计怎么处理,常常是第一个卡住的地方。新建工程的表计配套相对简单。但改造项目和存量建筑不一样,每栋楼的情况都不同。有的管网锈了二十年不敢碰,有的管井窄到人侧身才能进去,有的本…

2026/10/16 2:49:57 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →