In my app, I store the user’s app data using MySQLite databases, and I allow the user to backup the app data to the SD card within a folder that I create on the SD card (let’s call it MyAppFolder). On Android devices that have only a single SD card slot, everything works fine (e.g. my Droid).
However, on devices such as the Galaxy S that have more than 1 SD card, things don’t work. Unfortunately, I don’t actually have one of these devices, so I can’t debug anything, I can only go by user reports. I also did some searching and found this is a known issue. However, I did not find any solutions that didn’t involve just hardcoding the other paths that get used, so I’m looking for some help with that.
In my app, I check and see if MyAppFolder already exists. If not, I create that folder. The folder is always created successfully, although it is created on the “internal” memory slot returned by getExternalStorageDirectory() when there are 2 slots present. However, the files do not get created and copied there. I don’t understand why the folder is created, but the files are not created.
Can someone tell me how I can modify this code to work for devices with 2 card slots as well as 1 card slot? I’d prefer not to hard-code locations to check, but if that’s the only way, I’ll do it just to get things working.
Here is the code I use(slightly modified to make more readable here):
File root = Environment.getExternalStorageDirectory();
String state = Environment.getExternalStorageState();
if( Environment.MEDIA_MOUNTED.equals(state))
{
File dataDirectory = Environment.getDataDirectory();
if (root.canWrite())
{
String savePath = root + "/MyAppFolder/";
File directory = new File(savePath);
if( !directory.exists() )
{
directory.mkdirs(); //folder created successfully
}
String currentDBPath = "\\data\\my_app\\databases\\database.db";
File currentDB = new File(datDirectory, currentDBPath);
File backupDB = new File(savePath, "database.db");
if (currentDB.exists())
{
FileChannel src = new FileInputStream(currentDB[i]).getChannel();
FileChannel dst = new FileOutputStream(backupDB[i]).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
}
“External storage” does not mean “removable storage”. “External storage” means “mountable storage” — IOW, the user has access to that storage when they plug their device into a host machine via a USB cable.
Android, at present, is designed to allow developers to write things to one external storage point, and it is up to the device manufacturer whether that is fixed flash or something removable. Hence, you should be backing things up to external storage, not thinking that you are backing things up to an SD card.
Use
getDatabasePath()to get a database path, rather than the gyrations you are presently going through. Never use concatenation to create paths, the way you are withroot + "/MyAppFolder/"— use aFileconstructor, as you are elsewhere. Make sure you hold theWRITE_EXTERNAL_STORAGEpermission. Beyond that, this should work fine for any device with sufficient external storage to hold your database, regardless of how many “card slots” the device may have.