Hi friend thanks for previous replies,
i am facing problem in removing cache and temp files/folders,
what i require is to clean the whole device temp files and cache from one app which is mine app
but here i am able to clean only my apps cache , here is my code
private void mAppMethod(List<App> mApps) {
// TODO Auto-generated method stub
// File f = g
for (int i = 0; i < mApps.size(); i++) {
File dir = new File("/data/data/"+mApps.get(i).getPackageName().concat("/cache"));
Log.e("dir "+dir, "is directory "+dir.isDirectory());
int j = clearCacheFolder(dir, 10);
if (dir!= null && dir.isDirectory())
Log.e("j", "rff "+dir.delete());
System.out.println(j+" rff "+dir.delete());
}
and my clear cache method as under
static int clearCacheFolder(final File dir, final int numDays) {
int deletedFiles = 0;
if (dir!= null && dir.isDirectory()) {
// System.out.println("here"+dir.delete());
Log.e("here", "here "+dir.isDirectory());
try {
Log.e("here1", "here1"+dir.listFiles());
for (File child:dir.listFiles()) {
Log.e("here11", "here11");
//first delete subdirectories recursively
if (child.isDirectory()) {
Log.e("here111", "here111");
deletedFiles += clearCacheFolder(child, numDays);
Log.e("here1111", "here1111");
}
Log.e("here11111", "here11111");
//then delete the files and subdirectories in this dir
//only empty directories can be deleted, so subdirs have been done first
if (child.lastModified() < new Date().getTime() - numDays * DateUtils.DAY_IN_MILLIS) {
Log.e("here111111", "here111111");
if (child.delete()) {
Log.e("here1111111", "here1111111");
deletedFiles++;
Log.e("here11111111", "here11111111");
}
}
}
}
catch(Exception e) {
Log.e("TAG", String.format("Failed to clean the cache, error %s", e.getMessage()));
}
}
return deletedFiles;
}
please help how can i clear the whole device cache,here i am getting every apps cache location i.e. dir to cache of all apps in device but when i want to delete them it returns false
please help any help is appreciable
i am able to clear cache of one app which is the one i am running this code but not for other apps
thanks in advance
Try with this code
public void clearApplicationData() {
File cache = getCacheDir();
File appDir = new File(cache.getParent());
if(appDir.exists()){
String[] children = appDir.list();
for(String s : children){
if(!s.equals("lib")){
deleteDir(new File(appDir, s));
Log.i("TAG", "**************** File /data/data/APP_PACKAGE/" + s +" DELETED *******************");
}
}
}
}
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;
}
}
}
return dir.delete();
}
This will delete your all data,and cache files in the application.
Let me get this out of the way; I am a beginner to java, I research the code I need and try to learn it while using it in my app.
I am currently stuck, not really sure how I can continue, ANY help is greatly appreciated.
I am trying to look in the /mnt/ folder for any folder with 'ext' or 'sd' in the file name. This is what I have so far, it gets me a null pointer exception but I don't know what variable is null.
public class MainActivity extends Activity
{
static File[] dirs;
#Override
public void onCreate(Bundle savedInstanceState)
{
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findMnt("/mnt/");
AlertDialog builder = new AlertDialog.Builder(this).setTitle("AppName").setMessage(dirs[0].getPath()).setNeutralButton("Close", null).show();
AlertDialog builder2 = new AlertDialog.Builder(this).setTitle("AppName").setMessage(dirs[1].getPath()).setNeutralButton("Close", null).show();
}
public static void findMnt(String path) {
File file = new File(path);
if(file.exists()){
File[] list = file.listFiles();
for(int i=0; i<list.length; i++) {
if(list[i].isDirectory()) {
if(list[i].getPath().contains("sd") || list[i].getPath().contains("ext")){
for(int b=0; b<list.length; b++){
dirs[b] = new File(list[i].getPath());
}
}
}
}
}
}
Memory Cases: if you take any new device or for ex. micromax funbook, then its having three memory
/data/data/ (phone internal memory) getFilesDirectory()
/mnt/sdcard/ (phone's internal sdcard)
Environment.getExternalStorageDirectory()
/mnt/extsd/ (External sdcard) /mnt/extsd
You first need to be sure whether your External card is of /mnt/sdcard/ or /mnt/extSd for that I have created a function
/**
* #return Number of bytes available on external storage extSD
*/
public long getExternalAvailableSpaceInBytes() {
long availableSpace = -1L;
try {
StatFs stat = new StatFs("mnt/extsd");
System.out.println("ExternalAvailableSpace Path : "+mStringExernalSD);
availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
} catch (Exception e) {
e.printStackTrace();
}
return availableSpace;
}
if getExternalAvailableSpaceInBytes() returns 0 it means you need to consider /mnt/sd
To get all folders
ArrayList<File> mFiles= new ArrayList<File>();
if(getExternalAvailableSpaceInBytes()>0)
findMnt(mFiles, "/mnt/extsd");
else
findMnt(mFiles, "/mnt/sdcard");
public ArrayList<File> findMnt(ArrayList<File> files, File dir)
{
if (!dir.isDirectory())
{
files.add(dir);
return files;
}
for (File file : dir.listFiles())
findMnt(files, file);
return files;
}
This method is crude but will work for what I need it to. Searches for the sdcard folder, then searches for a folder with ext in the name, and if it fails it searches the sdcard folder for an ext folder.
String sd = findSd("/mnt/") + "/";
String ext = findExt("/mnt/") + "/";
if(ext == "ext not found"){
ext = findExt(sd + "/");
}
public static String findSd(String path){
File file = new File(path);
if(file.exists()){
File[] list = file.listFiles();
for(int i=0; i<list.length; i++) {
if(list[i].isDirectory()) {
if(list[i].getPath().contains("sd")){
return list[i].getPath();
}
}
}
}
return "sd not found";
}
public static String findExt(String path){
File file = new File(path);
if(file.exists()){
File[] list = file.listFiles();
for(int i=0; i<list.length; i++) {
if(list[i].isDirectory()) {
if(list[i].getPath().contains("ext") && list[i].getPath() != findSd("/mnt/")){
return list[i].getPath();
}
}
}
}
return "ext not found";
}
I tried File.delete() but it doesn't work. How to delete a directory on SD card?
I'm working on Android 2.1.
You have to have all the directory empty before deleting the directory itself, see here
In Android, you should have the proper permissions as well - WRITE_EXTERNAL_STORAGE in your manifest.
EDIT: for convenience I copied the code here, but it is still from the link above
public static boolean deleteDirectory(File path) {
if( path.exists() ) {
File[] files = path.listFiles();
if (files == null) {
return true;
}
for(int i=0; i<files.length; i++) {
if(files[i].isDirectory()) {
deleteDirectory(files[i]);
}
else {
files[i].delete();
}
}
}
return( path.delete() );
}
https://stackoverflow.com/a/16411911/2397275
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
in AndroidManifest.xml file
it's worked fine for me, i hope it will work for you.
File dir = new File(Environment.getExternalStorageDirectory()+"DirName");
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
new File(dir, children[i]).delete();
}
}
Directories must be empty before they will be deleted. You have to recursively empty and delete all directories in the tree:
boolean delete(File file) {
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null)
for (File f : files) delete(f);
}
return file.delete();
}
Update:
It seems like file.isDirectory() == (file.listFiles() == null), but file.listFiles() logs "fail readDirectory() errno=20" when file.isDirectory() == false.
It worked for me:
Add in manifest-
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
private boolean deleteDirectory(File path) {
if( path.exists() ) {
File[] files = path.listFiles();
if (files == null) {
return false;
}
for(File file : files) {
if(file.isDirectory()) {
deleteDirectory(file);
}
else {
file.delete();
}
}
}
return path.exists()?path.delete():false;
}
I want the users of my application to be able to delete the DCIM folder (which is located on the SD card and contains subfolders).
Is this possible, if so how?
You can delete files and folders recursively like this:
void deleteRecursive(File fileOrDirectory) {
if (fileOrDirectory.isDirectory())
for (File child : fileOrDirectory.listFiles())
deleteRecursive(child);
fileOrDirectory.delete();
}
Let me tell you first thing you cannot delete the DCIM folder because it is a system folder. As you delete it manually on phone it will delete the contents of that folder, but not the DCIM folder. You can delete its contents by using the method below:
Updated as per comments
File dir = new File(Environment.getExternalStorageDirectory()+"Dir_name_here");
if (dir.isDirectory())
{
String[] children = dir.list();
for (int i = 0; i < children.length; i++)
{
new File(dir, children[i]).delete();
}
}
We can use the command line arguments to delete a whole folder and its contents.
public static void deleteFiles(String path) {
File file = new File(path);
if (file.exists()) {
String deleteCmd = "rm -r " + path;
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec(deleteCmd);
} catch (IOException e) { }
}
}
Example usage of the above code:
deleteFiles("/sdcard/uploads/");
In Kotlin you can use deleteRecursively() extension from kotlin.io package
val someDir = File("/path/to/dir")
someDir.deleteRecursively()
Short koltin version
fun File.deleteDirectory(): Boolean {
return if (exists()) {
listFiles()?.forEach {
if (it.isDirectory) {
it.deleteDirectory()
} else {
it.delete()
}
}
delete()
} else false
}
UPDATE
Kotlin stdlib function
file.deleteRecursively()
use below method to delete entire main directory which contains files and it's sub directory. After calling this method once again call delete() directory of your main directory.
// For to Delete the directory inside list of files and inner Directory
public static boolean deleteDir(File dir) {
if (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();
}
Your approach is decent for a folder that only contains files, but if you are looking for a scenario that also contains subfolders then recursion is needed
Also you should capture the return value of the return to make sure you are allowed to delete the file
and include
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in your manifest
void DeleteRecursive(File dir)
{
Log.d("DeleteRecursive", "DELETEPREVIOUS TOP" + dir.getPath());
if (dir.isDirectory())
{
String[] children = dir.list();
for (int i = 0; i < children.length; i++)
{
File temp = new File(dir, children[i]);
if (temp.isDirectory())
{
Log.d("DeleteRecursive", "Recursive Call" + temp.getPath());
DeleteRecursive(temp);
}
else
{
Log.d("DeleteRecursive", "Delete File" + temp.getPath());
boolean b = temp.delete();
if (b == false)
{
Log.d("DeleteRecursive", "DELETE FAIL");
}
}
}
}
dir.delete();
}
There is a lot of answers, but I decided to add my own, because it's little different. It's based on OOP ;)
I created class DirectoryCleaner, which help me each time when I need to clean some directory.
public class DirectoryCleaner {
private final File mFile;
public DirectoryCleaner(File file) {
mFile = file;
}
public void clean() {
if (null == mFile || !mFile.exists() || !mFile.isDirectory()) return;
for (File file : mFile.listFiles()) {
delete(file);
}
}
private void delete(File file) {
if (file.isDirectory()) {
for (File child : file.listFiles()) {
delete(child);
}
}
file.delete();
}
}
It can be used to solve this problem in next way:
File dir = new File(Environment.getExternalStorageDirectory(), "your_directory_name");
new DirectoryCleaner(dir).clean();
dir.delete();
You can not delete the directory if it has subdirectories or files in Java. Try this two-line simple solution. This will delete the directory and contests inside the directory.
File dirName = new File("directory path");
FileUtils.deleteDirectory(dirName);
Add this line in gradle file and sync the project
compile 'org.apache.commons:commons-io:1.3.2'
According to the documentation:
If this abstract pathname does not denote a directory, then this method returns null.
So you should check if listFiles is null and only continue if it's not
boolean deleteDirectory(File path) {
if(path.exists()) {
File[] files = path.listFiles();
if (files == null) {
return false;
}
for (File file : files) {
if (file.isDirectory()) {
deleteDirectory(file);
} else {
boolean wasSuccessful = file.delete();
if (wasSuccessful) {
Log.i("Deleted ", "successfully");
}
}
}
}
return(path.delete());
}
If you dont need to delete things recursively you can try something like this:
File file = new File(context.getExternalFilesDir(null), "");
if (file != null && file.isDirectory()) {
File[] files = file.listFiles();
if(files != null) {
for(File f : files) {
f.delete();
}
}
}
public static void deleteDirectory( File dir )
{
if ( dir.isDirectory() )
{
String [] children = dir.list();
for ( int i = 0 ; i < children.length ; i ++ )
{
File child = new File( dir , children[i] );
if(child.isDirectory()){
deleteDirectory( child );
child.delete();
}else{
child.delete();
}
}
dir.delete();
}
}
see android.os.FileUtils, it's hide on API 21
public static boolean deleteContents(File dir) {
File[] files = dir.listFiles();
boolean success = true;
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
success &= deleteContents(file);
}
if (!file.delete()) {
Log.w("Failed to delete " + file);
success = false;
}
}
}
return success;
}
Source: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/FileUtils.java#414
The fastest and easiest way:
public static boolean deleteFolder(File removableFolder) {
File[] files = removableFolder.listFiles();
if (files != null && files.length > 0) {
for (File file : files) {
boolean success;
if (file.isDirectory())
success = deleteFolder(file);
else success = file.delete();
if (!success) return false;
}
}
return removableFolder.delete();
}
This is what I do... (terse and tested)
...
deleteDir(new File(dir_to_be_deleted));
...
// delete directory and contents
void deleteDir(File file) {
if (file.isDirectory())
for (String child : file.list())
deleteDir(new File(file, child));
file.delete(); // delete child file or empty directory
}
private static void deleteRecursive(File dir)
{
//Log.d("DeleteRecursive", "DELETEPREVIOUS TOP" + dir.getPath());
if (dir.isDirectory())
{
String[] children = dir.list();
for (int i = 0; i < children.length; i++)
{
File temp = new File(dir, children[i]);
deleteRecursive(temp);
}
}
if (dir.delete() == false)
{
Log.d("DeleteRecursive", "DELETE FAIL");
}
}
Simple way to delete all file from directory :
It is generic function for delete all images from directory by calling only
deleteAllImageFile(context);
public static void deleteAllFile(Context context) {
File directory = context.getExternalFilesDir(null);
if (directory.isDirectory()) {
for (String fileName: file.list()) {
new File(file,fileName).delete();
}
}
}
Safest code I know:
private boolean recursiveRemove(File file) {
if(file == null || !file.exists()) {
return false;
}
if(file.isDirectory()) {
File[] list = file.listFiles();
if(list != null) {
for(File item : list) {
recursiveRemove(item);
}
}
}
if(file.exists()) {
file.delete();
}
return !file.exists();
}
Checks the file exists, handles nulls, checks the directory was actually deleted
//To delete all the files of a specific folder & subfolder
public static void deleteFiles(File directory, Context c) {
try {
for (File file : directory.listFiles()) {
if (file.isFile()) {
final ContentResolver contentResolver = c.getContentResolver();
String canonicalPath;
try {
canonicalPath = file.getCanonicalPath();
} catch (IOException e) {
canonicalPath = file.getAbsolutePath();
}
final Uri uri = MediaStore.Files.getContentUri("external");
final int result = contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{canonicalPath});
if (result == 0) {
final String absolutePath = file.getAbsolutePath();
if (!absolutePath.equals(canonicalPath)) {
contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath});
}
}
if (file.exists()) {
file.delete();
if (file.exists()) {
try {
file.getCanonicalFile().delete();
} catch (IOException e) {
e.printStackTrace();
}
if (file.exists()) {
c.deleteFile(file.getName());
}
}
}
} else
deleteFiles(file, c);
}
} catch (Exception e) {
}
}
here is your solution it will also refresh the gallery as well.
This (Tries to delete all sub-files and sub-directories including the supplied directory):
If File, delete
If Empty Directory, delete
if Not Empty Directory, call delete again with sub-directory, repeat 1 to 3
example:
File externalDir = Environment.getExternalStorageDirectory()
Utils.deleteAll(externalDir); //BE CAREFUL.. Will try and delete ALL external storage files and directories
To gain access to External Storage Directory, you need the following permissions:
(Use ContextCompat.checkSelfPermission and ActivityCompat.requestPermissions)
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Recursive method:
public static boolean deleteAll(File file) {
if (file == null || !file.exists()) return false;
boolean success = true;
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null && files.length > 0) {
for (File f : files) {
if (f.isDirectory()) {
success &= deleteAll(f);
}
if (!f.delete()) {
Log.w("deleteAll", "Failed to delete " + f);
success = false;
}
}
} else {
if (!file.delete()) {
Log.w("deleteAll", "Failed to delete " + file);
success = false;
}
}
} else {
if (!file.delete()) {
Log.w("deleteAll", "Failed to delete " + file);
success = false;
}
}
return success;
}
Here is a non-recursive implementation, just for fun:
/**
* Deletes the given folder and all its files / subfolders.
* Is not implemented in a recursive way. The "Recursively" in the name stems from the filesystem command
* #param root The folder to delete recursively
*/
public static void deleteRecursively(final File root) {
LinkedList<File> deletionQueue = new LinkedList<>();
deletionQueue.add(root);
while(!deletionQueue.isEmpty()) {
final File toDelete = deletionQueue.removeFirst();
final File[] children = toDelete.listFiles();
if(children == null || children.length == 0) {
// This is either a file or an empty directory -> deletion possible
toDelete.delete();
} else {
// Add the children before the folder because they have to be deleted first
deletionQueue.addAll(Arrays.asList(children));
// Add the folder again because we can't delete it yet.
deletionQueue.addLast(toDelete);
}
}
}
I've put this one though its' paces it deletes a folder with any directory structure.
public int removeDirectory(final File folder) {
if(folder.isDirectory() == true) {
File[] folderContents = folder.listFiles();
int deletedFiles = 0;
if(folderContents.length == 0) {
if(folder.delete()) {
deletedFiles++;
return deletedFiles;
}
}
else if(folderContents.length > 0) {
do {
File lastFolder = folder;
File[] lastFolderContents = lastFolder.listFiles();
//This while loop finds the deepest path that does not contain any other folders
do {
for(File file : lastFolderContents) {
if(file.isDirectory()) {
lastFolder = file;
lastFolderContents = file.listFiles();
break;
}
else {
if(file.delete()) {
deletedFiles++;
}
else {
break;
}
}//End if(file.isDirectory())
}//End for(File file : folderContents)
} while(lastFolder.delete() == false);
deletedFiles++;
if(folder.exists() == false) {return deletedFiles;}
} while(folder.exists());
}
}
else {
return -1;
}
return 0;
}
Hope this helps.
Yet another (modern) way to solve it.
public class FileUtils {
public static void delete(File fileOrDirectory) {
if(fileOrDirectory != null && fileOrDirectory.exists()) {
if(fileOrDirectory.isDirectory() && fileOrDirectory.listFiles() != null) {
Arrays.stream(fileOrDirectory.listFiles())
.forEach(FileUtils::delete);
}
fileOrDirectory.delete();
}
}
}
On Android since API 26
public class FileUtils {
public static void delete(File fileOrDirectory) {
if(fileOrDirectory != null) {
delete(fileOrDirectory.toPath());
}
}
public static void delete(Path path) {
try {
if(Files.exists(path)) {
Files.walk(path)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
// .peek(System.out::println)
.forEach(File::delete);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I'm using this recursive function to do the job:
public static void deleteDirAndContents(#NonNull File mFile){
if (mFile.isDirectory() && mFile.listFiles() != null && mFile.listFiles().length > 0x0) {
for (File file : mFile.listFiles()) {
deleteDirAndContents(file);
}
} else {
mFile.delete();
}
}
The function checks if it is a directory or a file.
If it is a directory checks if it has child files, if it has child files will call herself again passing the children and repeating.
If it is a file it delete it.
(Don't use this function to clear the app cache by passing the cache dir because it will delete the cache dir too so the app will crash...
If you want to clear the cache you use this function that won't delete the dir you pass to it:
public static void deleteDirContents(#NonNull File mFile){
if (mFile.isDirectory() && mFile.listFiles() != null && mFile.listFiles().length > 0x0) {
for (File file : mFile.listFiles()) {
deleteDirAndContents(file);
}
}
}
or you can check if it is the cache dir using:
if (!mFile.getAbsolutePath().equals(context.getCacheDir().getAbsolutePath())) {
mFile.delete();
}
Example code to clear app cache:
public static void clearAppCache(Context context){
try {
File cache = context.getCacheDir();
FilesUtils.deleteDirContents(cache);
} catch (Exception e){
MyLogger.onException(TAG, e);
}
}
Bye, Have a nice day & coding :D
This is kotlin option. It worked very well.
fun executeDelete(context: Context, paths: List<String>): Int {
return try {
val files = paths.map { File(it) }
val fileCommands = files.joinToString(separator = " ") {
if (it.isDirectory) "'${it.absolutePath}/'" else "'${it.absolutePath}'"
}
val command = "rm -rf $fileCommands"
val process = Runtime.getRuntime().exec(arrayOf("sh", "-c", command))
val result = process.waitFor()
if (result == 0) {
context.rescanPaths(paths)
}
result
} catch (e: Exception) {
-1
}
}
// avoid calling this multiple times in row, it can delete whole folder contents
fun Context.rescanPaths(paths: List<String>, callback: (() -> Unit)? = null) {
if (paths.isEmpty()) {
callback?.invoke()
return
}
var cnt = paths.size
MediaScannerConnection.scanFile(applicationContext, paths.toTypedArray(), null) { _, _ ->
if (--cnt == 0) {
callback?.invoke()
}
}
}