0

I want to filter files stored in my phone with the .apk extension. I have tried the below code but it filters files found only in sdcard/file.apk but I want it to filter the file by searching into the sub directories of sdcard also.

For example if there is an apk file inside sdcard/download/mm.apk it should filter it and also if there is another file in sdcard/New Folder/ABC/cc.apk it should filter it too.

How can I do that? thank you for your help...

ExtFilter apkFilter = new ExtFilter("apk");
            File file[] =Environment.getExternalStorageDirectory().listFiles(apkFilter);
            Log.i("InstallApk","Filter applied. Size: "+ file.length);
            for (int i=0; i < file.length; i++)
                {
                    Log.i("InstallApk",
                          "FileName:" + file[i].getName());
                }
            ArrayAdapter af=new ArrayAdapter<File>(this,android.R.layout.simple_list_item_1,android.R.id.text1,file);
            ListView ll=(ListView) findViewById(R.id.mainListView1);
            ll.setAdapter(af);
        }
    class ExtFilter implements
    FilenameFilter {       
    String ext;        
    public ExtFilter(String ext) {     
    this.ext = "." + ext;        
    }       
    public boolean accept(File dir, String name) 
    {            
    return name.endsWith(ext);      
    }
        }
Abdul
  • 2,002
  • 7
  • 31
  • 65
surayanbo
  • 1
  • 2

2 Answers2

1

You have to do it recursively. It is not enough to check for the extension, you must also verify that it is a regular file cos I can as well name a directory dir.apk. Verifying that it is a regular file is also not enough since one can name any file with any extension. Regardless, checking that it is a regular file should be enough without consideration of the intended action on these files.

public void someFunction() {
    List<File> apkFiles = getApkFiles(Environment.getExternalStorageDirectory(), new ApkSearchFilter());
    File file[] = apkFiles.toArray(new File[apkFiles.size()]);
    Log.i("InstallApk", "Filter app\"lied. Size: " + file.length);
    for (File aFile : file) {
        Log.i("InstallApk", "FileName:" + aFile.getName());
    }
}

List<File> getApkFiles(File file, ApkSearchFilter filter) {
    if (filter.isApk(file))
        return Collections.singletonList(file);
    else if (filter.isDirectory(file)) {
        LinkedList<File> files = new LinkedList<>();
        for (File subFile : file.listFiles()) {
            files.addAll(getApkFiles(subFile, filter));
        }
        return files;
    } else return Collections.emptyList();
}


class ApkSearchFilter implements FileFilter {

    boolean isApk(File file) {
        return !file.isDirectory() && file.getName().matches(".*\\.apk");
    }

    boolean isDirectory(File file) {
        return file.isDirectory();
    }

    @Override
    public boolean accept(File file) {
        return isDirectory(file) || isApk(file);
    }
}
Olayinka
  • 2,813
  • 2
  • 25
  • 43
  • A basic recursive methods. I would just pass the List in parameter to gain some cycle (the addAll that could take time if there is many apk). But I use the same logic to find every video file on a directory and it takes few seconds to find hundreds. PS : is it usefull to use a LinkedList ? – AxelH Aug 05 '16 at 12:05
  • @AxelH You are right, passing a list around is more optimal and the LinkedList is unnecessary. I was only hoping Java linked list allows appending one linkedlist to another. Apparently it doesn't. – Olayinka Aug 05 '16 at 12:10
  • Yeah, overloading the addAll for a LinkedList to hook both list together would be a gread idea but unfortunalty, it's looping on the collection. But nice try ;) – AxelH Aug 05 '16 at 12:36
0

This is one in many way you can try, don't forget to add permission in manifest:

private List<String> ReadSDCard()
{
     File f = new File("your path"); // Environment.getExternalStorageDirectory()

     File[] files=f.listFiles();

     for(int i=0; i<files.length; i++)
     {
      File file = files[i];
      String filePath = file.getPath();
      if(filePath.endsWith(".apk")) 
      tFileList.add(filePath);
     }
 return tFileList;
}
xxx
  • 3,315
  • 5
  • 21
  • 40
  • I have tried it @Huy N but it only filters apks found in Sdcard/ only but I want to filter apks found in sdcard whole folders in short apks found in the phone file system. – surayanbo Aug 05 '16 at 11:48
  • @surayanbo i just found this article may helpful for you: http://stackoverflow.com/questions/8307034/how-to-get-the-apk-file-of-an-application-programatically – xxx Aug 05 '16 at 11:53