Choose File Dialog

AndroidFileUser InterfaceDialogCode Snippets

Android Problem Overview


Does anyone know of a complete choose file dialog? Maybe one where you can filter out all files except for ones with specific extensions?

I have not found anything lightweight enough to implement easily into one of my projects. The only other option seems to be using OI FileManager's open intents, but that requires the user already having the file manager installed.

I would be grateful if someone could point out a Dialog that would allow the user to browse folders and select a file, and return the path.

Android Solutions


Solution 1 - Android

You just need to override onCreateDialog in an Activity.

//In an Activity
private String[] mFileList;
private File mPath = new File(Environment.getExternalStorageDirectory() + "//yourdir//");
private String mChosenFile;
private static final String FTYPE = ".txt";    
private static final int DIALOG_LOAD_FILE = 1000;

private void loadFileList() {
	try {
		mPath.mkdirs();
	}
	catch(SecurityException e) {
		Log.e(TAG, "unable to write on the sd card " + e.toString());
	}
	if(mPath.exists()) {
		FilenameFilter filter = new FilenameFilter() {

            @Override
			public boolean accept(File dir, String filename) {
				File sel = new File(dir, filename);
				return filename.contains(FTYPE) || sel.isDirectory();
			}

		};
		mFileList = mPath.list(filter);
	}
	else {
		mFileList= new String[0];
	}
}

protected Dialog onCreateDialog(int id) {
	Dialog dialog = null;
	AlertDialog.Builder builder = new Builder(this);

	switch(id) {
		case DIALOG_LOAD_FILE:
			builder.setTitle("Choose your file");
			if(mFileList == null) {
				Log.e(TAG, "Showing file picker before loading the file list");
				dialog = builder.create();
				return dialog;
			}
			builder.setItems(mFileList, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					mChosenFile = mFileList[which];
					//you can do stuff with the file here too
				}
			});
			break;
	}
	dialog = builder.show();
	return dialog;
}

Solution 2 - Android

Thanx schwiz for idea! Here is modified solution:

public class FileDialog {
    private static final String PARENT_DIR = "..";
    private final String TAG = getClass().getName();
    private String[] fileList;
    private File currentPath;
    public interface FileSelectedListener {
        void fileSelected(File file);
    }
    public interface DirectorySelectedListener {
        void directorySelected(File directory);
    }
    private ListenerList<FileSelectedListener> fileListenerList = new ListenerList<FileDialog.FileSelectedListener>();
    private ListenerList<DirectorySelectedListener> dirListenerList = new ListenerList<FileDialog.DirectorySelectedListener>();
    private final Activity activity;
    private boolean selectDirectoryOption;
    private String fileEndsWith;    

    /**
    * @param activity 
    * @param initialPath
    */
    public FileDialog(Activity activity, File initialPath) {
        this(activity, initialPath, null);
    }

    public FileDialog(Activity activity, File initialPath, String fileEndsWith) {
        this.activity = activity;
        setFileEndsWith(fileEndsWith);
        if (!initialPath.exists()) initialPath = Environment.getExternalStorageDirectory();
            loadFileList(initialPath);
    }

    /**
    * @return file dialog
    */
    public Dialog createFileDialog() {
        Dialog dialog = null;
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);

        builder.setTitle(currentPath.getPath());
        if (selectDirectoryOption) {
            builder.setPositiveButton("Select directory", new OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    Log.d(TAG, currentPath.getPath());
                    fireDirectorySelectedEvent(currentPath);
                }
            });
        }
    
        builder.setItems(fileList, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                String fileChosen = fileList[which];
                File chosenFile = getChosenFile(fileChosen);
                if (chosenFile.isDirectory()) {
                    loadFileList(chosenFile);
                    dialog.cancel();
                    dialog.dismiss();
                    showDialog();
                } else fireFileSelectedEvent(chosenFile);
            }
        });
    
        dialog = builder.show();
        return dialog;
    }


    public void addFileListener(FileSelectedListener listener) {
        fileListenerList.add(listener);
    }

    public void removeFileListener(FileSelectedListener listener) {
        fileListenerList.remove(listener);
    }

    public void setSelectDirectoryOption(boolean selectDirectoryOption) {
        this.selectDirectoryOption = selectDirectoryOption;
    }

    public void addDirectoryListener(DirectorySelectedListener listener) {
        dirListenerList.add(listener);
    }

    public void removeDirectoryListener(DirectorySelectedListener listener) {
        dirListenerList.remove(listener);
    }

    /**
    * Show file dialog
    */
    public void showDialog() {
        createFileDialog().show();
    }

    private void fireFileSelectedEvent(final File file) {
        fileListenerList.fireEvent(new FireHandler<FileDialog.FileSelectedListener>() {
            public void fireEvent(FileSelectedListener listener) {
                listener.fileSelected(file);
            }
        });
    }

    private void fireDirectorySelectedEvent(final File directory) {
        dirListenerList.fireEvent(new FireHandler<FileDialog.DirectorySelectedListener>() {
            public void fireEvent(DirectorySelectedListener listener) {
                listener.directorySelected(directory);
            }
        });
    }

    private void loadFileList(File path) {
        this.currentPath = path;
        List<String> r = new ArrayList<String>();
        if (path.exists()) {
            if (path.getParentFile() != null) r.add(PARENT_DIR);
            FilenameFilter filter = new FilenameFilter() {
                public boolean accept(File dir, String filename) {
                    File sel = new File(dir, filename);
                    if (!sel.canRead()) return false;
                    if (selectDirectoryOption) return sel.isDirectory();
                    else {
                        boolean endsWith = fileEndsWith != null ? filename.toLowerCase().endsWith(fileEndsWith) : true;
                        return endsWith || sel.isDirectory();
                    }
                }
            };
            String[] fileList1 = path.list(filter);
            for (String file : fileList1) {
                r.add(file);
            }
        }
        fileList = (String[]) r.toArray(new String[]{});
    }

    private File getChosenFile(String fileChosen) {
        if (fileChosen.equals(PARENT_DIR)) return currentPath.getParentFile();
        else return new File(currentPath, fileChosen);
    }

    private void setFileEndsWith(String fileEndsWith) {
        this.fileEndsWith = fileEndsWith != null ? fileEndsWith.toLowerCase() : fileEndsWith;
    }
}

class ListenerList<L> {
    private List<L> listenerList = new ArrayList<L>();

    public interface FireHandler<L> {
        void fireEvent(L listener);
    }

    public void add(L listener) {
        listenerList.add(listener);
    }

    public void fireEvent(FireHandler<L> fireHandler) {
        List<L> copy = new ArrayList<L>(listenerList);
        for (L l : copy) {
            fireHandler.fireEvent(l);
        }
    }

    public void remove(L listener) {
        listenerList.remove(listener);
    }

    public List<L> getListenerList() {
        return listenerList;
    }
}

Use it on activity onCreate (directory selection option is commented):

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    File mPath = new File(Environment.getExternalStorageDirectory() + "//DIR//");
    fileDialog = new FileDialog(this, mPath, ".txt");
    fileDialog.addFileListener(new FileDialog.FileSelectedListener() {
        public void fileSelected(File file) {
            Log.d(getClass().getName(), "selected file " + file.toString());
        }
    });
    //fileDialog.addDirectoryListener(new FileDialog.DirectorySelectedListener() {
    //	public void directorySelected(File directory) {
    //		Log.d(getClass().getName(), "selected dir " + directory.toString());
    //	}
    //});
    //fileDialog.setSelectDirectoryOption(false);
    fileDialog.showDialog();
}

Solution 3 - Android

I have created FolderLayout which may help you. This link helped me

folderview.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="match_parent"
	android:layout_height="match_parent">
	<TextView android:id="@+id/path" android:text="Path"
		android:layout_width="match_parent" android:layout_height="wrap_content"></TextView>
	<ListView android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:id="@+id/list"></ListView>
	
</LinearLayout>
FolderLayout.java
package com.testsample.activity;




   public class FolderLayout extends LinearLayout implements OnItemClickListener {

	Context context;
	IFolderItemListener folderListener;
	private List<String> item = null;
	private List<String> path = null;
	private String root = "/";
	private TextView myPath;
	private ListView lstView;

	public FolderLayout(Context context, AttributeSet attrs) {
		super(context, attrs);

		// TODO Auto-generated constructor stub
		this.context = context;
		

		LayoutInflater layoutInflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View view = layoutInflater.inflate(R.layout.folderview, this);

		myPath = (TextView) findViewById(R.id.path);
		lstView = (ListView) findViewById(R.id.list);

		Log.i("FolderView", "Constructed");
		getDir(root, lstView);

	}

	public void setIFolderItemListener(IFolderItemListener folderItemListener) {
		this.folderListener = folderItemListener;
	}

	//Set Directory for view at anytime
	public void setDir(String dirPath){
		getDir(dirPath, lstView);
	}
	

	private void getDir(String dirPath, ListView v) {

		myPath.setText("Location: " + dirPath);
		item = new ArrayList<String>();
		path = new ArrayList<String>();
		File f = new File(dirPath);
		File[] files = f.listFiles();

		if (!dirPath.equals(root)) {

			item.add(root);
			path.add(root);
			item.add("../");
			path.add(f.getParent());

		}
		for (int i = 0; i < files.length; i++) {
			File file = files[i];
			path.add(file.getPath());
			if (file.isDirectory())
				item.add(file.getName() + "/");
			else
				item.add(file.getName());

		}

		Log.i("Folders", files.length + "");

		setItemList(item);
		
	}
	
	//can manually set Item to display, if u want
	public void setItemList(List<String> item){
		ArrayAdapter<String> fileList = new ArrayAdapter<String>(context,
				R.layout.row, item);

		lstView.setAdapter(fileList);
		lstView.setOnItemClickListener(this);
	}
	

	public void onListItemClick(ListView l, View v, int position, long id) {
		File file = new File(path.get(position));
		if (file.isDirectory()) {
			if (file.canRead())
				getDir(path.get(position), l);
			else {
//what to do when folder is unreadable
				if (folderListener != null) {
					folderListener.OnCannotFileRead(file);
					
				}
				
			}
		} else {

//what to do when file is clicked
//You can add more,like checking extension,and performing separate actions
			if (folderListener != null) {
				folderListener.OnFileClicked(file);
			}
			
		}
	}

	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
		// TODO Auto-generated method stub
		onListItemClick((ListView) arg0, arg0, arg2, arg3);
	}

}

And an Interface IFolderItemListener to add what to do when a fileItem is clicked

###IFolderItemListener.java###

public interface IFolderItemListener {

	void OnCannotFileRead(File file);//implement what to do folder is Unreadable
	void OnFileClicked(File file);//What to do When a file is clicked
}

Also an xml to define the row

row.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/rowtext" android:layout_width="fill_parent"
	android:textSize="23sp" android:layout_height="match_parent"/>

##How to Use in your Application ##

In your xml,

###folders.xml###

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="match_parent" android:layout_height="match_parent"
	android:orientation="horizontal" android:weightSum="1">
	<com.testsample.activity.FolderLayout android:layout_height="match_parent" layout="@layout/folderview"
		android:layout_weight="0.35"
		android:layout_width="200dp" android:id="@+id/localfolders"></com.testsample.activity.FolderLayout></LinearLayout>

In Your Activity,

SampleFolderActivity.java
public class SampleFolderActivity extends Activity implements IFolderItemListener {

	FolderLayout localFolders;
	
	/** Called when the activity is first created. */

	@Override
	public void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		localFolders = (FolderLayout)findViewById(R.id.localfolders);
		localFolders.setIFolderItemListener(this);
            localFolders.setDir("./sys");//change directory if u want,default is root	
		
	}
	
    //Your stuff here for Cannot open Folder
	public void OnCannotFileRead(File file) {
		// TODO Auto-generated method stub
		new AlertDialog.Builder(this)
		.setIcon(R.drawable.icon)
		.setTitle(
				"[" + file.getName()
						+ "] folder can't be read!")
		.setPositiveButton("OK",
				new DialogInterface.OnClickListener() {

					public void onClick(DialogInterface dialog,
							int which) {


					}
				}).show();

	}
    

    //Your stuff here for file Click
	public void OnFileClicked(File file) {
		// TODO Auto-generated method stub
		new AlertDialog.Builder(this)
		.setIcon(R.drawable.icon)
		.setTitle("[" + file.getName() + "]")
		.setPositiveButton("OK",
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog,
							int which) {


					}

				}).show();
	}

}

Import the libraries needed. Hope these help you...

Solution 4 - Android

Was looking for a file/folder browser myself recently and decided to make a new explorer activity (Android library): https://github.com/vaal12/AndroidFileBrowser

Matching Test application https://github.com/vaal12/FileBrowserTestApplication- is a sample how to use.

Allows picking directories and files from phone file structure.

Solution 5 - Android

Adding to the mix: the OI File Manager has a public api registered at openintents.org

http://www.openintents.org/filemanager

http://www.openintents.org/action/org-openintents-action-pick-file/

Solution 6 - Android

I have implemented the Samsung File Selector Dialog, it provides the ability to open, save file, file extension filter, and create new directory in the same dialog I think it worth trying Here is the Link you have to log in to Samsung developer site to view the solution

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAymon FournierView Question on Stackoverflow
Solution 1 - AndroidNathan SchwermannView Answer on Stackoverflow
Solution 2 - AndroidKirill MikhailovView Answer on Stackoverflow
Solution 3 - Androidsonu thomasView Answer on Stackoverflow
Solution 4 - AndroidAlexey VassilievView Answer on Stackoverflow
Solution 5 - AndroidEdward FalkView Answer on Stackoverflow
Solution 6 - AndroidFiras ShrourouView Answer on Stackoverflow