sorting files based on its creation date in android - android

I want list of file based on my creation date.
When i updating any if images and trying to retrive all images,then orders are changed randomly.
Here is my code,
File[] files = parentDir.listFiles();
for (File file : files) {
// I am getting files here
}
Any help..

List<File> fileList = new ArrayList<File>();
Collections.sort(fileList, new Comparator<File>() {
#Override
public int compare(File file1, File file2) {
long k = file1.lastModified() - file2.lastModified();
if(k > 0){
return 1;
}else if(k == 0){
return 0;
}else{
return -1;
}
}
});

I want list of file based on my creation date.
As the two previous answers pointed out, you can sort the files according to the modification date:
file.lastModified()
But the modification date is updated e.g. in the instant of renaming a file. So, this won't work to represent the creation date.
Unfortunately, the creation date is not available, thus you need to rethink your basic strategy:
see an old answer of CommonsWare

Here is the code to sort the files according to the modification date as the creation date is not available.
File[] files = parentDir.listFiles();
Arrays.sort(files, new Comparator() {
public int compare(Object o1, Object o2) {
if (((File)o1).lastModified() > ((File)o2).lastModified()) {
return -1;
} else if (((File)o1).lastModified() < ((File)o2).lastModified()) {
return +1;
} else {
return 0;
}
}
});

try this may help you,
public static void main(String[] args) throws IOException {
File directory = new File(".");
// get just files, not directories
File[] files = directory.listFiles((FileFilter) FileFileFilter.FILE);
System.out.println("Default order");
displayFiles(files);
Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
System.out.println("\nLast Modified Ascending Order (LASTMODIFIED_COMPARATOR)");
displayFiles(files);
Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_REVERSE);
System.out.println("\nLast Modified Descending Order (LASTMODIFIED_REVERSE)");
displayFiles(files);
}
public static void displayFiles(File[] files) {
for (File file : files) {
System.out.printf("File: %-20s Last Modified:" + new Date(file.lastModified()) + "\n", file.getName());
}
}

In the Kotlin language it can be written like this:
private fun getListFiles(parentDir: File): MutableList<File> {
val inFiles: MutableList<File> = parentDir.listFiles().toMutableList()
inFiles.filter { it.extension == "jpg" }
inFiles.sortByDescending({ it.lastModified()})
return inFiles
}

guys If you are not able to resolve this LastModifiedFileComparator problem, Here is the solution I have found.
Step 1
Open app level build.gradle
and add dependency as below. To get updated version click here
implementation group: 'commons-io', name: 'commons-io', version: '2.0.1'
Step 2
If it did't work than Add mavenCentral() creating new repositories in your app level build.gradle
repositories{
mavenCentral()
}
dependencies {
//all implementation
That all It should work like charm, If not please refer here

1.add this to build.gradle :
implementation group: 'commons-io', name: 'commons-io', version: '2.4'
2.add code to activity :
File[] folderFiles = Files.listFiles();
// Sort files in ascending order base on last modification
Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
// Sort files in descending order base on last modification
Arrays.sort(folderFiles, LastModifiedFileComparator.LASTMODIFIED_REVERSE);

One quick and elegant way to sort array of files, by date of change is:
Arrays.sort(fileList, new Comparator<File>() {
#Override
public int compare(File f1, File f2) {
return Long.compare(f1.lastModified(), f2.lastModified());
// For descending
// return -Long.compare(f1.lastModified(), f2.lastModified());
}
});
To sort array of files, by name is:
Arrays.sort(fileList, new Comparator<File>() {
#Override
public int compare(File f1, File f2) {
return f1.compareTo(f2);
// For descending
// return -f1.compareTo(f2);
}
});

Related

listFiles() but ignore a subdirectory in Android

I need to get a list of files but ignore a particular subdirectory. For example here is a sample structure.
Content
->1
-->file_a.mp4
-->file_b.mp4
->2
-->file_c.mp4
-->file_d.mp4
->Bonus
-->1
--->file_e.mp4
--->file_f.mp4
I need to be able to get a list of files/directories that excludes the bonus directory.
I also need to separate list the files for the bonus directory, but I think that can be easily solved by using the normal method.
How do I perform a list files, but ignore a directory?
Here is my sample code that is going to return everything
final List<Boxset> boxsets = getCloudBoxsetsWithTrackData(context);
final File[] boxsetFiles = dir.listFiles();
if (boxsetFiles != null)
{
for (File subDir : boxsetFiles)
{
if (subDir.isDirectory())
{
for (Boxset boxset : boxsets)
{
if (subDir.getName().equalsIgnoreCase(String.valueOf(boxset.persistentId)))
{
DBHandler.getInstance(context).moveBoxsetToDeviceList(boxset);
DownloadLibrarian.getInstance(context).stopDownload(boxset);
}
}
}
}
}
You can make use of FileFilter to obtain a list of sub-directories that doesn't include Bonus
File[] nonBonusDirs = dir.listFiles(new FileFilter() {
#Override public boolean accept(File file) {
return file.isDirectory() && !file.getName().equalsIgnoreCase("bonus");
}
});
You can then obtain a list of all files not in the Bonus directory
List<File> filesNotInBonusDir = new ArrayList<>();
for (File directory : nonBonusDirs) {
filesNotInBonusDir.addAll(Arrays.asList(directory.listFiles()));
}
Though of course these shenanigans are much nicer in Kotlin thanks to flatMap ;)
val filesNotInBonusDir: List<File> = dir.listFiles()
.filter { it.isDirectory && !it.name.equals("bonus", ignoreCase = true) }
.flatMap { it.listFiles().toList() }

How to get all media files in /res/raw dynamically?

I want to initialize MediaPlayer instances for all of the soundfiles found in res/raw:
/res/raw/test1.mp3
/res/raw/test2.mp3
/res/raw/testN.mp3
Purpose is to play different samples on a button click, without delays.
List<MediaPlayer> player = new ArrayList<>();
//TODO how to loop properly?
for (Rawfile file : rawfiles) {
pl = MediaPlayer.create(getBaseContext(), R.raw.test1);
player.add(pl);
}
Lateron, if eg button2 is clicked:
player.get(1).start();
Question: how can I get the R.raw.* files dynamically during initialization of the app?
Update: the following is quite close, but there are 2 problems:
1) If eg only one file "test.mp3" is placed in my /res/raw folder, the function shows 3 files.
2) How can I then load those files to mediaplayer?
public void listRaw(){
Field[] fields=R.raw.class.getFields();
for(int count=0; count < fields.length; count++){
Log.i("Raw Asset: ", fields[count].getName());
}
}
Result:
I/Raw Asset:: $change
I/Raw Asset:: serialVersionUID
I/Raw Asset:: test
For the moment solved as follows, but feels kinda hacky:
public static List<Integer> listRawMediaFiles() {
List<Integer> ids = new ArrayList<>();
for (Field field : R.raw.class.getFields()) {
try {
ids.add(field.getInt(field));
} catch (Exception e) {
//compiled app contains files like '$change' or 'serialVersionUID'
//which are no real media files
}
}
return ids;
}
I Really forget from where i get this, it can be duplicated any way not my code but works perfectly :
private boolean listFiles(String path) {
String [] list;
try {
list = getAssets().list(path);
if (list.length > 0) {
// folder founded
for (String file : list) {
if (!listAssetFiles(path + "/" + file))
return false;
}
} else {
//file founded
}
} catch (IOException e) {
return false;
}
return true;
}
Though undervoted, this answer from CommonsWare is comprehensive. The best you can do is iterate over the raw fields by reflection. If you find non-resource fields, you should discard them manually (I see you did it in an answer).
One point: putting files in raw directory is done during development time, and programming the iteration over raw resources is also done during development time. It's a problem you should solve before compilation, rather than finding out what files you have in run time, that is, you should list the files by name in your code.

Create a fast file search function in android

I'm new to android and I'm trying to develop file explorer which includes search function. I'm using a recursive search function that works fine in folders with a few subfolders and files, but for some reason it's EXTREMELY SLOW and could "Force Close" in folders with lots of subfolders and files, because there's not enough memory. I do the search by creating ArrayList where the results will be placed, and then calling the recursive function that will fill the list. The "path" argument is the file where the search will start from, and "query" is the search query.
ArrayList<File> result = new ArrayList<File>();
fileSearch(path, query, result);
this is what the recursive function looks like:
private void fileSearch(File dir, String query, ArrayList<File> res) {
if (dir.getName().toLowerCase().contains(query.toLowerCase()))
res.add(dir);
if (dir.isDirectory() && !dir.isHidden()) {
if (dir.list() != null) {
for (File item : dir.listFiles()) {
fileSearch(item, query, res);
}
}
}
}
If someone could point me to a way of performing a faster and/or more efficient file search, I would really appreciate that.
EDIT:
This is how I tried to do the job with AsyncTask:
private class Search extends AsyncTask<File, Integer, Void> {
String query;
ArrayList<File> result = new ArrayList<File>();
public Search(String query){
this.query = query;
setTitle("Searching");
}
#Override
protected Void doInBackground(File... item) {
int count = item.length;
for (int i = 0; i < count; i++) {
fileSearch(item[i], query, result);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return null;
}
protected void onProgressUpdate(Integer... progress) {
setProgress(progress[0]);
}
protected void onPostExecute() {
searchResults = new ListItemDetails[result.size()];
for (int i = 0; i < result.size(); i++) {
File temp = result.get(i);
if (temp.isDirectory())
searchResults[i] = new ListItemDetails(temp.getAbsolutePath(),
R.drawable.folder, temp.lastModified(), temp.length());
else {
String ext;
if (temp.getName().lastIndexOf('.') == -1)
ext = "";
else
ext = temp.getName().substring(
temp.getName().lastIndexOf('.'));
searchResults[i] = new ListItemDetails(temp.getAbsolutePath(),
getIcon(ext), temp.lastModified(), temp.length());
}
}
finishSearch();
}
}
public void finishSearch() {
Intent intent = new Intent(this, SearchResults.class);
startActivity(intent);
}
The call to finishSearch() is just so I can create the Intent to show the results in other Activity. Any ideas, suggestions, tips? Thanks in advance
It is possible that you are hitting symbolic links and going into an infinitive loop with your search function and depleting available memory to your application.
I would suggest you to keep a separate list containing canonical paths (File.getCanonicalPath()) of directories you've visited and avoid visiting them over and over again.
Why don't you use Apache Commons IO? It has some functions to deal with searching.
I also suggest using the method FileUtils.listFiles, which takes a folder, a search query and a directory filter as parameters.
The following example returns you a list of all file's paths that matched according to a regex. Try adding it in doInBackground of your AsyncTask:
Collection files = FileUtils.listFiles(new File(yourRootPath),
new RegexFileFilter(searchQuery),
DirectoryFileFilter.DIRECTORY);
Have you looked into Lucene?
It is especially designed to index and query large numbers of free-text documents, so many of the I/O streaming and indexing tasks have already been solved for you. If you remove the recursion and do the document indexing using a Lucene index in a purely iterative fashion, memory issues may be mitigated.
Look into this thread:
Lucene in Android
Do it in the background, and starting from Android O (API 26) , you can use Files.find API. Exmaple:
Files.find(
Paths.get(startPath), Integer.MAX_VALUE,
{ path, _ -> path.fileName.toString() == file.name }
).forEach { foundPath ->
Log.d("AppLog", "found file on:${foundPath.toFile().absolutePath}")
}

Getting files from other folders in android

I want to make an array of specific types of files with .txt that are found in all android folders.
I am bit off I need to loop through all folders then create a list out of all the items found with the file name of ".txt".
My question is what method do I need to start from the top of all the folders? Also I need a method to open a specific folder(So I can loop through the FileNameFilter method).
Also I don't mind any recommendation on how to do this kind of method.
public String getFile(int position){
File root = Environment.getExternalStorageDirectory();//This is incorrect it just goes to it's current environment it's folder found for this application.
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String filename) {
// TODO Auto-generated method stub
return !filename.endsWith(".txt");
}
};
ArrayList<File> items = new ArrayList<File>(Arrays.asList(root.listFiles(filter)));
String returned = items.get(position).toString();
return returned;
You need a recursive method that will loop through a folder and, for each child : if the child is a folder, call itself with the child as parameter. If the child is a file, check its name and add it if needed.
You can do something like
public void findAllFilesWithExtension( File dir, String extension, List<File> listFiles ) {
List<File> listChildren = Arrays.asList(dir.listFiles());
for( File child : listChildren ) {
if( child.isDirectory() ) {
findAllFilesWithExtension( child, extension, listFiles );
} else if( child.getName().endsWith( extension ) ) {
listFiles.add( child );
} //else
} //for
}//met
And call it first on your root directory.

How can I clear the Android app cache?

I am writing a app which can programatically clear application cache of all the third party apps installed on the device. Following is the code snippet for Android 2.2
public static void trimCache(Context myAppctx) {
Context context = myAppctx.createPackageContext("com.thirdparty.game",
Context.CONTEXT_INCLUDE_CO|Context.CONTEXT_IGNORE_SECURITY);
File cachDir = context.getCacheDir();
Log.v("Trim", "dir " + cachDir.getPath());
if (cachDir!= null && cachDir.isDirectory()) {
Log.v("Trim", "can read " + cachDir.canRead());
String[] fileNames = cachDir.list();
//Iterate for the fileName and delete
}
}
My manifest has following permissions:
android.permission.CLEAR_APP_CACHE
android.permission.DELETE_CACHE_FILES
Now the problem is that the name of the cache directory is printed but the list of files cachDir.list() always returns null. I am not able to delete the cache directory since the file list is always null.
Is there any other way to clear the application cache?
"android.permission.CLEAR_APP_CACHE" android.permission.DELETE_CACHE_FILES"
Ordinary SDK applications cannot hold the DELETE_CACHE_FILES permission. While you can hold CLEAR_APP_CACHE, there is nothing in the Android SDK that allows you to clear an app's cache.
Is there any other way to clear the application cache?
You are welcome to clear your own cache by deleting the files in that cache.
Check out android.content.pm.PackageManager.clearApplicationUserData: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.3_r1/android/content/pm/PackageManager.java/
The other hidden methods in that class might be useful, too.
In case you've never used hidden methods before, you can access hidden methods using Java reflection.
poate iti merge asta
static int clearCacheFolder(final File dir, final int numDays) {
int deletedFiles = 0;
if (dir!= null && dir.isDirectory()) {
try {
for (File child:dir.listFiles()) {
//first delete subdirectories recursively
if (child.isDirectory()) {
deletedFiles += clearCacheFolder(child, numDays);
}
//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) {
if (child.delete()) {
deletedFiles++;
}
}
}
}
catch(Exception e) {
Log.e("ATTENTION!", String.format("Failed to clean the cache, error %s", e.getMessage()));
}
}
return deletedFiles;
}
public static void clearCache(final Context context, final int numDays) {
Log.i("ADVL", String.format("Starting cache prune, deleting files older than %d days", numDays));
int numDeletedFiles = clearCacheFolder(context.getCacheDir(), numDays);
Log.i("ADVL", String.format("Cache pruning completed, %d files deleted", numDeletedFiles));
}
I'm not sure how appropriate this is in terms of convention, but this works so far for me in my Global Application class:
File[] files = cacheDir.listFiles();
for (File file : files){
file.delete();
}
Of course, this doesn't address nested directories, which might be done with a recursive function like this (not tested extensively with subdirectories):
deleteFiles(cacheDir);
private void deleteFiles(File dir){
if (dir != null){
if (dir.listFiles() != null && dir.listFiles().length > 0){
// RECURSIVELY DELETE FILES IN DIRECTORY
for (File file : dir.listFiles()){
deleteFiles(file);
}
} else {
// JUST DELETE FILE
dir.delete();
}
}
}
I didn't use File.isDirectory because it was unreliable in my testing.

Categories

Resources