# Unity Android 寫入檔案至外部資料夾 在 Unity 中如果想要存資料到裝置上的話,一般會選用可讀可寫的 `Application.persistentDataPath`。 若我們想把檔案寫到這以外的路徑,在以前我們可以在 manifest 加上 `WRITE_EXTERNAL_STORAGE` 權限,搭配 `requestLegacyExternalStorage`使用。但自從 Android 11 之後,相關權限有所改動: > ![](https://i.imgur.com/RIRRjIg.png) > https://developer.android.com/about/versions/11/privacy/storage ## 解決方法 如果 target platform 設為 Android R (11) 以上,改為使用 `MANAGE_EXTERNAL_STORAGE` 權限 https://developer.android.com/training/data-storage/manage-all-files 例如我們想要把檔案寫到使用者根目錄的 `~/LabData/{APP名稱}/`底下,程式大概長這樣: ```csharp= void WriteFileDemo() { string path = $"/storage/emulated/0/LabData/{Application.productName}/Test_{System.DateTime.Now:yyyyMMdd_HHmmss}.txt"; // create folder if(!Directory.Exists(Path.GetDirectoryName(path))) Directory.CreateDirectory(Path.GetDirectoryName(path)); // write data File.AppendAllText(_path, "Hello World!\n"); _demoText.text = $"Append to {path}"; } ``` 如果我們直接跑這段程式,雖然可以建出資料夾,但在寫檔時會報出 `UnauthorizedAccessException` 這裡我們需要先在 manifest (`Plugins/Android/AndroidManifest.xml`) 定義好需要的權限。 *(如果沒有,就去勾 PlayerSettings>Plublishing Settings>Custom main manifest 的框框,他就長出來囉)* ```xml= <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> ``` 接下來在寫檔案前預先向使用者索取權限 *(我是寫在 `Start()` 裡面)*,這裡官方文檔說要用 intent 跳轉到設定頁面,程式如下: ```csharp= // Android >11 需要跳轉外部管理權限 (檢查 AndroidManifest 有沒有 <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> ) if(new AndroidJavaClass("android.os.Environment").CallStatic<bool>("isExternalStorageManager") == false) { AndroidJavaObject currentActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity"); AndroidJavaObject reqPermsIntent =new AndroidJavaObject("android.content.Intent", new AndroidJavaClass("android.provider.Settings").GetStatic<string>("ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION"), new AndroidJavaClass("android.net.Uri").CallStatic<AndroidJavaObject>("parse", "package:"+Application.identifier)); currentActivity.Call("startActivity", reqPermsIntent); } ``` > ![](https://i.imgur.com/Fntykma.png =300x) > 上面這段程式會判斷是否已同意權限,如果還沒就會跳出這個視窗。把它勾起來返回遊戲就能正常寫檔了。 ## Demo https://github.com/JCxYIS/UnityAndroid_StoreToExternalPathTest