Search Unity

Help with access/write files on Android

Discussion in 'Android' started by stefann, Jan 5, 2011.

  1. stefann

    stefann

    Joined:
    Jan 4, 2011
    Posts:
    17
    hi everybody,
    I'm trying to write a file to the Application.dataPath and to the sdcard but both of it doesn't work.
    I've been searching for quite a while now, but it seems that this topic is not really well covered yet.
    To do this I slightly modified this script from the Scripting Reference:
    Code (csharp):
    1. // Saves screenshot as PNG file.
    2. import System.IO;
    3.  
    4. // Take a shot immediately
    5. function OnGUI () {
    6.     if (GUI.Button (Rect (10,10,150,100), "write")) {
    7.         print ("You clicked the button!");
    8.         UploadPNG ();
    9.     }
    10. }
    11.  
    12. function UploadPNG () {
    13.     // We should only read the screen bufferafter rendering is complete
    14.     yield WaitForEndOfFrame();
    15.    
    16.     // Create a texture the size of the screen, RGB24 format
    17.     var width = Screen.width;
    18.     var height = Screen.height;
    19.     var tex = new Texture2D (width, height, TextureFormat.RGB24, false);
    20.     // Read screen contents into the texture
    21.     tex.ReadPixels (Rect(0, 0, width, height), 0, 0);
    22.     tex.Apply ();
    23.  
    24.     // Encode texture into PNG
    25.     var bytes = tex.EncodeToPNG();
    26.     Destroy (tex);
    27.  
    28.     // For testing purposes, also write to a file in the project folder
    29.     //File.WriteAllBytes(Application.dataPath + "/SavedScreen.png", bytes);
    30.     File.WriteAllBytes("/sdcard/testfolder/testWrite.png", bytes);
    31.    
    32. }
    When I press tho button nothing happens and in the LogCat I get the following messages:
    - for saving to sdcard:
    -for saving to Application.dataPath:
    My scripting skills are very basic so maybe I do something completely wrong, but I need to figure this out.
    Please help me!
    Thanks a lot,

    Stefan
     
  2. eriQue

    eriQue

    Unity Technologies

    Joined:
    May 25, 2010
    Posts:
    595
    Application.dataPath should never be used for write access. The reason for this is simple: Application.dataPath points to the actual .apk (which essentially is a .zip file). (I would actually argue that Application.dataPath should not be used for write access on any platform, for various reasons.)

    Write access to sd-card is possible just as you described, but as you see you get an UnauthorizedAccessException. The reason for this is that sd-card access is controlled by the manifest permissions. The default manifest created by Unity does not include the android.permission.WRITE_EXTERNAL_STORAGE which enables sd-card access. If you override the manifest you can add this permission yourself.

    With Unity 3.2 we added a check-box to control this more easily.
     
    KainAsylum likes this.
  3. stefann

    stefann

    Joined:
    Jan 4, 2011
    Posts:
    17
    Thank you very much for your answer. I tried to change the manifest and was able to save the .png to the SD card. This was my preferred method anyway. I'm looking forward to work with 3.2. Seems to bring a lot of improvements!

    Stefan
     
  4. ohan

    ohan

    Joined:
    Jan 9, 2011
    Posts:
    1
    I have the same problem for writing/reading in files.

    How do we override the manifest file in Unity? Where is the manifest file used for build .apk stored in the Unity hierarchy?

    Thanks
    Ohan
     
  5. eriQue

    eriQue

    Unity Technologies

    Joined:
    May 25, 2010
    Posts:
    595
    By using the plugin mechanism. Basically you save your AndroidManifest.xml in the Assets/Plugins/Android folder of your project.
     
  6. kablammyman

    kablammyman

    Joined:
    Nov 22, 2010
    Posts:
    507
    Hmmm, I added this line to my manifest: (located in Assets/Plugins/Android)

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    yet, I still get the same access denied message. This is driving me nuts! anybody have any ideas?

    never mind. I learned that you cant try to access the sdcard while the phone is still plugged in to the pc via usb.
     
    Last edited: Feb 3, 2011
  7. bernardfrancois

    bernardfrancois

    Joined:
    Oct 29, 2009
    Posts:
    373
    grange_nathan likes this.
  8. eriQue

    eriQue

    Unity Technologies

    Joined:
    May 25, 2010
    Posts:
    595
    It's recommended to use Application.persistentDataPath on all platforms.
    Using .dataPath on Windows will output files next to the binaries which is usually not what you want; instead you want it tied to the current user.
    In Unity 3.3, on iPhone .persistentDataPath and concat'ing "Documents" to .dataPath should result in the same thing, thus making the string juggling unnecessary.
    Ultimately Application.persistentDataPath should do the best thing on all platforms, which removes the need of having #ifdefs in the code.
     
    kthrose and KainAsylum like this.
  9. bernardfrancois

    bernardfrancois

    Joined:
    Oct 29, 2009
    Posts:
    373
    Thanks, erique. We've updated to 3.3 and now it works with Application.persistentDataPath on all platforms!

    I'll update the blog post.
     
  10. Cawas

    Cawas

    Joined:
    Jan 14, 2010
    Posts:
    121
    This is all great legacy info... But would any of you know how to save image files into both iOS and Android's DCIM or ScreenCapture folder?

    From my point of view, Application.CaptureScreenshot should already do that by default. But, even on Unity4, it doesn't. Can we fix it?
     
  11. eriQue

    eriQue

    Unity Technologies

    Joined:
    May 25, 2010
    Posts:
    595
    I doubt that all developers want their screenshots showing up in the DCIM/Camera folder ;)
    If you want them to show up there, just move the file after Application.CaptureScreenshot is done.
     
  12. Abza1989

    Abza1989

    Joined:
    Jul 17, 2012
    Posts:
    47
    Hi I have been following this post and have already done all the necessary steps to get my image into the DCIM/Camera folder but when i go to my Gallery and have a look at the pictures in there my downloaded image is not there however if i use the ES Explorer and navigate to DCIM/Camera the image is there. Where do i need to place the image so that users without ES Explorer can view the image directly from the gallery.

    Thanks in Advance.
     
  13. ScorpionDeity

    ScorpionDeity

    Joined:
    Sep 19, 2012
    Posts:
    38
    Have you figured this out by chance? Or can anyone answer this? I'm having the same issue. I want to be able to save an image file, not directly into the gallery folder, but a folder that is at least easy for the user to find on Android. I can save the file fine, but it's only visible via ES Explorer and not the standard file explorer.

    EDIT: Actually, a couple things going on here. ES Explorer is being deceiving. What's happening is that the file is actually being stored under "Device Storage", not the SDCARD. ES Explorer is showing the folder/file from the device storage as a whole, but it makes it look like it's on the SDCARD because ES Explorer indicates /sdcard/ as it's browsing directory. So. That said, the folder/file shows fine with file explorer, but still working on getting it to be created on the SDCARD, not the device storage. I've already added the WRITE_EXTERNAL_STORAGE, but still a no-go. I'll update this post if I find the final answer.

    Scorp
     
    Last edited: Jun 17, 2013
unityunity