もとの構成はこんな感じです(facebookAppId の値はダミーです)。
build.gradle
android {
...
defaultConfig {
...
manifestPlaceholders = [facebookAppId: "1234567890000000"]
}
...
}
dependencies {
...
implementation "com.facebook.android:facebook-android-sdk:6.1.0"
implementation "com.facebook.android:facebook-share:6.1.0"
}
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
...
<application
...>
...
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="${facebookAppId}" />
<provider
android:name="com.facebook.FacebookContentProvider"
android:authorities="com.facebook.app.FacebookContentProvider${facebookAppId}"
android:exported="true" />
</application>
</manifest>
公式のドキュメント(https://developers.facebook.com/docs/android/getting-started#app_id)には meta-data を AndroidManifest に書けば勝手に初期化処理がされると書いてあるのに、実際に動かすと以下の初期化処理が走っていないというエラーで落ちます。
java.lang.ExceptionInInitializerError Caused by: The SDK has not been initialized, make sure to call FacebookSdk.sdkInitialize() first.
調べてみると FacebookSdk の loadDefaultsFromMetadata() の中で meta-data から読みんだ com.facebook.sdk.ApplicationId の値が Float になっていることが判明しました!(facebookAppId が全て数字だからそうなるのでしょうか...)
下記の Object appId が Float になってしまっていたのです。そのためその後の if 文に入らず、applicationId がセットされていませんでした。
FacebookSdk.java
// Package private for testing only
static void loadDefaultsFromMetadata(Context context) {
if (context == null) {
return;
}
ApplicationInfo ai = null;
try {
ai = context.getPackageManager().getApplicationInfo(
context.getPackageName(), PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
return;
}
if (ai == null || ai.metaData == null) {
return;
}
if (applicationId == null) {
Object appId = ai.metaData.get(APPLICATION_ID_PROPERTY);
if (appId instanceof String) {
String appIdString = (String) appId;
if (appIdString.toLowerCase(Locale.ROOT).startsWith("fb")) {
applicationId = appIdString.substring(2);
} else {
applicationId = appIdString;
}
} else if (appId instanceof Integer) {
throw new FacebookException(
"App Ids cannot be directly placed in the manifest." +
"They must be prefixed by 'fb' or be placed in the string resource file.");
}
}
...
}
ここの処理を読むと、appId の最初に fb or FB がついているときはそれを省いた部分を applicationId にしていることがわかります。
そこで以下のように meta-data の value を "fb${facebookAppId}" にしたら怒られなくなりました!
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
...
<application
...>
...
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="fb${facebookAppId}" />
<provider
android:name="com.facebook.FacebookContentProvider"
android:authorities="com.facebook.app.FacebookContentProvider${facebookAppId}"
android:exported="true" />
</application>
</manifest>
ちなみに facebookAppId を string resource で用意した場合
<string name="facebook_app_id">1234567890000000</string>
とか
android {
...
defaultConfig {
...
resValue "string", "facebook_app_id", "1234567890000000"
}
...
}
のときは、fb を付けなくても com.facebook.sdk.ApplicationId の値は String として読み込まれます。
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" />
0 件のコメント:
コメントを投稿