由于磁盘加密,Android Crashlytics在直接启动时失败

时间:2018-07-17 08:54:55

标签: android firebase encryption crashlytics boot

Android Crashlytics将无法在android上直接启动时初始化。问题是在用户输入凭据之前,支持Android中上下文的默认存储已被加密:

https://developer.android.com/reference/android/content/Context.html#createDeviceProtectedStorageContext()

您会在类似的日志中看到一堆信息

  

07-17 16:47:18.083 1897-1982 / XXX   E / SharedPreferencesImpl:无法创建目录   SharedPreferences文件   /data/user/0/com.xxx.xxx/shared_prefs/com.crashlytics.sdk.android:answers:settings.xml

还通过向initializationCallback注册Fabric.Builder进行了验证

是否可以通过createDeviceProtectedStorageContext存储将崩溃解析配置为使用共享的首选项后端?

问题在于,如果应用程序以这种方式在启动时启动,那么crashlytics将在应用程序的生命周期内无法正常工作。这可能会导致丢失很多崩溃报告。

1 个答案:

答案 0 :(得分:1)

基本上,它失败了,因为Crashlytics之类的库会调用getBaseContext,这会使createDeviceProtectedStorageContext无效。对于Crashlytics,它还期望getApplicationContext返回一个Application。这是完整的解决方法。

实现以下类:(将其翻译成Java并不难)

@SuppressLint("Registered")
@TargetApi(24)
class DeviceStorageApp(context: Context) : Application() {
    init {
        attachBaseContext(context.createDeviceProtectedStorageContext())
    }

    /**
     * Thou shalt not get the REAL underlying application context which would no
     * longer be operating under device protected storage.
     */
    override fun getApplicationContext(): Context = this
}

AndroidManifest.xml中禁用自动初始化:

<meta-data android:name="firebase_crashlytics_collection_enabled"
           android:value="false"/>

然后在真实的Application.onCreate中执行以下操作:(省略了Android SDK版本检查)

Fabric.with(DeviceStorageApp(this), Crashlytics())

完整示例:https://github.com/Mygod/VPNHotspot/commit/2578c1c6ec67a8b9c7274c6f0e0f47ed030a6813