Hi everyone,
I took a quick look at the forums rules for this first post of mine, but feel free to inform me of any missing information.
I’m coding a Unity Android App, in which I want to implement an auto-update functionality. After Unity has downloaded the updated version of my app from a server, I want it to open it programmatically.
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.
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 (Android Studio side, no custom one is used on Unity side):
<?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.enableJetifier=true```
to gradle.properties (still on Android Studio side).
**Problem**
Whenever I build my *.aar package and add it to Unity, if the AndroidManifest.xml file contains a reference to a file provider, 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. :smile:
Here is the log cat of my smartphone when I try to open the app:
```Unable to get provider androidx.core.content.FileProvider: java.lang.ClassNotFoundException: Didn't find class "androidx.core.content.FileProvider"```
**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](https://github.com/Mihail5412/Unity-Android-Files-Opener)) by Mihail5412, a plugin I used before but stopped working after a while (Unity Editor package rename errors).
I tried 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).
I also tried making my own CustomFileProvider class to be referenced by the AndroidManifest.xml file, but fails again.
I followed many threads, the last of which made me think it may have something to do with how I set Unity publishing settings..?
https://discussions.unity.com/t/754221
https://discussions.unity.com/t/problem-with-file-provider-class/233959/2
Whenever I try to add references to the FileProvider via custom AndroidManifest.xml on Unity side, add "dependencies { implement:androidx.core[...] }" and "android.useAndroidX=true", Unity fails to build saying that gradle version is not set for Android SDK > 32.
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. ;)
A guess, but try creating custom proguard file (Unity - Manual: Android Player settings), Unity - Manual: Android Player settings
and add entry like
-keep class androidx.core.content.FileProvider { *; }
This will ensure class stays available
Hi Tomas, thanks a lot for your reply, this has been very helpful!
I added as you said, and then realized Unity wasn’t configured to use Jetifier and AndroidX.
So in addition to adding:
-keep class androidx.core.content.FileProvider { *; }
to gradleTemplate.properties, file to enable via Unity->Edit->Projects Settings->Player->Publishing Settings->Custom Gradle Properties Template.
I also added:
android.enableJetifier=true
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:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource=" @ /file_paths" />
</provider>
</application>
I let a lot of details on how to access these files for those who would encounter a similar issue.
New problem
I now have an issue with configuring the file path to be opened by my plugin. If this requires a new post, I’ll remove the following text and open a new thread (let me know).
Now that the app runs, I get the following error:
java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/com.opu.securityconcilapp/files/storage/emulated/0/Android/data/com.opu.securityconcilapp/files/<NAME_OF_APK_FILE>.apk
My plugin’s package name in Android Studio is “com.opu.intranet”.
The name of my final Unity apk is “com.opu.securityconcilapp”.
Here is the file_paths.xml I use in Android Studio for my OpenApkFile() java method:
<!--<external-path path="Android/data/com.opu.intranet" name="files_root" />-->
<!--<external-path path="Android/data/com.opu.securityconcilapp" name="files_root" />
<external-path path="/data/data/com.opu.securityconcilapp/files" name="files_root" />
<external-path path="." name="external_storage_root" />-->
<external-path path="Android/data/com.opu.securityconcilapp" name="files_root" />
</paths>
All those I commented were tested and do not work either.
My file is downloaded by Unity at runtime and stored in “Application.persistentDataPath”.
Any idea how to configure the path properly?
Should I, maybe, call my plugin’s package by the same name as the Unity side app ?
Thanks again!
Any idea how to configure the path properly?
Should I, maybe, call my plugin’s package by the same name as the Unity side app ?
Sorry no idea about this one
Very useful ressource, I didn’t find it during my research, thank you!
The changes I needed to do to make it work are part of that package, so that will be useful for others. (I found out on my own shortly before your reply).
For the file_paths.xml entry that was required, it happened that no entry is required on Unity side.
Here is the final file_paths.xml I now use to allow my Android Studio plugin to access the downloaded file:
<files-path path="/storage/emulated/0/Android/data/<UNITY_APK_PACKAGE_NAME>/files" name="files_root" />
This is the path provided to my Android Studio plugin (that has a different name than the Unity package, but requires the Unity Package name because it’s this that downloaded the file I try to open in the first place).
Now (because problems never stop arising ), it says “Problem occured while analyzing package” when it opens it, even though downloading the APK via my web browser and installing it via the File Manager works fine.
Probably an authorization issue I’ll seek an answer to that later and keep showing my findings here!