This is my first time asking a question on stack overflow, let me know if I missed mandatory informations.
I’ll try to summarize efficiently.
The goal
I’m coding a Unity Android App, in which I want to implement an auto-update functionnality.
After Unity has downloaded the updated version of my app from a server, I want it to open it programmaticaly.
On Unity side, everything works fine (I can call custom made java functions from my *.aar file).
On Android Studio side (which I’m using for the first time), I’m implementing a "OpenApk()" method.
My code
Here is what I import to use Android tools:
import androidx.core.content.FileProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import java.io.File;
Here is my function in Android Studio:
public void openApkFile(String _filePath) {
try {
File apkFullPath = new File(context.getFilesDir() + File.separator + _filePath);
Uri apkUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", apkFullPath);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(intent);
}
catch (Exception e) {
printToastMessage(e.toString(), true);
}
}
Here is my AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.opu.intranet"> <!-- I ADDED MY PACKAGE NAME HERE -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!-- ADDING THIS PROVIDER VIA XML PREVENTS APP FROM RUNNING (CRASH ON EXECUTION) -->
<application>
<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_paths" />
</provider>
</application>
</manifest>
Also I added:
android.useAndroidX=true # WAS ALREADY PRESENT BY DEFAULT
android.enableJetifier=true
to gradle.properties.
Le problem
Whenever I build my *.aar package and add it to Unity, if the AndroidManifest.xml file contains , the app won’t run anymore on my phone.
It closes immediately after opening, and the OS asks me to wait for the developer to solve the problem haha.
Here is the error log:
FATAL EXCEPTION: main
Process: com.opu.securityconcilapp, PID: 29513
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/~~jLNBDfF2HmsctyymOxViwQ==/com.opu.securityconcilapp-bZsahkZ0i3R7T1ZoK0sdTw==/base.apk"],nativeLibraryDirectories=[/data/app/~~jLNBDfF2HmsctyymOxViwQ==/com.opu.securityconcilapp-bZsahkZ0i3R7T1ZoK0sdTw==/lib/arm64, /data/app/~~jLNBDfF2HmsctyymOxViwQ==/com.opu.securityconcilapp-bZsahkZ0i3R7T1ZoK0sdTw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]] at android.app.ActivityThread.installProvider(ActivityThread.java:8463)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:7963)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7649)
at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2478)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8893)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Caused by: java.lang.ClassNotFoundException: Didn’t find class "androidx.core.content.FileProvider" on path: DexPathList[[zip file "/data/app/~~jLNBDfF2HmsctyymOxViwQ==/com.opu.securityconcilapp-bZsahkZ0i3R7T1ZoK0sdTw==/base.apk"],nativeLibraryDirectories=[/data/app/~~jLNBDfF2HmsctyymOxViwQ==/com.opu.securityconcilapp-bZsahkZ0i3R7T1ZoK0sdTw==/lib/arm64, /data/app/~~jLNBDfF2HmsctyymOxViwQ==/com.opu.securityconcilapp-bZsahkZ0i3R7T1ZoK0sdTw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at android.app.AppComponentFactory.instantiateProvider(AppComponentFactory.java:147)
at android.app.ActivityThread.installProvider(ActivityThread.java:8447)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:7963)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7649)
at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2478)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8893)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Software versions
Unity: 2022.3.20f1
Android Studio: 2023.2.1
Gradle: 7.1.2 on Unity side, 8.4 on Android Studio side
Android: 14 (API 34)
Target SDK : API 24 or higher
Fix attempts
I spent 2 days reading similar discussions about this everywhere, and testing multiple combinations. I even unzipped AndroidFileOpener (See here) by Mihail5412, a plugin I used before but stopped working after a while (Unity Editor package rename errors).
I tried removing "enableJetifier=true", using "android.support.v4.content.FileProvider" instead of "androidx.core.content.FileProvider" (with the required *.jar library added to the project but it created duplicates with androidx.core).
A huge thanks to anyone who will take the time to read me, please be sure I’ll follow that thread with attention.
Best regards.
2
Answers
I fixed the problem, a huge thanks to Bob Smith, Retired Ninja for their help here, and to Tomas1856 member of Unity Dev team on this thread.
I have to add:
-keep class androidx.core.content.FileProvider { *; }
to proguard-user.txt, file to enable via Unity->Edit->Projects Settings->Player->Publishing Settings->Custom Proguard File. The file path is then showed by Unity below the toggle button.
I also had to add:
to gradleTemplate.properties, file to enable via Unity->Edit->Projects Settings->Player->Publishing Settings->Custom Gradle Properties Template.
Final Android Studio AndroidManifest.xml configuration is:
I still have issues with file path configuration to allow the plugin to open the APK (Failed to find configured root that contains [...]), but I'll ask a new question for that, since it is off topic.
Try this solution:
src/main/res/xml/file_paths.xml
src/main/AndroidManifest.xml
src/main/java/com/image/crop/lib/DocumentScannerFileProvider.kt