The Android SDK does not have a file browser dialog for use by app developers. For my app MoPhotos, I needed to allow the user to select a file from their Android system that my app can use. I was surprised to learn there is no real built-in file chooser dialog. From my experience with .NET and the Win32 API, that’s a function that you can count on being there. I did not think it would be difficult to write one myself, but I’m always looking for quicker ways to get there.
Eventually, I found a blog post by Android-er, who shows a very simple version of the mechanics behind a file open dialog. After getting my version of his code up and running, I wanted to make a few modifications to meet my needs. These modifications are:
- Alphabetize the list of files
- Exclude hidden files, hidden directories, and directories without read access
- Only show files with compatible file extensions
Fortunately, this was very easy to do using standard Java API’s. Instead of calling:
File[] files = f.listFiles();
I create a FileFilter to filter out the results:
File[] files = f.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { //If a file or directory is hidden, or unreadable, don't show it in the list.</div> if(pathname.isHidden()) return false; if(!pathname.canRead()) return false; //Show all directories in the list. if(pathname.isDirectory()) return true; //Check if there is a supported file type that we can read. String fileName = pathname.getName(); String fileExtension; int mid= fileName.lastIndexOf("."); fileExtension = fileName.substring(mid+1,fileName.length()); for(String s : supportedFileExtensions) { if(s.contentEquals(fileExtension)) return true; } return false; } });
//Sort the files alphabetically. Collections.sort(fileStringList); Collections.sort(pathStringList); fileListAdapter = new ArrayAdapter(this.getContext(), R.layout.open_file_entry, R.id.fileName, fileStringList); ListView lv = (ListView) this.findViewById(R.id.pcap_files_list); if(lv != null) { lv.setAdapter(fileListAdapter); }
So far, this code is working as intended. I don’t know if this is the most-optimal to do this, but that will be analyzed before I release this app to the market. For now, I’m still building out the basic infrastructure.