阻止来自 Facebook Android SDK 的网络请求

Prevent network requests from Facebook Android SDK

Android Facebook SDK 在调用 FacebookSdk.sdkInitialize(context) 时始终向 graph.facebook.com 发出网络请求,即使尚未使用任何 SDK。

因此,如果我们在 Application.onCreate() 中对其进行初始化,总会有至少一个网络请求。即使设置如下:

 <meta-data
    android:name="com.facebook.sdk.AutoLogAppEventsEnabled"
    android:value="false" />

我们已经仔细研究了这一点,因为用户抱怨他没有使用 Facebook 登录(这就是我们首先拥有 Facebook SDK 的原因)并且仍然有 "user data" 转移到脸书。在 GDPR 和可疑用户的时代,这是一种非常不利的行为!

我们现在所做的是仅在用户想要使用 Facebook 登录时(在用户单击按钮时)调用 FacebookSdk.sdkInitialize(context)。此外,我们从 AndroidManifest 中删除了 android:name="com.facebook.sdk.ApplicationId"meta-data。这会阻止初始网络请求,但随后 CurrentAccessTokenExpirationBroadcastReceiver:

中出现以下崩溃
java.lang.RuntimeException: Unable to start receiver com.facebook.CurrentAccessTokenExpirationBroadcastReceiver: The SDK has not been initialized, make sure to call FacebookSdk.sdkInitialize() first.
at com.facebook.internal.Validate.sdkInitialized(Validate.java:143)
    at com.facebook.FacebookSdk.getApplicationContext(FacebookSdk.java:518)
    at com.facebook.AccessTokenManager.getInstance(AccessTokenManager.java:86)
    at com.facebook.CurrentAccessTokenExpirationBroadcastReceiver.onReceive(CurrentAccessTokenExpirationBroadcastReceiver.java:34)

现在有几个问题:

  1. 为什么Facebook还在一开始就提出请求?如果他们想验证授权令牌,他们可以在真正使用 SDK 后立即执行...

  2. 当未调用 sdkInitialize() 时,Facebook 是否知道并容忍崩溃?因为我担心当这个 NullPointerException 被删除时会有其他崩溃......

  3. 最重要的:有没有其他方法可以在不使用 Facebook SDK 的功能时阻止来自 Facebook SDK 的网络请求?

根据Facebook Support,

如果您想暂时禁用自动事件收集,例如在收集数据之前获得最终用户的同意,您可以在应用程序标签的 AndroidManifest.xml 中将 AutoLogAppEventsEnabled 的值设置为 false。

例如:

<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="false"/>

要重新启用收集,例如在最终用户同意后,调用 FacebookSDK 的 setAutoLogAppEventsEnabled() 方法 class。

例如:setAutoLogAppEventsEnabled(true);

如果您出于任何原因需要再次暂停收集,您可以调用setAutoLogAppEventsEnabled(false);,收集将暂停直到重新启用。

我注意到 Facebook SDK(至少在版本 4.33 中)在您的应用程序清单中添加了一个提供程序 (com.facebook.internal.FacebookInitProvider),它会自动调用 FacebookSdk.sdkInitialize 和应用程序上下文。

即使你已经添加了:

<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="false" />

在您的清单中,将至少向 Facebook 发出 2 个请求:

  • 获取应用设置的图表请求
  • 一个事件请求“fb_sdk_initialize”,它记录了您的应用中包含的所有 Facebook 框架

因此,为了防止这些请求(只要用户不允许它们 (GDPR),我们就不想要),我认为您做了我们需要做的一切:

  • 不要在清单中添加<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
  • 在清单中添加<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="false"/>
  • 仅在需要时才初始化 Facebook SDK。

例如这样:

FacebookSdk.setApplicationId(<context>.getString(R.string.facebook_app_id));
FacebookSdk.sdkInitialize(<context>);
AppEventsLogger logger = AppEventsLogger.newLogger(<context>); // I don't use FB Login for my project but app events.

但是关于你的崩溃,我不知道为什么会发生,因为广播“com.facebook.sdk.ACTION_CURRENT_ACCESS_TOKEN_CHANGED”似乎是本地发送的。

尽管如此,我认为您可以通过将此添加到您的清单中来防止它:

<provider
    android:name="com.facebook.internal.FacebookInitProvider"
    tools:node="remove" />
<receiver
android:name="com.facebook.CurrentAccessTokenExpirationBroadcastReceiver"
    tools:node="remove" />

但是,这样做可能会对使用 Facebook SDK 产生不良后果,我认为您必须提供(并在您的清单中注册)您自己的 BroadcastReceiver:

public class CustomCurrentAccessTokenExpirationBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (AccessTokenManager.ACTION_CURRENT_ACCESS_TOKEN_CHANGED.equals(intent.getAction())) {
            new CurrentAccessTokenExpirationBroadcastReceiver().onReceive(context, intent); // Call it only if you have initialized the Facebook SDK!
        }
    }
}