In my android application, I am trying to create the following folder on the sdcard:
/mnt/sdcard/OSGiComponents/admin/felix-cache/
Here's the code:
File cacheDir =
new File( Environment.getExternalStorageDirectory().getAbsolutePath() +
"/OSGiComponents/admin/felix-cache/" );
// Create the folder
cacheDir.mkdirs();
// Check if it exists
if ( ! cacheDir.exists() ) {
Log.e ( "Debug" , "Cache directory cannot be created" );
}
I have the WRITE_STORAGE_PERMISSION under the manifest tag of the android manifest file. I am able to create other folders and files without problem on the sdcard. The app works fine on the following phones:
However on Samsung Galaxy Nexus phone (unrooted) running Ice Cream Sandwich (4.0.4), the directory is created as a zero size file, which can be seen in Astro. The exists() call returns false.
I suspect it is a permissions problem, but I not sure what it is, and why a 0 byte file is created while exists() returns false. Nowhere else in the code am I creating this file.
Any suggestions on what could be the problem?
Thanks :)
UPDATE: I think I have identified the issue, please see the answer I posted.
I found a workaround which solves this problem. Whenever I am deleting a file/directory, instead of using delete() directly, I rename the file/folder, and then delete() it. This weird workaround seems to remove the problem.
I got this idea by seeing this question's answers - Open failed EBUSY device or Resource busy
However, I'm not sure why this works, or what caused the problem in the first place.
In case anyone else is using Felix on Galaxy Nexus and encounters the same problem, just change the Felix source code as shown below:
org.apache.felix.framework.util.SecureAction.java:
public boolean deleteFile(File target)
{
if (System.getSecurityManager() != null)
{
try
{
Actions actions = (Actions) m_actions.get();
actions.set(Actions.DELETE_FILE_ACTION, target);
return ((Boolean) AccessController.doPrivileged(actions, m_acc))
.booleanValue();
}
catch (PrivilegedActionException ex)
{
throw (RuntimeException) ex.getException();
}
}
else
{
// Solution: Rename before deleting
// https://stackoverflow.com/questions/11539657/open-failed-ebusy-device-or-resource-busy
File to = new File(target.getAbsolutePath() + System.currentTimeMillis());
boolean renameStatus = target.renameTo(to);
boolean deleteStatus = to.delete();
boolean returnStatus = ( renameStatus && deleteStatus );
// Debug SecureAction
//boolean returnStatus = target.delete();
Log.e ( "SecureAction" , "Deleting " + target + " delete(): " + returnStatus );
return returnStatus;
}
}