81

I would like my app to archive the application DB to the SD card. In my code I check if the directory canWrite() exists, and if not, throw an IOException. In this particular instance, I am trying to copy the db file to the root directory on the SD card, but it's throwing an IOException. How can I change the permission on a folder/file to be able to write to it?

Mark Bertenshaw
  • 5,594
  • 2
  • 27
  • 40
bugzy
  • 7,086
  • 9
  • 42
  • 44

2 Answers2

210

You're right that the SD Card directory is /sdcard but you shouldn't be hard coding it. Instead, make a call to Environment.getExternalStorageDirectory() to get the directory:

File sdDir = Environment.getExternalStorageDirectory();

If you haven't done so already, you will need to give your app the correct permission to write to the SD Card by adding the line below to your Manifest:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
JPM
  • 9,077
  • 13
  • 78
  • 137
David Webb
  • 190,537
  • 57
  • 313
  • 299
  • Thanks...I will change my code as per your suggestion. However currently I have it hard coded, and do not have the permission set in the manifest file but it allows me to save it to the sd card anyway. why am I able to save it wothout having the permission set? – bugzy Feb 08 '10 at 16:34
  • 4
    @user244190 - my guess would be that your phone is running Android 1.5. `WRITE_EXTERNAL_STORAGE` was introduced in 1.6, so you'll need to include it in your application if you want it to be forward-compatible. – David Webb Feb 08 '10 at 16:38
  • @DaveWebb : please see my question here :http://stackoverflow.com/questions/9351904/cannot-write-to-sdcard-in-android-emulator – Saher Ahwal Feb 21 '12 at 07:21
  • No one has responded and I don't know why is that not working. – Saher Ahwal Feb 21 '12 at 07:21
  • @DaveWebb - right idea, but it's probably not that the phone is running 1.5 but rather that the app specifies it was built against 1.5 or (more commonly) does not specify a version at all, and when a more recent phone sees that it adds the permission for backwards compatibility. – Chris Stratton Mar 14 '14 at 20:39
1

The suggested technique above in Dave's answer is certainly a good design practice, and yes ultimately the required permission must be set in the AndroidManifest.xml file to access the external storage.

However, the Mono-esque way to add most (if not all, not sure) "manifest options" is through the attributes of the class implementing the activity (or service).

The Visual Studio Mono plugin automatically generates the manifest, so its best not to manually tamper with it (I'm sure there are cases where there is no other option).

For example:

[Activity(Label="MonoDroid App", MainLauncher=true, Permission="android.permission.WRITE_EXTERNAL_STORAGE")]
public class MonoActivity : Activity
{
  protected override void OnCreate(Bundle bindle)
  {
    base.OnCreate(bindle);
  }
}
samus
  • 6,102
  • 6
  • 31
  • 69
  • Actually, I see now that this WRITE_EXTERNAL_STORAGE setting is a user-permission, and if set the way it is above, will appear as a activity setting (android:permission) and not a user-permission in the manifest file. Oh, I just remembered, you set the user-permissions user the project properties in VS (its a checkbox list of all the permissions). – samus Aug 22 '12 at 19:18
  • 1
    They are actually "uses-permission" tags, not "user-permission", but aside from that everything else holds true. – samus Aug 22 '12 at 20:06
  • One thing that is absolutely necessary is to call if (Build.VERSION.SDK_INT >= 19) { MainActivity.get().getExternalFilesDirs(null); } // To get access to SD/Android/data/your.package.name // Do not attempt to create the package dir yourself. Not making this call results in mkdir or mkdirs failing to work. – pstorli Jan 05 '18 at 22:54