android recursively list the files in sd card - android

I want to search for a particular file in my sd card . So i am trying to list complete files and search for the pattern. Please see code below
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String root_sd = Environment.getExternalStorageDirectory().toString();
file = new File(root_sd);
listfiles( new File(root_sd));
}
public void listfiles(File file) {
//file = new File(path);
// file = new File( root_sd ) ;
File list[] = file.listFiles();
Log.i("DIR", "PATH" +file.getPath());
for (int i = 0; i < list.length; i++) {
// myList.add( list[i].getName() );
File temp_file = new File(file.getAbsolutePath(),list[i].getName());
Log.i("DIR", "PATH" +temp_file.getAbsolutePath());
if (temp_file.isFile() && temp_file.listFiles() != null) {
Log.i("inside", "call fn");
listfiles(temp_file);
} else {
if (list[i].getName().toLowerCase().contains("pattern1"))
Log.i("File", i + list[i].getName());
if (list[i].getName().toLowerCase().contains("pattern2"))
Log.i("File", i + list[i].getName());
}
}
Here only first level of search is happening . This condition if (temp_file.isFile() && temp_file.listFiles() != null)
is always returning false and thus recursive call not happening.
Please help me to fix it. Thanks for your answer and time.

if the temp_file.isFile() returns true then it means it is a file and hence temp_file.listFiles() automatically becomes null thus making your entire statement false. Thus your combined statement returns a false always. What you need is a || in place of &&.

Related

How can I read all files and directory in a device?

Is it possible to develop a Java application that can read all files and directories in the device's memory?
I think it's not possible (for security reasons), but I need another opinion.
You can do it like this.
I will take path is the device storage.
If you are using Android Studio or a likewise tool, put the debug point next to:
File[] dir = new File(path).listFiles();
And you will see the file/folder hierarchy.
path = Environment.getExternalStorageDirectory().toString()
public static ArrayList<String> listFoldersAndFilesFromSDCard(String path) {
ArrayList<String> arrayListFolders = new ArrayList<String>();
try {
File[] dir = new File(path).listFiles();
// Here 'dir' will give you a list of folder/files in the hierarchy
if (null != dir && dir.length > 0) {
for (int i = 0; i < dir.length; i++) {
if (dir[i].isDirectory()) {
arrayListFolders.add(new File(dir[i].toString()).getName());
// Here you can call recursively this
// function for file/folder hierarchy
}
else {
// Do whatever you want with the files
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return arrayListFolders;
}

Delete files from a known folder

I'm trying to delete all files that are exists in a known path.
I've used the next function to do so -
public void deleteAllImages(){
Log.d(TAG, "ENTERD DELETED ALL IMAGES ");
String path = "/data/data/yourapp/app_data/imageDir/";
File directory = new File(path);
if (directory.isDirectory()){
Log.d(TAG, "ENTERED IF ");
for (File child : directory.listFiles()){
Log.d(TAG, "ENTERED FOR "+ child);
child.delete();
}
}
}
But it seem that it never getting into the if statement - guess it mean that it doesn't treat directory as one. So what am I doing wrong here?
Most likely the path is not correct. The isDirectory() will return false in the following cases:
The path points to file (obviously), and not to directory.
The path
is invalid (i.e. there is no such file/directory exists).
There is
not enough permissions granted to your application to determine
whether path points to directory.
Try this :
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
new File(dir, children[i]).delete();
}
}
Check this : Delete files from folder
Hope this helps.
try this...
String path = "/data/data/yourapp/app_data/imageDir/";
File file = new File(path);
if(file.isDirectory()) {
File[] files = file.listFiles();
if(files != null && files.length > 0) {
for (File file2 : files) {
file2.delete();
}
}
}

Android How do I check the number of files in a directory

I am creating a directory in internal memory of device for storing files for application use.I am using:
File dir = context.getDir(userfavorites, Context.MODE_PRIVATE);
The above code will create a new directory if it does not exists or returns me the existing file object if directory has already been created.What I want to check is the number and name of files this directory contains.How do I use this file object to accomplish this task.
NOTE:I don't want to use external memory of device.And I can't avoid creating directory as well because the files in directory has to be separated from other files that are not in directory.
UPDATED CODE:
private static boolean IsFoldercontainsFiles(Context context) {
// TODO Auto-generated method stub
File dir = context.getDir(USER_FAV, Context.MODE_PRIVATE);
if (dir.exists()) {
if (dir.listFiles() == null){
return false;} //it never execute this line even though its null
else{
File childfile[] = dir.listFiles();
Log.i("file no is ", Integer.toString(childfile.length));
if (childfile.length == 0) {
return false;
} else {
return true;
}
}
} else {
return false;
}
}
Thanks in advance
Check the listFiles method of File that will give you the list of children.
File file=new File("/mnt/sdcard/yourfolder");
File[] list = file.listFiles();
int count = 0;
for (File f: list){
String name = f.getName();
if (name.endsWith(".jpg") || name.endsWith(".mp3") || name.endsWith(".some media extention"))
count++;
System.out.println("170 " + count);
}
try this
File childfile[] = dir .listFiles();
for (File file2 : childfile) {
Log.v("file name is ", file2.getName());
}
here listFiles() return all the childfiles for the "dir" and iterating this will help you to get the names of the childfiles
Simple:
File dir = new File(path); // "/mnt/sdcard/yourfolder"
long totalNumFiles = dir.listFiles().length;
Try this sample of code for getting number of files in a directory
private int getNumberOfFiles() throws FileNotFoundException {
File outFile = new File(outFolder);
if (!outFile.exists())throw new FileNotFoundException();
int numberofFiles = outFile.listFiles(new FileFilter() {
#Override
public boolean accept(File file) {
return (file.getPath().startsWith("frame_")&&(file.getPath().endsWith(".jpg")||file.getPath().endsWith(".jpeg")));
}
}).length;
return numberofFiles;
}
The listFiles method of the File class returns an array of File objects, one for each file or directory in the directory.
One can use recursion to find all files within a directory and its subdirectories.
fun File.getFileCountRecursively(): Int {
var fileCount = 0
if (exists() && isDirectory) {
listFiles()?.forEach { child ->
fileCount += if (child.isDirectory) child.getFileCountRecursively() else 1
}
}
return fileCount
}

android list all folders that has an image

As part of my app i need to have file browser that lists only specific folders.
For eg list only those folders in the path that an image file in any of its subfolders in any level.
I could do it using recursion. But it affects performance. Especially finding folders at top level need many recursive calls. Is there a better way to do it
Please see my code below
public List<GeneralFileItem> getGridItemsList(String root) {
List<GeneralFileItem> gridItemsList = new ArrayList<GeneralFileItem>();
File file;
file = new File(root);
File list[] = file.listFiles();
if (list.length == 0) {
return null;
}
for (int i = 0; i < list.length; i++) {
GeneralFileItem item = new GeneralFileItem();
File temp_file = new File(file.getAbsolutePath(), list[i].getName());
if (hasPhoto(temp_file)) {
item.setPath(file.getAbsolutePath() + "/" + list[i].getName());
item.setName(list[i].getName());
if (temp_file.listFiles() != null) {
item.setType(GeneralFileItem.DIRECTORY_TYPE);
} else {
item.setType(GeneralFileItem.FILE_TYPE);
}
gridItemsList.add(item);
//Log.i(TAG,"added"+list[i].getName());
}
}
return gridItemsList;
}
private boolean hasPhoto(File temp_file) {
//Log.i(TAG,temp_file.getName());
if (temp_file.listFiles() == null) {
if (temp_file.getName().toUpperCase().endsWith(("JPG"))) {
//Log.i(TAG,temp_file.getName()+ "is a photo");
return true;
} else
return false;
}
else{
File list[] = temp_file.listFiles();
for (int i = 0; i < list.length; i++) {
if(hasPhoto(list[i]))
return true;
}
}
return false;
}
I want to know if there is any other way than recursive search. How are the files maintained in Android. I know that various file systems are supported and it varies from hardware manufaturer . I would like to know if there is a way like if there is FileTable from which i can get all .jpg files .
use FilenameFilter to search for specirfic type of files.
presently you are checking only current directory.However if you wish to search recursively then you will have to check if each file found is a directory or not
Your algo would be something like
File file;
file = new File(root);
File list[] = file.listFiles();
if (list.length == 0) {
return null;
}
for (int i = 0; i < list.length; i++) {
if(list[i].isDirectory()){
//Then go inside it to search for specific file
File subList[] = list[i].listFiles();
//search for jpg..
}else if("is this jpg"){
//Add to list
}
}
To simplify this you could segregate these into methods as per your requirement.
Here's something I came up! It works like a charm!
First you must create a File, this one is root of SD card
File = rootPrimary = new File(Environment.getExternalStorageDirectory());
than you must list all the files in to a File []
File[] fileArray = rootDirectory.listFiles();
Then you create a ArrayList and set it equal to a method i've created and pass the File[] in.
ArrayList<File> alFolders = new ArrayList<File>();
alFolder = putImgFldr(fileArray);
This method will add all dorectoryes that contain images with .jpg and .png extension.
private ArrayList<File> putImgFldr(File[] fileArray) {
// TODO Auto-generated method stub
ArrayList<File> a = new ArrayList<File>();
for (int i = 0; i < fileArray.length; i++) {
if (fileArray[i].isDirectory()) {
//if file is folder pass that file trough this method
a.addAll(putImgFldr(fileArray[i].listFiles()));
} else if (fileArray[i].getAbsolutePath().endsWith(".jpg") || fileArray[i].getAbsolutePath().endsWith(".png")) {
// if file is img ad it's parent, folder to ArrayList
a.add(fileArray[i].getParentFile());
// this finishes the file searching
// because the image has allready bean found
i = fileArray.length + 1;
}
}
return a;
}
now You can add another File [] to alFolders if nessesery
alFolders.addAll(putImgFldr(secFileArray));
One more example of listing files and directories using Java 8 filter. For instance, here I am using just jpeg images
public static void main(String[] args) {
System.out.println("Files!!");
try {
Files.walk(Paths.get("."))
.filter(Files::isRegularFile)
.filter(c ->
c.getFileName().toString().substring(c.getFileName().toString().length()-4).contains(".jpg")
||
c.getFileName().toString().substring(c.getFileName().toString().length()-5).contains(".jpeg")
)
.forEach(System.out::println);
} catch (IOException e) {
System.out.println("No jpeg or jpg files");
}
System.out.println("\nDirectories!!\n");
try {
Files.walk(Paths.get("."))
.filter(Files::isDirectory)
.forEach(System.out::println);
} catch (IOException e) {
System.out.println("No Jpeg files");
}
}

Path to screenshots in Android

Is there a way to find out the path used by android to save screenshots?
Can I get the path from a code?
Android's API has no fixed path for screenshots but
File pix = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File screenshots = new File(pix, "Screenshots");
might work. That's what ICS uses as path.
The "Screenshots" value is part of the private API.
Here is link to the source code where the value is set. Since the class is loaded in our application context there is no option to access the field. I'd hardcode it as #zapi suggested.
Few might find this usefull..
public static File mDir= new File(String.valueOf(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)));
public static File mDirScreenshots = new File(mDir,"Screenshots");
And to fetch the screenshots
public static ArrayList<File> getAllScreenshots(File dir){
File listFile[] = dir.listFiles();
if (listFile != null && listFile.length > 0) {
for (int i = 0; i < listFile.length; i++) {
Log.e(YOUR_TAG, "getAllScreenshots: " + i + listFile[i].getName());
mScreenshotsFiles.add(listFile[i]);
}
}
return mScreenshotsFiles;
}
Recursion is your friend here.
Tested on Android version 9 and 12. Works good.
final String findThisDirectory = "screenshots";
final String rootPath = Environment.getExternalStorageDirectory().getPath();
//we do not want to include 'Android' directory because looking inside it
//or some directories inside of it can and will cause crash in some Android versions due to permissions related issues
String ignoreThisDirectory = "android";
void getPathRecursively(String rootPath, String matchThisDirectory, String ignoreThisDirectory){
File[] filesArray = new File(rootPath).listFiles();
if(filesArray.length > 0){
for(File file: filesArray){
if(file.isDirectory()){
if(file.getName().toLowerCase().equals(ignoreThisDirectory)){
continue;
}
else if(file.getName().toLowerCase().equals(matchThisDirectory)){
// here you found the path to 'screenshots' in file object
// get it from the file.getAbsolutePath()
break;
}
getPathRecursively(file.getAbsolutePath(), matchThisDirectory, ignoreThisDirectory);
}
}
}
}

Categories

Resources