You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity3d NativeShare在Android8.0+设备报错FileUriExposedException求助

Fixing android.os.FileUriExposedException for Android 8.0+ in Unity NativeShare

Hey there, that FileUriExposedException is a super common gotcha for Android 7.0 (API 24) and newer—Google tightened security to block apps from exposing local file paths directly via file:// URIs. Let's get your NativeShare script working on Oreo and above with these straightforward steps:

Step 1: Add FileProvider Configuration to AndroidManifest.xml

First, we need to declare a FileProvider in your Android manifest to safely share file URIs. Open your project's Plugins/Android/AndroidManifest.xml (create the file if it doesn't exist) and add this inside the <application> tag:

<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>

Next, create a new folder Plugins/Android/res/xml and add a file named file_paths.xml with this content (this tells FileProvider which directories we're allowed to share):

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="shared_files" path="." />
</paths>

The <files-path> tag maps directly to Unity's Application.persistentDataPath (which corresponds to the files directory on Android), so this covers your screenshot storage path perfectly.

Step 2: Update the NativeShare.cs Android Code

Now modify the Android section of your Share method to use FileProvider instead of direct file:// URIs. Here's the revised code block:

#if UNITY_ANDROID
AndroidJavaClass intentClass = new AndroidJavaClass("android.content.Intent");
AndroidJavaObject intentObject = new AndroidJavaObject("android.content.Intent");
intentObject.Call<AndroidJavaObject>("setAction", intentClass.GetStatic<string>("ACTION_SEND"));

// Replace old Uri.parse logic with FileProvider
AndroidJavaObject fileObject = new AndroidJavaObject("java.io.File", imagePath);
AndroidJavaClass fileProviderClass = new AndroidJavaClass("androidx.core.content.FileProvider");
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
string packageName = currentActivity.Call<string>("getPackageName");
AndroidJavaObject uriObject = fileProviderClass.CallStatic<AndroidJavaObject>(
    "getUriForFile",
    currentActivity,
    packageName + ".fileprovider", // Matches authority from AndroidManifest
    fileObject
);

// Grant temporary read permission to the receiving app
intentObject.Call<AndroidJavaObject>("addFlags", intentClass.GetStatic<int>("FLAG_GRANT_READ_URI_PERMISSION"));

intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_STREAM"), uriObject);
intentObject.Call<AndroidJavaObject>("setType", "image/png");
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_TEXT"), shareText);

AndroidJavaObject jChooser = intentClass.CallStatic<AndroidJavaObject>("createChooser", intentObject, subject);
currentActivity.Call("startActivity", jChooser);
#endif

Key Changes Breakdown:

  • FileProvider.getUriForFile: Generates a secure content:// URI instead of the blocked file:// scheme, which is required for Android 7.0+.
  • FLAG_GRANT_READ_URI_PERMISSION: Gives the receiving app temporary access to the screenshot file, so it can load and display it.
  • Package Name Authority: Uses your app's unique package name to ensure the FileProvider authority matches what's declared in the manifest (avoids mismatches).

Step 3: Double-Check Unity Android Settings

Make sure your Unity project is set up to use AndroidX (since we're using androidx.core.content.FileProvider):

  • Go to Edit > Project Settings > Player > Android > Publishing Settings
  • Enable Custom Main Gradle Template
  • Open the generated mainTemplate.gradle and confirm it includes AndroidX dependencies (Unity usually adds this by default in recent versions, look for something like implementation 'androidx.core:core:1.+').

That's it! This should resolve the FileUriExposedException and get your share feature working smoothly on Android 8.0+ devices while keeping compatibility with older versions.

内容的提问来源于stack exchange,提问作者Ahmad Zafar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:53:58