Unity Android端Gallery脚本无法识别JPG图片存储路径问题
问题根因
当前代码无法在Android端识别目标文件夹,由3个直接错误导致:
Directory.GetFiles属于System.IO原生文件接口,仅识别操作系统原生路径,不支持file://协议前缀,当前代码拼接的"file:///" + "/unitypictures/"属于无效路径,全平台都无法正常识别。- Android不存在根目录下的
/unitypictures/硬编码路径,不同存储分区的路径由系统分配,必须通过Unity提供的跨平台API获取,不能直接写死绝对路径。 - 加载纹理时重复拼接
file:///前缀:Directory.GetFiles返回的已经是文件绝对路径,重复拼接前缀会生成无效URI,导致加载失败。
修复方案
根据你存放jpg文件的位置选择对应跨平台路径API:
- 图片随安装包打包:使用
Application.streamingAssetsPath - 图片存应用私有可读写目录(卸载应用自动清理,无需额外存储权限):使用
Application.persistentDataPath - 图片存系统公共相册/Pictures目录:Android 13+需动态申请
READ_MEDIA_IMAGES权限后,通过系统存储访问框架获取路径,禁止硬编码。
以下是修复后的完整可运行代码,默认使用无需权限的persistentDataPath作为存储根目录:
using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; public class Gallery : MonoBehaviour { public List<Sprite> gallery = new List<Sprite>(); public Image displayImage; public Button nextImg; public Button prevImg; public int i = 0; void Start () { // 自动适配全平台路径,Android端会映射到当前应用私有存储下的对应目录 string jpgRootPath = Path.Combine(Application.persistentDataPath, "unitypictures"); // 目录不存在时自动创建,避免首次运行找不到路径报错 if (!Directory.Exists(jpgRootPath)) { Directory.CreateDirectory(jpgRootPath); } // System.IO接口仅传入原生路径,不要加file协议前缀 string[] Images = Directory.GetFiles(jpgRootPath,"*.jpg"); Debug.Log($"扫描到jpg文件数量:{Images.Length},根路径:{jpgRootPath}"); StartCoroutine(LoadImages(Images)); } IEnumerator LoadImages(string[] Images) { foreach (var path in Images) { Debug.Log($"正在加载图片:{path}"); // 通过Uri类自动生成正确的本地文件访问URI,避免手动拼接前缀出错 using (var uwr = UnityWebRequestTexture.GetTexture(new System.Uri(path).AbsoluteUri)) { yield return uwr.SendWebRequest(); if (uwr.result != UnityWebRequest.Result.Success) { Debug.Log($"图片加载失败:{uwr.error},路径:{path}"); // 单张图加载失败不终止整个加载流程,跳过继续加载剩余图片 continue; } Texture2D tex = DownloadHandlerTexture.GetContent(uwr); tex.wrapMode = TextureWrapMode.Clamp; Sprite sprite = Sprite.Create(tex, new Rect(0f, 0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), 50f, 0, SpriteMeshType.FullRect); gallery.Add(sprite); } yield return null; } // 所有图片加载完成后默认显示第一张,避免打开画廊空白 if (gallery.Count > 0) { displayImage.sprite = gallery[0]; } } public void BtnNext (){ if(i + 1 < gallery.Count){ i++; } displayImage.sprite = gallery[i]; } public void BtnPrev () { // 修复原逻辑无法切到第0张图的边界bug if (i - 1 >= 0){ i--; } displayImage.sprite = gallery[i]; } }
额外注意事项
- 所有System.IO命名空间下的文件/目录操作接口,一律传入不带协议前缀的原生路径;只有UnityWebRequest等网络类接口访问本地文件时,才需要标准URI格式,优先用
new Uri(path).AbsoluteUri自动生成,不要手动拼接file:///,避免斜杠数量错误。 - 若需读取Android公共存储的图片,目标SDK版本33及以上不要申请已废弃的
READ_EXTERNAL_STORAGE权限,需在Manifest中声明android.permission.READ_MEDIA_IMAGES,并在运行时动态申请通过后再访问。 - 真机调试时可通过Logcat输出的根路径,直接用adb工具检查对应目录下是否确实放入了jpg文件,排除文件本身没有存入目标目录的问题。
内容的提问来源于stack exchange,提问作者OscarTC
相关产品推荐
相关产品推荐

