在我的Android应用程序中,我正在尝试在SD卡上创建以下文件夹:
/mnt/sdcard/OSGiComponents/admin/felix-cache/
以下是代码:
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" );
}
我在android清单文件的manifest标签下有WRITE_STORAGE_PERMISSION。我能够在SD卡上创建其他文件夹和文件而不会出现问题。 该应用程序适用于以下手机:
然而,在运行Ice Cream Sandwich(4.0.4)的三星Galaxy Nexus手机(无根)上,该目录被创建为零大小的文件,可以在Astro中看到。 exists()调用返回false。
我怀疑这是一个权限问题,但我不确定它是什么,以及为什么创建0字节文件而exists()返回false。我在代码中没有其他地方创建这个文件。
关于可能出现什么问题的任何建议?
谢谢:)
更新:我想我已经确定了问题,请参阅我发布的答案。
答案 0 :(得分:2)
请代替
使用 File cacheDir = new File( Environment.getExternalStorageDirectory().getAbsolutePath() +
"/OSGiComponents/admin/felix-cache/" );
cacheDir.mkdirs();
到
File cacheDir =
new File( Environment.getExternalStorageDirectory().getAbsolutePath() +
"/OSGiComponents/admin/felix-cache" );
cacheDir.mkdir();
答案 1 :(得分:2)
我找到了解决此问题的解决方法。每当我删除文件/目录,而不是直接使用delete(),我重命名文件/文件夹,然后删除()它。这种奇怪的解决方法似乎消除了这个问题。
我通过看到这个问题的答案得到了这个想法 - Open failed EBUSY device or Resource busy
但是,我不确定为什么会这样,或者首先导致问题的原因。
如果其他人在Galaxy Nexus上使用Felix并遇到同样的问题,只需更改Felix源代码,如下所示:
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;
}
}
答案 2 :(得分:1)
我建议您使用adb
连接到设备并使用目录中的ls -l
命令来检查有关此0 size file
的操作系统报告(权限等) 。这最终可以为这个问题带来一些启示。
如果您无法找到可行的解决方案,也许您可以使用exec()
直接执行mkdir
。
您可以使用cobe bellow来执行此操作:
public static boolean execCmd(String command, ArrayList<String> results){
Process process;
try {
process = Runtime.getRuntime().exec(new String [] {"sh", "-c", command});
} catch (IOException e) {
e.printStackTrace();
return false;
}
int result;
try {
result = process.waitFor();
} catch (InterruptedException e1) {
e1.printStackTrace();
return false;
}
if(result != 0){ //error executing command
Log.d("execCmd", "result code : " + result);
String line;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
try {
while ((line = bufferedReader.readLine()) != null){
if(results != null) results.add(line);
Log.d("execCmd", "Error: " + line);
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return false;
}
//Command execution is OK
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
try {
while ((line = bufferedReader.readLine()) != null){
if(results != null) results.add(line);
Log.d("execCmd", line);
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
使用它:
boolean res= execCmd("mkdir "+ Environment.getExternalStorageDirectory().getAbsolutePath() + "/OSGiComponents", results);
if(!res) return error;
res= execCmd("mkdir "+ Environment.getExternalStorageDirectory().getAbsolutePath() + "/OSGiComponents/admin", results);
if(!res) return error;
res= execCmd("mkdir "+ Environment.getExternalStorageDirectory().getAbsolutePath() + "/OSGiComponents/admin/felix-cache", results);
if(!res) return error;
问候。
答案 3 :(得分:1)
String root = Environment.getExternalStorageDirectory()
.getAbsolutePath()+"/OSGiComponents/admin/felix-cache";
File myDir = new File(root);
String fname = "Image Name as you want";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
答案 4 :(得分:0)
虽然不能直接回答您的问题,但下面提到的信息可能会对您有所帮助:
在某些设备中,Environment.getExternalStorageDirectory().getAbsolutePath()
无需反映实际的外部SD卡路径。有时它代表内部存储。
例如在Galaxy Note 2中:
Log.i(TAG,Environment.getExternalStorageDirectory().getAbsolutePath());
将打印
12-19 17:35:11.366: E / sample.Examples(10420):/ storage / sdcard0
同时实际的外部SD卡应该是:
/存储/ extSdCard
以下是有关此问题的几篇帖子,可能对您有所帮助:
Building a Utility to get the path to External Removable storage every time
Check if the SDCard is present, boolean is always true
How could i get the correct external storage on Samsung and all other devices?
Android how to use Environment.getExternalStorageDirectory()