❤️Android 集成 Facebook 登录❤️

5,304 阅读5分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

美国时间10月28日的 Connect 2021 直播活动中,Facebook 创始人马克·扎克伯格正式宣布,公司将更名为“Meta”,不管怎么改咱先接入功能。

🔥 创建应用

如果已创建请忽略这一步。

💥 选择受众

💥 选择类型

💥 详情(后面都可以修改)

💥 创建成功(开发中)

用户数据删除:访问用户数据的应用必须为用户提供请求删除数据的方式。你必须提供数据删除请求回调或说明,告知用户如何从你的应用或网站删除自己的数据。如不提供将有应用功能被下架的风险。

💥 添加平台

选中,next。

除了这些其他官方都不认可,上线一段时间后你会受到邮件警告等。

当然其他平台应用(如官网)的包,你可以填写上面12个应用市场的包名。但是生成密钥散列的时候要用对应的包名。Facebook目前认密钥散列,不认包名

这里咱没有密钥散列先填包名,受到警告先放着。

💥 添加登录功能

然后他会一步一步教你集成Facebook SDK。

💥 设置权限

获取权限

🔥 集成Facebook SDK

按照上面指示操作即可,不要下载SDK项目,让你导入的库的版本,那些已经过时了。如让你导入的SDK还是[5,6)版本,但是Github上面的版本已经12.0.1了。看操作就行,最新项目和导入的哭还是要去GitHub上找。地址下面给到,咱们先集成。

💥 使用 Maven

🌀 1.在 build.gradle (Project) 中添加 jcenter()

buildscript {
    repositories {
        jcenter()
    }
}

🌀 2.在 build.gradle (Module: app) 并中添加库

dependencies {
    implementation 'com.facebook.android:facebook-android-sdk:12.0.1'
    implementation 'com.facebook.android:facebook-login:12.0.1'
}

🌀 3.构建项目

使用 Facebook 登录 SDK 时,如果未禁用事件自动记录功能,那么系统将自动记录和收集应用事件,以用于 Facebook 分析。(这个功能基本废了)

💥 将软件包名称和默认类与应用进行关联

💥 生成密钥散列

密钥散列(不同电脑生成的可能不同),所以不管生成开发或发布密钥散列时都核实一下,并上传到Facebook。

🌀 生成开发密钥散列

每个 Android 开发环境都将会有一个唯一的开发密钥散列(不同电脑生成的可能不同)。Facebook支持上传多个密钥。

Mac OS

需要 Java 开发包中的密钥和证书管理工具 (keytool)。 如要生成开发密钥散列,请打开终端窗口,运行以下命令:

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

Windows

  • Java 开发包中的密钥和证书管理工具 (keytool)
  • Google Code Archive 的 Windows 版 openssl-for-windows OpenSSL 库 如要生成开发密钥散列,请在 Java SDK 文件夹的命令提示符中运行以下命令:
keytool -exportcert -alias androiddebugkey -keystore "C:\Users\USERNAME\.android\debug.keystore" | "PATH_TO_OPENSSL_LIBRARY\bin\openssl" sha1 -binary | "PATH_TO_OPENSSL_LIBRARY\bin\openssl" base64

🌀 生成发布密钥散列(发版了)

Android 应用必须先使用发布密钥进行电子签名,然后才能上传到商店中。如要生成发布密钥散列,请在 Mac 或 Windows 内运行以下命令:

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

🌀 代码生成

这种生成方式,我经常用。简单省事

        try {
            PackageInfo info = getPackageManager().getPackageInfo(
                    "com.scc.sccmall(你的包名)",
                    PackageManager.GET_SIGNATURES);
            for (Signature signature : info.signatures) {
                MessageDigest md = MessageDigest.getInstance("SHA");
                md.update(signature.toByteArray());
                Log.e("HashKey:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
            }
        } catch (PackageManager.NameNotFoundException e) {
        } catch (NoSuchAlgorithmException e) {
        }

运行结果:E/HashKey: +HCAQng1tQI5z/lqF2jVThpufHk=

咱们将 +HCAQng1tQI5z/lqF2jVThpufHk= 填入save,继续向下走。

🌀 错误提示生成

做登录测试的时候会提示密钥散列不正确,并且会将正确的密钥散列显示出来,填入即可。

💥 配制资源和清单文件

🌀 在strings.xml添加资源

刚才获取的应用编号

<string name="facebook_app_id">2992757927647074</string> 
<string name="fb_login_protocol_scheme">fb2992757927647074</string>

🌀 在AndroidManifest.xml添加内容

        <meta-data
            android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id" />

        <activity
            android:name="com.facebook.FacebookActivity"
            android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
            android:label="@string/app_name" />
        <activity
            android:name="com.facebook.CustomTabActivity"
            android:exported="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="@string/fb_login_protocol_scheme" />
            </intent-filter>
        </activity>

💥 记录应用事件

iOS14 的原因导致应用事件(回传事件时间较长14天左右)无法满足运营需求,故从AppsFlyer回传至Facebook经常分析。

当然如果仅参考或者无时间要求可接入

🌀 Application 类的 onCreate 方法中添加内容

@Override
public void onCreate() {
    super.onCreate();
    FacebookSdk.sdkInitialize(getApplicationContext());
    AppEventsLogger.activateApp(this);
}

🌀 购买事件

logger.logPurchase(BigDecimal.valueOf(4.32), Currency.getInstance("USD"));

🌀 其他事件

    public void setEvent(String event) {
        AppEventsLogger logger = AppEventsLogger.newLogger(MyApp.getAppContext().getTopActivity());
        if(event.equals("Complete Registration"))
        {
            //这里你可以传入FB定义的Event也可以自定义
            //params是你传入的事件参数,可不传
            Bundle params = new Bundle();
            logger.logEvent(AppEventsConstants.EVENT_NAME_COMPLETED_REGISTRATION, params);
        }else {
            logger.logEvent(event);
        }
        setAfEvent(event, null);
    }

💥 注册回调

public class MainActivity extends AppCompatActivity {

    private CallbackManager registerCallback(){
        if (callbackManager == null) {
            callbackManager = CallbackManager.Factory.create();

            LoginManager.getInstance().registerCallback(callbackManager,
                    new FacebookCallback<LoginResult>() {
                        @Override
                        public void onSuccess(LoginResult loginResult) {
                            AccessToken accessToken = loginResult.getAccessToken();
                            String userId = accessToken.getUserId();
                            String token = accessToken.getToken();
                            MLog.e("onSuccessLogin", "userId:" + userId + "|accessToken:" + token);
                        }

                        @Override
                        public void onCancel() {
                            // App code
                            MLog.e("onCancel");
                        }

                        @Override
                        public void onError(FacebookException exception) {
                            MLog.e("onError");
                        }
                    });    
        }
        return callbackManager;
    }
    private CallbackManager callbackManager;
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        registerCallback().onActivityResult(requestCode, resultCode, data);
        super.onActivityResult(requestCode, resultCode, data);
    }

🔥 安装FaceBook

  • 已放弃Android WebView的登入方式。

  • SDK 版本 必须高于 8.2 ,并在登录期间删除登录行为中的任何覆盖(即,使用 LoginBehavior.WEB_VIEW_ONLY)。

所以必须下载FaceBoook进行登录。

🔥 开始测试

💥 开发中

可以生成测试账号用于本应用测试。

💥 已上线

我将已上线打开,直接用自己的facebook账号测试。

💥 错误

  • 有的是因为密钥散列输入有误导致的,将她提示的密钥散列添加即可。

  • 有的因为应用刚创建或刚对外,暂未生效,过段时间再尝试。

  • 未设置权限和功能

💥 登入测试

调用SDK方法登入,传入的public_profile 就是我们在上面申请的权限。

public_profile:允许应用在 用户 节点中读取 默认公开资料字段 。系统将自动向所有应用授予此权限。

LoginManager.getInstance().logInWithReadPermissions(MainActivity.this, Arrays.asList("public_profile"));

好了,在回调接口中拿到了LoginResult.getAccessToken(),下面是AccessToken的userId和token,齐活。

日志打印:

E/-SCC-onSuccessLogin: 
userId:600111111111194|
accessToken:EAAqh5cEtF2IBAHy4SZBSGTEKKkcLPIBw83Uslk2yKOgZB5iCdDGLiXXXXXXXXXXXXXXXXXXGkN9COLbLAebhqVpyPdq7FEnto2ZB7S8nXzL2U754VZBJ5xfvrnhEJ4mqtYHqHIAO88MRKOXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXhqVpD48lZA1zfBejpyfglXQ0kYUIj0S1JeEkKhZAh0KIhAZDZD

好了,在回调接口中拿到了LoginResult.getAccessToken(),

🔥 应用事件测试

🔥 传送门

💥 登入文档传送门

💥 创建应用传送门

💥 应用事件测试传送门

💥 GithubSDKDemo传送门