I've the sequent trouble. My app should read a list of files and show their name to the user.
When the app is launched for the first time i need to create a specific folder for the app?
then how can i check if it's empty?
Assuming you created the directory in the internal storage, you can get the number of child objects in the directory like this
File dir = context.getDir("somePath", Context.MODE_PRIVATE);
File[] children = dir.listFiles();
if(children.length > 0)
{
// the directory is not empty
}
else
{
// the directory is empty.
}
This is just a quick sample code. The better way would be to exclude the self and parent aliases using a custom FileFilter with dir.listFiles(), as I'm not sure they will always be excluded from the resulting list.
The following code will check if a folder already exists and if not creates one and warns you if error creating one:
// check if appfolder is created and if not through an
// exception
File path = new File("yourDir");
if (!path.exists()) {
if (!path.mkdirs()) {
try {
throw new IOException(
"Application folder can not be created. Please check if your memory is writable and healthy and then try again.");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
} else {
Log.i("app", "directory is: " + path.getPath());
}
exists() checks if a path exists or not and path.exists() simply creates one for you.
Related
I'm making a video downloader app and I've got no problems saving and deleting files downloaded by the app to external storage but any file transfered from my computer cannot be deleted by the app.
This is a real problem as it's one of the key features I want. Here's the code I'm using:
public boolean deleteDataFromStorage(Data toDelete) {
//The file object soon to be deleted
File f = null;
Log.e(TAG, "Deleting " + toDelete.fileName);
// Delete file from storage
try {
// Get file to delete
f = new File(Environment.getExternalStorageDirectory().getCanonicalPath() + DIRECTORY + toDelete.fileName);
} catch (IOException e) {
Log.e(TAG, e.toString());
// Print to stack trace
e.printStackTrace();
}
// Delete file
if(f.delete()) {
return true;
} else {
Log.e(TAG, "Failed to delete " + toDelete.fileName);
return false;
}
}
As the f.delete() function doesn't throw any exceptions I have no idea what the problem is. The only thing I can think of is that the app doesn't have the permission to delete a file created in windows and yet I have downloaded apps from the app store that have no problem deleting transfered files.
Any help would be greatly appreciated.
As per your comment, since f.isFile() and f.exists() returns false, your f is not a file, in other words, you're getting the path wrong.
Print to the logs f.getAbsolutePath(), check what it is, and then it should be easy to fix.
A question, I'm making a app that will store a textfile (.txt) with highscore data. I've made a file with this line from my highscores activity:
File highscoreList = new File("highscores.txt");
Where will it be placed? In the same dir as the highscores.java file? Or, how should I specify a dir that will put the textfile in the same folder as highscores.java?
You should access your files using the Context methods openFileInput and openFileOutput. You can determine where they are actually stored using getFileStreamPath. (The directory they go in can be obtained with getFilesDir.) The advantage of using this method is that the files will be private to your application and will be removed automatically if your app is uninstalled.
In your activity, you can create your File with:
File highscoreList = getFileStreamPath("highscores.txt");
If all you want to do is write to it:
FileOutputStream output = null;
try {
output = openFileOutput("highscores.txt", MODE_PRIVATE);
// write to file
} finally {
if (output != null) {
try { output.close(); }
catch (IOException e) {
Log.w(LOG_TAG, "Error closing file!", e);
}
}
}
Similarly, for reading you can use:
FileInputStream input = openFileInput("highscores.txt");
If you are trying to access your file from outside an Activity subclass, you'll need a Context. (In a View, for instance, you can use getContext(). For a helper class, you'll need to pass in your Activity instance or some other Context object.)
I read through the Android documentation of the cache (see Data Storage Documentation) but I didn't got how I can clean the whole folder.
So how can I delete the cache-folder of my app? It's in this path:
/Android/data/de.stepforward/cache/
Put this code in onDestroy() to clear app cache:
void onDestroy() { super.onDestroy();
try {
trimCache(this);
// Toast.makeText(this,"onDestroy " ,Toast.LENGTH_LONG).show();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void trimCache(Context context) {
try {
File dir = context.getCacheDir();
if (dir != null && dir.isDirectory()) {
deleteDir(dir);
}
} catch (Exception e) {
// TODO: handle exception
}
}
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
// The directory is now empty so delete it
return dir.delete();
}
You can use the code referenced here:
https://stackoverflow.com/a/7600257/327011
File cacheDir = context.getCacheDir();
File[] files = cacheDir.listFiles();
if (files != null) {
for (File file : files)
file.delete();
}
Kotlin:
You can make use of File.deleteRecursively() from the standard library to remove all sub directories as well
To delete the whole cache directory of the app:
context.cacheDir.deleteRecursively()
To delete a specific directory in the cache including its sub directories
File(context.cacheDir, "child directory name").deleteRecursively()
Thanks for the suggestion #elyeante
Rather than rolling your own utility methods, you may want to consider using the apache commons FileUtils library. It contains a lot of useful File manipulation methods and makes operations like this very trivial.
Here are the JavaDocs
And here is an example:
try {
FileUtils.deleteDirectory(context.getCacheDir());
} catch (IOException e) {
Log.e(LOGTAG,"Error deleting cache dir", e);
}
Alternately, rather than deleting the whole cache directory, you may want to create subdirectories within the app's cache directory for specific data. Than you can delete those specific directories when required (e.g. on user logout).
From the documentation:
Saving cache files
If you'd like to cache some data, rather than store it persistently,
you should use getCacheDir() to open a File that represents the
internal directory where your application should save temporary cache
files.
When the device is low on internal storage space, Android may delete
these cache files to recover space. However, you should not rely on
the system to clean up these files for you. You should always maintain
the cache files yourself and stay within a reasonable limit of space
consumed, such as 1MB. When the user uninstalls your application,
these files are removed.
Create a method to recurse through the folder and delete them, if that's what you want to do.
I develop an app which collects some data from internet. Then save it to a temporary folder. To build this app I need to create and access a folder ( just for the purpose of app, not for the user). How can I do it?
this code is to create folder:
File direct = new File(Environment.getExternalStorageDirectory() + "/New Folder");
if(!direct.exists())
{
(direct.mkdir()) //directory is created;
}
try it may help you
File mFile;
onCreate()
mFile= new File(Environment.getExternalStorageDirectory()+"/temp/";
mFile.mkdir();
onDestroy();
mFile.delete();
try out this...
private void makeFolder(){
File root = new File(Environment.getExternalStorageDirectory()
+ File.separator + getString(R.string.folder_name));
boolean mainfolderexist = root.exists();
if (!mainfolderexist) {
try {
if (Environment.getExternalStorageDirectory().canWrite()) {
root.mkdirs();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
All The best
You should really check this other SO answer: https://stackoverflow.com/a/6485850/65716
Aside from the fact that you have to completely manage your use of the space, etc, caching on external storage requires more permission for your app.
See http://developer.android.com/reference/android/content/Context.html#getCacheDir()
"Apps require no extra permissions to read or write to the returned path, since this path lives in their private storage."
For app use only, I would recommend to use Context.getDir() for retrieving the directory if the files is used by our app only and don`t want to be visible to users by file browsers.
// No need to check if exist, created automatically.
File tempRoot = context.getDir("temp", Context.MODE_PRIVATE);
// do something
As described in android documentation, to create a new file which will be situated in the application's directory there is the method in Context class: openFileOutput().
But where will be the file situated if I use simple createNewFile() method from File class.?
CreateNewFile() is used like this:
File file = new File("data/data/your package name/test.txt");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
So you will tell the file where it should be created. Remember that you can only create new files on your package. That is "data/data/your package name/".
Somehow createNewFile() was not able to create the complete file path here on my devices.
try {
if (!futurePhotoFile.exists()) {
new File(futurePhotoFile.getParent()).mkdirs();
futurePhotoFile.createNewFile();
}
} catch (IOException e) {
Log.e("", "Could not create file.", e);
Crouton.showText(TaskDetailsActivity.this,
R.string.msgErrorNoSdCardAvailable, Style.ALERT);
return;
}
it will be stored in the current directory to which your classPath is pointing to
Depends on the path you pass to the File constructor. If the parent directory exists, and if you have the permission to write to it, of course.
Documentation of createNewFile() method says:
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist. The check for the existence of the file and the creation of the file if it does not exist are a single operation that is atomic with respect to all other filesystem activities that might affect the file.
Therefore we don't need to check existence of a file manually:
val dir = context.filesDir.absolutePath + "/someFolder/"
val logFile = File(dir + "log.txt")
try {
File(dir).mkdirs() // make sure to call mkdirs() when creating new directory
logFile.createNewFile()
} catch (e: Exception) {
e.printStackTrace()
}