Saturday, January 15, 2011

How to write a file to Android filesystem using Adobe AIR

The other night I ended up banging my head against the wall wondering why I couldn't write a file (or even create a directory for that matter) to my Samsung Galaxy S filesystem using a Flex application running on Adobe AIR.


The code was simple enough and apparently the code should have worked on my mobile without any additional changes.  However, when things didn't work I was left stumped.


The code:
 private function saveFile() : void {  
      var myFile:File = File.documentsDirectory.resolvePath("Test Folder/test.txt");  
      var fs:FileStream = new FileStream();  
      fs.open(myFile,FileMode.WRITE);  
      fs.writeUTFBytes("blah blah");  
      fs.close();  
  }  


Using the code above nothing was written to the filesystem.  WTF?? I tried to figure out the paths of the special directories to see if was trying to write the file in a weird directory somewhere.  


The debug code below:
 debugText += File.applicationDirectory.nativePath + "\n";  
 debugText += File.applicationStorageDirectory.nativePath + "\n";  
 debugText += File.documentsDirectory.nativePath + "\n";  
 debugText += File.userDirectory.nativePath + "\n";  
resulted in the following output:

    /data/data/air.TestApp.debug/TestApp.debug/Local Store
   /mnt/sdcard
   /mnt/sdcard
   /


So it should have correctly written to the internal SD card on my Galaxy S but there wasn't a file or directory in sight.  The next thing I tried to do was create a directory using the code below, while checking for any errors.


 var file:File = File.documentsDirectory.resolvePath("Test Folder");  
 try {  
      file.createDirectory();  
 } catch (e:Error) {  
      debugText += e.message;  
 }  

This resulted in "error #3001" which means "File or directory access denied."
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/runtimeErrors.html

Why was access being denied since the "/mnt/sdcard/" folder had read and write access? The answer lied in the security permissions for an android application as described on the android developer guide.
http://developer.android.com/guide/topics/security/security.html

By default, an android application doesn't have permission to write to external storage so in order to write to my Samsung Galaxy S's internal SD card ("/mnt/sdcard/") I needed to set the WRITE_EXTERNAL_STORAGE permission to my applications XML descriptor file ("TestApp-app.xml").

 <android>  
   <manifestAdditions><![CDATA[  
      <manifest>  
           <!-- See the Adobe AIR documentation for more information about setting    Google Android permissions -->  
           ...  
         ...  
           <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  
         ...  
         ...  
      </manifest>  
 ]]></manifestAdditions>  
  </android>  


After adding this line everything worked like a charm.  Such relief.



18 comments:

  1. omg, thank you very much for this :D

    ReplyDelete
  2. You may also get this error if you're debugging your app on your device. This is because when your phone is mounted you no longer have access to the sdcard. Solution: unplug your device ;P

    ReplyDelete
    Replies
    1. Very true! Make sure to unplug!

      Delete
    2. Also to add permissions without messing with the manifest, if you are developing with Flash, is to set your permissions in the settings of you AIR for Android project in the properties section. You can set a whole bunch of permissions and it will edit the manifest itself.

      Delete
  3. How can the above code be modified for reading a file.
    -S

    ReplyDelete
  4. This is a how I read a file:

    var fileStream:FileStream = new FileStream();
    fileStream.open(new File(filePath), FileMode.READ);
    var fileData:String = fileStream.readUTFBytes(fileStream.bytesAvailable);
    fileStream.close();

    Hope it helps.

    ReplyDelete
  5. To debug on your phone and not get this error, make sure you are just charging your phone. So go under USB connection in the alert bar and set to charging only. This will allow it to write to the SD Card.

    ReplyDelete
  6. How would I use this to save an already present file (soundboard app) to the phone's SD?

    ReplyDelete
  7. Thanks my frnd..
    I have issue.I can't write to file which is on external sd card not on internal sd card. i got error "File or directory access denied."
    I already set permission

    but still it shows me this error.
    Please help me.

    ReplyDelete
  8. I have the external permission, and writing directly to the File.documentsDirectory works. However, when I try this on a subfolder on the sdcard, I get the access denied error. Any ideas?

    I tried unplugging the USB as mentioned above but it didn't help

    ReplyDelete
  9. Hi,
    I want to download video from the url and save to sd card.
    Can you tell me is that possible ?
    does file.save method will work ?

    Thankspratik

    ReplyDelete
  10. Thank you for such a very good tips. It will help a lot.
    Adobe Support

    ReplyDelete
  11. Simplest way, install this free file browser and navigate to your sdcard. You will read path on the top. In my case path was: storage/extsd/extsd01/

    https://play.google.com/store/apps/details?id=com.smartwho.SmartFileManager

    ReplyDelete
  12. Hello Friends, Use this magnificent converter for aif file, mov file, or mp4 file,

    Unique Converter

    ReplyDelete