Unity移动端真机截图无法保存求助(模拟器运行正常)
问题解决:Unity移动端真机截图保存失败
核心问题分析
模拟器正常但真机失败,通常和路径格式错误、动态权限未申请、Android 10+存储权限限制这三个核心原因有关。
解决方案
1. 修正路径拼接错误
你的代码中直接拼接Application.persistentDataPath会导致路径缺少目录分隔符,改用Path.Combine自动处理路径格式:
using System.IO; using System; void CaptureScreenshot() { string fileName = $"_coin_{gameObject.name}_{DateTime.Now:MM-dd-yyyy_HH-mm-ss}.png"; string savePath = Path.Combine(Application.persistentDataPath, fileName); ScreenCapture.CaptureScreenshot(savePath); Debug.Log($"截图路径:{savePath}"); }
2. 动态申请权限(Android 6.0+)
仅在AndroidManifest.xml配置权限不够,Android 6.0(API 23)及以上需要代码动态申请读写权限:
using UnityEngine; using UnityEngine.Android; public class ScreenshotHandler : MonoBehaviour { public void TakeScreenshotWhenObjectVisible() { // 检查权限是否已授权 if (Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite) && Permission.HasUserAuthorizedPermission(Permission.ExternalStorageRead)) { CaptureScreenshot(); } else { // 请求权限 Permission.RequestUserPermission(Permission.ExternalStorageWrite); Permission.RequestUserPermission(Permission.ExternalStorageRead); // 延迟调用确保权限申请完成 Invoke(nameof(CaptureScreenshot), 2f); } } void CaptureScreenshot() { string fileName = $"_coin_{gameObject.name}_{DateTime.Now:MM-dd-yyyy_HH-mm-ss}.png"; string savePath = Path.Combine(Application.persistentDataPath, fileName); ScreenCapture.CaptureScreenshot(savePath); } }
3. 适配Android 10+的Scoped Storage
Android 10(API 29)引入Scoped Storage后,WRITE_EXTERNAL_STORAGE不再允许直接访问公共目录。如果需要截图在系统相册显示,需通过MediaStore插入图片:
#if UNITY_ANDROID && !UNITY_EDITOR using UnityEngine; using System.IO; using System; using Android.Content; using Android.Provider; using Android.Net; using Android.OS; public static class AndroidMediaHelper { public static Uri SaveToGallery(string localImagePath, string imageName) { ContentValues values = new ContentValues(); values.Put(MediaStore.Images.Media.Columns.DisplayName, imageName); values.Put(MediaStore.Images.Media.Columns.MimeType, "image/png"); // 适配Android 10+ if (Build.VERSION.SdkInt >= BuildVersionCodes.Q) { values.Put(MediaStore.Images.Media.Columns.RelativePath, "Pictures/YourAppScreenshots"); values.Put(MediaStore.Images.Media.Columns.IsPending, 1); } ContentResolver resolver = Android.App.Application.Context.ContentResolver; Uri uri = resolver.Insert(MediaStore.Images.Media.ExternalContentUri, values); if (uri != null) { // 将私有目录的图片复制到媒体库 using (Stream output = resolver.OpenOutputStream(uri)) using (Stream input = new FileStream(localImagePath, FileMode.Open)) { input.CopyTo(output); } if (Build.VERSION.SdkInt >= BuildVersionCodes.Q) { values.Clear(); values.Put(MediaStore.Images.Media.Columns.IsPending, 0); resolver.Update(uri, values, null, null); } } return uri; } } #endif
修改截图方法,完成后同步到相册:
void CaptureScreenshot() { string tempPath = Path.Combine(Application.persistentDataPath, $"_coin_{gameObject.name}_{DateTime.Now:MM-dd-yyyy_HH-mm-ss}.png"); ScreenCapture.CaptureScreenshot(tempPath); // 延迟1秒确保截图写入完成 Invoke(() => { #if UNITY_ANDROID && !UNITY_EDITOR AndroidMediaHelper.SaveToGallery(tempPath, Path.GetFileName(tempPath)); // 删除私有目录的临时文件(可选) File.Delete(tempPath); #endif }, 1f); }
4. 检查Unity Player Settings
- 打开
Player Settings > Android > Publishing Settings,确保勾选Custom Main Manifest,并确认AndroidManifest.xml配置正确。 - 若需兼容Android 11+全存储访问(不推荐),需在Manifest中添加:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
该权限需用户手动在应用设置中开启,优先推荐使用MediaStore方案。
调试建议
通过Android Studio的Logcat查看真机日志,搜索IOException或Permission Denied关键词,快速定位具体错误原因。
内容的提问来源于stack exchange,提问作者Yunesh Shrestha
相关产品推荐
相关产品推荐

