internal persistentDataPath with WRITE_EXTERNAL_STORAGE permission

Hi,

I having problem about using persistentDataPath on Android.

I know that persistentDataPath will return different data path base on “write access” setting.
same of permission __WRITE_______EXTERNAL_______STORAGE in AndroidManifest.xml

Internal Only : data/data/xxxx/files/ ( Player cannot get file inside this path without root )

External ( SD Card ) : Android/data/com.xxx.xx/files/ ( Player can get file inside this path without root )

However, I am going to save game data into Internal persistentDataPath, but i have WRITE_ EXTERNAL_STORAGE permission because i want to use expansion file( .obb ), but now my game data saved at SD Card and player can get file and edit.

So my question is, how can i save data into internal persistentDataPath with __WRITE_______EXTERNAL_______STORAGE permission ?

=== UPDATE ===

I am trying to hard code internal persistentDataPath and move file from public persistentDataPath, it was success, i can move it and also read and delete _AT THE FIRST TIME, but when i quit app and launch again, i got a _UnauthorizedAccessException and blocked at Delete File action.

4 Answers

4

Finally, i found that UnauthorizedAccessException caused by System.IO.File.Move() ,

I took many test, to read, to write, to delete, i found that i can read and write data directly before called Move(),

so I used ReadAllBytes, WriteAllBytes and then Delete() the old file instead

problem solved.

You can get your Android apps internal path directly from Unity without a plugin, even with permission WRITE_EXTERNAL_STORAGE. Similar code can be used to get any other path.

I spent 2 days on this :P. First I made my own Java plugin, but as I do not like to extend my current Activity or Application I ran into problems. Finally I pieced together how to do it directly from Unity with the following code:

string path = "";
#if UNITY_ANDROID && !UNITY_EDITOR
try {
         IntPtr obj_context = AndroidJNI.FindClass("android/content/ContextWrapper");
         IntPtr method_getFilesDir = AndroidJNIHelper.GetMethodID(obj_context, "getFilesDir", "()Ljava/io/File;");

         using (AndroidJavaClass cls_UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
            using (AndroidJavaObject obj_Activity = cls_UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity")) {
               IntPtr file = AndroidJNI.CallObjectMethod(obj_Activity.GetRawObject(), method_getFilesDir, new jvalue[0]);
               IntPtr obj_file = AndroidJNI.FindClass("java/io/File");
               IntPtr method_getAbsolutePath = AndroidJNIHelper.GetMethodID(obj_file, "getAbsolutePath", "()Ljava/lang/String;");   
                                
               path = AndroidJNI.CallStringMethod(file, method_getAbsolutePath, new jvalue[0]);                    

               if(path != null) {
                  Debug.Log("Got internal path: " + path);
               }
               else {
                  Debug.Log("Using fallback path");
                  path = "/data/data/*** YOUR PACKAGE NAME ***/files";
               }
            }
         }
      }
      catch(Exception e) {
         Debug.Log(e.ToString());
      }
#else
      path = Application.persistentDataPath;
#endif

I hope it will help some devs without Java knowledge (like myself :)) to save some time and headache.

Thanks I'm going to use this! I have an issue where the persistentDataPath is pointing to the SD card of players, but my game doesn't have the permission to write there. Your code will help me for when this happens!

Can you save your data in PlayerPrefs Unity - Scripting API: PlayerPrefs ? It cannot be modified by the user without root access. For storing several string or number values that would be pretty convenient.

Otherwise, I can’t remember a simple way of having WRITE_EXTERNAL_STORAGE and having your data path in the internal storage.

no, cause my game datas is a sqlite file.... do you think can i hard code the internal data path to do this ?

You need to write a native android plugin to return the internal storage path, and not use the Application.persistantDataPath. Look at the code in this example: 日本入室强伦姧BD在线观看,日韩中文人妻无码不卡,卧室征服朋友人妻,人妻办公室被强奷