I use the following code to create some temp files, and wrapped tem as inputsteam to send to client side.
I understand that the temp files can be deleted automatically b
Try Using WorkManager to make sure it cleans up the temp files even after the app is closed.
override fun doWork(): Result {
return try {
applicationContext.cacheDir?.let {
if(it.exists()){
val entries = it.listFiles()
if (entries != null){
for (entry in entries) {
Timber.i("My file: ${entry.name}")
entry.delete()
}
}
}
}
Result.success()
} catch (e: Exception) {
Timber.e(e)
Result.failure()
}
}
Delete the files in onDestroy
if isChangingConfigurations()
is false
or isFinishing
is true
. Example:
@Override protected void onDestroy() {
super.onDestroy();
if(!isChangingConfigurations()) {
deleteTempFiles(getCacheDir());
}
}
private boolean deleteTempFiles(File file) {
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
for (File f : files) {
if (f.isDirectory()) {
deleteTempFiles(f);
} else {
f.delete();
}
}
}
}
return file.delete();
}
It would be better if you can maintain a Set (Avoid Duplicates) for all files you create.
And iterate the file list and delete every file one by one.
public static final Set<String> TMP_FILES = new HashSet<>();
And delete all by iterating.
public void deleteTempFiles() {
for(String myTempFile: TMP_FILES) {
try {
new File(myTempFile).delete();
} catch (Exception e) {
// Handle if needed.
}
}
}
call the deleteOnExit() method!
Or
call the delete() method in the onStop()
of your activity.
Edit:
It might be better if you called delete() in onDestroy()
to insure that your code works even if app is destroyed by system.
First, keep in mind that "exit" for an Android app means something very different than it does for a desktop application. See this article for details, but the short answer is that, in general, you have no idea when the OS is actually going to close your app (even if it's not visible). In fact, there isn't an explicit guarantee that the OS will close it at all.
A few ideas can be found here (it's C#/Xamarin.Android but same exact idea for Java): How to detect application exit on android?
In addition to the stuff listed there, you could also try registering broadcast receivers for when the phone's shutting down.
Another (worse, in my opinion) way is to simply do this when the app becomes no longer visible (in onStop
). As noted above, however, this isn't the same thing as the program actually closing (because you don't know when - or even if - the OS will actually close the app).
I ended up here looking for a way to remove temp files that I was creating for camera intents, I actually used a combination of Sridhar's answer and the cleanOldFiles
function from this answer
I was creating a new image file using createTempFile
and then adding that to
public static final HashSet<File> TEMP_FILES = new HashSet<>();
To iterate and remove from the set using the normal foreach loop was throwing a java.util.ConcurrentModificationException
so I updated the loop using an Iterator
more on iterators
Thought I'd post in case it helps someone else, thanks to Sridhar and ggrandes from the other post for the help.
public synchronized void cleanTempFiles(final int secondsOld) {
long now = (System.currentTimeMillis() / 1000);
for (Iterator<File> iterator = TEMP_FILES.iterator(); iterator.hasNext(); ) {
File f = iterator.next();
long expired = (f.lastModified() / 1000) + secondsOld;
if (now >= expired) {
Log.d(TAG, "Deleted file - \"" + f.getAbsolutePath() +"\"");
f.delete();
iterator.remove();
}
}
}
The function removes files older than a given time value in seconds and is called like
cleanTempFiles(3); // or however long