尝试为 Unity 构建 Android 插件时无法获取提供程序 androidx.core.content.FileProvider ClassNotFoundException

Unable to get provider androidx.core.content.FileProvider ClassNotFoundException when trying to build an Android Plugin for Unity

我正在尝试为 unity3d 构建一个 android 插件,它只是通过 FileProvider 将屏幕截图分享给另一个应用程序。
我将我的项目迁移到 androidx.
我用过 androidx.core.content.FileProvider class.
每当我启动我的应用程序时,它就会崩溃,出现以下 Logcat:

2018-12-22 21:46:13.678 14755-14755/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.anascompany.testandroidplugin, PID: 14755
java.lang.RuntimeException: Unable to get provider androidx.core.content.FileProvider: java.lang.ClassNotFoundException: Didn't find class "androidx.core.content.FileProvider" on path: DexPathList[[zip file "/data/app/com.anascompany.testandroidplugin-bwZMktz2HTL449ojsD7y9g==/base.apk"],nativeLibraryDirectories=[/data/app/com.anascompany.testandroidplugin-bwZMktz2HTL449ojsD7y9g==/lib/x86, /data/app/com.anascompany.testandroidplugin-bwZMktz2HTL449ojsD7y9g==/base.apk!/lib/x86, /system/lib]]
    at android.app.ActivityThread.installProvider(ActivityThread.java:6396)
    at android.app.ActivityThread.installContentProviders(ActivityThread.java:5938)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5853)
    at android.app.ActivityThread.access00(ActivityThread.java:199)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
 Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.core.content.FileProvider" on path: DexPathList[[zip file "/data/app/com.anascompany.testandroidplugin-bwZMktz2HTL449ojsD7y9g==/base.apk"],nativeLibraryDirectories=[/data/app/com.anascompany.testandroidplugin-bwZMktz2HTL449ojsD7y9g==/lib/x86, /data/app/com.anascompany.testandroidplugin-bwZMktz2HTL449ojsD7y9g==/base.apk!/lib/x86, /system/lib]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    at android.app.AppComponentFactory.instantiateProvider(AppComponentFactory.java:121)

我已经搜索过这个问题并尝试了以下方法:
1.MultiDex问题。
为了在我的项目中轻松包含 MultiDex,我将最小 SDK 更改为 API 23 Marshmallow 6.0.
Android documentation 表示要包含 MultiDex,您需要在指定模块的 build.gradle 文件的 defaultConfig 中添加 multiDexEnabled true
注意:文档说如果最低 SDK 设置为 API 21 或更高,这是包含 MultiDex 所需的唯一步骤。
2. 包错问题(估计就是这个问题)
在 androidx 之前我们使用了这个包:com.android.support:support-v4 所以根据这个 page 你应该用 androidx.legacy:legacy-support-v4:1.0.0 替换以前的包并且还用 android.support.v4.content.FileProvider 替换=19=].
这是我的 android 清单:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.anascompany.unity">
<application>
    <provider
        android:authorities="com.anascompany.unity.fileprovider"
        android:name="androidx.core.content.FileProvider"
        android:grantUriPermissions="true"
        android:exported="false">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/filepaths" />
    </provider>
</application>


这是我的模块的 build.gradle 文件:

apply plugin: 'com.android.library'

android {
    compileSdkVersion 28
    defaultConfig {
    minSdkVersion 23
    targetSdkVersion 28
    versionCode 1
    versionName "1.0"

    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

    multiDexEnabled true
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 
'proguard-rules.pro'
    }
}
productFlavors {
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'

    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
}

task copyPlugin(type: Copy){
    dependsOn assemble
    from ('build/outputs/aar')
    into ('../../Assets/Plugins/Android')
    include (project.name + '-release.aar')
}


注:目标SDK在unity和android studio都设置为28 "Android Pie".
注意:我的问题与这个 不同,因为我已经包含在清单中 androidx.core.content.FileProvider

改为

implementation 'androidx.core:core:1.0.1'

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_provider_paths" />
</provider>

终于找到了解决方案,非常简单。就像手动复制 "support-v4-24.1.1.aar" 到插件统一项目文件夹一样简单。或者其他支持aar android 的文件。它带有 SDK。 在我的例子中,文件位于 "C:\AndroidSDK\extras\android\m2repository\com\android\support\support-v4.1.1"

无论版本如何,但您应该确保 "FileProvider" class 在文件中。您可以使用 winrar 简单地解压缩 aar 文件,并确保 class 在那里。

---更新---

总结:在 /yourProjectFolder/Assets/Plugins 中复制你的 unity-release.aar 编译的 android 模块并手动复制 support-v4-24.1.1.aar(或其他版本,我的大小接近 1MB)

这是我的清单:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.unity">
<application>
 <provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.example.unity.fileprovider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/filepaths" />
 </provider>
</application>
</manifest>

这是我的模块 build.gradle:

dependencies {
  implementation fileTree(include: ['*.jar'], dir: 'libs')
  implementation 'com.android.support:appcompat-v7:28.0.0'
  testImplementation 'junit:junit:4.12'
  androidTestImplementation 'com.android.support.test:runner:1.0.2'
  androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

希望对你和其他人有所帮助。

如果您想使用较新的实现 (androidx.core.content.FileProvider) 但它仍然崩溃,您可能还需要手动将库放入项目中。

我下载了 aar 文件 (https://mvnrepository.com/artifact/androidx.core/core/1.0.1),因为我正在处理一个 unity3d 项目,所以我将它放入文件夹“Assets\Plugins\Android\libs”。对于 Android,它可能是“Android\lib”。

希望对某人有所帮助

我有同样的初始化错误。我将 Android 项目 属性 中的 Code Shrinker 属性 从 ProGuard 和 R8 更改为 EMPTY。这解决了这个问题。只需删除 ProGuard 属性 即可。我稍后会尝试找到另一个解决方法,但现在,这对我来说没问题。