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

Unity构建的Android应用无法在运行时访问SD卡中的Addressables场景包

Unity构建的Android应用无法在运行时访问SD卡中的Addressables场景包

我之前做Unity Android项目时,刚好碰到过几乎一模一样的场景加载问题,结合你用的Android 7(API 25)系统特性,给你梳理几个关键解决步骤,应该能帮你搞定:

1. 先搞定存储权限的问题

Android 7(API 25)属于API 23及以上版本,必须动态申请存储权限,只在Manifest里加权限是不够的:

  • 先在Unity的Project Settings > Player > Publishing Settings > Build里勾选Custom Main Manifest,然后在生成的AndroidManifest.xml中添加这两个权限:
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
  • 然后在Unity代码里,要么在应用启动时,要么在点击加载按钮前,主动申请权限:
    using UnityEngine;
    using UnityEngine.Android;
    
    public class PermissionHandler : MonoBehaviour
    {
        void Start()
        {
            if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite))
            {
                Permission.RequestUserPermission(Permission.ExternalStorageWrite);
            }
            if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageRead))
            {
                Permission.RequestUserPermission(Permission.ExternalStorageRead);
            }
        }
    }
    
    注意:有些定制化ROM(比如MIUI、EMUI)可能需要用户手动在系统设置里给应用开启「存储权限」,哪怕代码里申请了也可能被拦截,测试时可以先去系统设置确认权限是否开启。

2. 确认SD卡的真实路径,别用硬编码的固定路径

很多人会踩坑:把SD卡路径硬编码成/storage/sdcard/,但不同厂商的SD卡路径可能不一样(比如/storage/XXXX-XXXX/,XXXX是随机生成的分区ID)。正确的做法是通过Android原生API获取真实的SD卡路径:

public static string GetSDCardPath()
{
    AndroidJavaClass environmentClass = new AndroidJavaClass("android.os.Environment");
    AndroidJavaObject externalStorageDirs = environmentClass.CallStatic<AndroidJavaObject>("getExternalFilesDirs", (object)null);
    AndroidJavaObject[] dirs = externalStorageDirs.Call<AndroidJavaObject[]>("toArray");
    
    // 第一个是内部存储的外部目录,第二个通常是SD卡的目录
    if (dirs.Length >= 2)
    {
        string sdPath = dirs[1].Call<string>("getAbsolutePath");
        // 截取到SD卡根目录(去掉后面的Android/data/包名/files部分)
        sdPath = sdPath.Substring(0, sdPath.IndexOf("Android/data/"));
        return sdPath;
    }
    // 如果没找到SD卡,返回内部存储路径
    return Application.persistentDataPath;
}

拿到真实路径后,再拼接你的.bundle文件的相对路径,比如GetSDCardPath() + "/MyBundles/Scene1.bundle",然后用File.Exists()先判断文件是否存在,排除路径错误的问题。

3. 配置Addressables从自定义SD卡路径加载

Addressables默认会从内置的StreamingAssets或者远程服务器加载,要让它从SD卡加载,需要做以下配置:

  • 首先,确保你打包Addressables时,对应的Group的「Content Packing & Loading」设置中,「Build Path」和「Load Path」不要用默认的Remote路径,而是留空或者设置为自定义变量。
  • 在运行时,手动指定Addressables的加载路径,或者直接加载SD卡上的bundle文件:
    using UnityEngine.AddressableAssets;
    using UnityEngine.ResourceManagement.AsyncOperations;
    using System.IO;
    
    public async void LoadSceneFromSDCard()
    {
        string bundlePath = GetSDCardPath() + "/MyBundles/Scene1.bundle";
        
        if (!File.Exists(bundlePath))
        {
            Debug.LogError("Bundle文件不存在:" + bundlePath);
            return;
        }
    
        // 先加载bundle作为外部资源
        AsyncOperationHandle<AssetBundle> bundleHandle = Addressables.LoadAssetBundleAsync(bundlePath);
        await bundleHandle.Task;
    
        if (bundleHandle.Status == AsyncOperationStatus.Succeeded)
        {
            // 从bundle中加载场景
            AsyncOperationHandle<SceneInstance> sceneHandle = Addressables.LoadSceneAsync("Scene1", LoadSceneMode.Additive);
            await sceneHandle.Task;
            if (sceneHandle.Status == AsyncOperationStatus.Succeeded)
            {
                Debug.Log("场景加载成功!");
            }
        }
        else
        {
            Debug.LogError("加载Bundle失败:" + bundleHandle.OperationException);
        }
    }
    
    另外,也可以通过修改Addressables的Profile,把RemoteLoadPath设置为SD卡的路径变量,这样更符合Addressables的规范。

4. 检查Unity的Player Settings设置

最后确认Unity的打包设置:

  • 打开Project Settings > Player > Android > Other Settings
  • 把「Write Access」设置为External (SDCard),这样Unity会允许应用访问外部存储
  • 确保「Minimum API Level」设置为25,和你的目标设备一致

按照这几个步骤排查下来,基本就能解决SD卡中Addressables场景包加载失败的问题了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 12:38:10