/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.files;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.TextView;
import com.timsu.astrid.R;
import com.todoroo.andlib.utility.DialogUtilities;
/**
* Based on the Android-File-Explore project by Manish Burman
* https://github.com/mburman/Android-File-Explore
*
*/
public class FileExplore extends Activity {
// Stores names of traversed directories
ArrayList<String> str = new ArrayList<String>();
// Check if the first level of the directory structure is the one showing
private Boolean firstLvl = true;
private static final String TAG = "F_PATH"; //$NON-NLS-1$
public static final String RESULT_FILE_SELECTED = "fileSelected"; //$NON-NLS-1$
public static final String RESULT_DIR_SELECTED = "dirSelected"; //$NON-NLS-1$
public static final String EXTRA_DIRECTORIES_SELECTABLE = "directoriesSelectable"; //$NON-NLS-1$
private Item[] fileList;
private File path;
private String chosenFile;
private static final int DIALOG_LOAD_FILE = 1000;
private String upString;
private boolean directoryMode;
private ListAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
path = new File(Environment.getExternalStorageDirectory().toString());
else
path = Environment.getRootDirectory();
loadFileList();
directoryMode = getIntent().getBooleanExtra(EXTRA_DIRECTORIES_SELECTABLE, false);
showDialog(DIALOG_LOAD_FILE);
upString = getString(R.string.file_browser_up);
Log.d(TAG, path.getAbsolutePath());
}
private void loadFileList() {
try {
path.mkdirs();
} catch (SecurityException e) {
DialogUtilities.okDialog(this, getString(R.string.file_browser_err_permissions), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
}
// Checks whether path exists
if (path.exists()) {
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
File sel = new File(dir, filename);
// Filters based on whether the file is hidden or not
return (sel.isFile() || sel.isDirectory())
&& !sel.isHidden();
}
};
String[] fList = path.list(filter);
fileList = new Item[fList.length];
for (int i = 0; i < fList.length; i++) {
fileList[i] = new Item(fList[i], R.drawable.file_icon);
// Convert into file path
File sel = new File(path, fList[i]);
// Set drawables
if (sel.isDirectory()) {
fileList[i].icon = R.drawable.directory_icon;
}
}
if (!firstLvl) {
Item temp[] = new Item[fileList.length + 1];
for (int i = 0; i < fileList.length; i++) {
temp[i + 1] = fileList[i];
}
temp[0] = new Item(upString, R.drawable.directory_up);
fileList = temp;
}
} else {
Log.e(TAG, "path does not exist"); //$NON-NLS-1$
}
adapter = new ArrayAdapter<Item>(this,
android.R.layout.select_dialog_item, android.R.id.text1,
fileList) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// creates view
View view = super.getView(position, convertView, parent);
TextView textView = (TextView) view
.findViewById(android.R.id.text1);
// put the image on the text view
textView.setCompoundDrawablesWithIntrinsicBounds(
fileList[position].icon, 0, 0, 0);
// add margin between image and text (support various screen
// densities)
int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
textView.setCompoundDrawablePadding(dp5);
return view;
}
};
}
private class Item {
public String file;
public int icon;
public Item(String file, Integer icon) {
this.file = file;
this.icon = icon;
}
@Override
public String toString() {
return file;
}
}
@Override
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
AlertDialog.Builder builder = new Builder(this);
if (fileList == null) {
dialog = builder.create();
return dialog;
}
switch (id) {
case DIALOG_LOAD_FILE:
builder.setTitle(getString(directoryMode ? R.string.dir_browser_title : R.string.file_browser_title));
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface d, int which) {
chosenFile = fileList[which].file;
File sel = new File(path + File.separator + chosenFile);
if (sel.isDirectory()) {
firstLvl = false;
// Adds chosen directory to list
str.add(chosenFile);
fileList = null;
path = new File(sel.toString());
loadFileList();
removeDialog(DIALOG_LOAD_FILE);
showDialog(DIALOG_LOAD_FILE);
} else if (chosenFile.equals(upString) && !sel.exists()) { // Checks if 'up' was clicked
// present directory removed from list
String s = str.remove(str.size() - 1);
// path modified to exclude present directory
path = new File(path.toString().substring(0,
path.toString().lastIndexOf(s)));
fileList = null;
// if there are no more directories in the list, then
// its the first level
if (str.isEmpty()) {
firstLvl = true;
}
loadFileList();
removeDialog(DIALOG_LOAD_FILE);
showDialog(DIALOG_LOAD_FILE);
} else {
Intent result = new Intent();
if (directoryMode) {
result.putExtra(RESULT_DIR_SELECTED, path.getAbsolutePath());
} else {
result.putExtra(RESULT_FILE_SELECTED, sel.getAbsolutePath());
}
setResult(RESULT_OK, result);
removeDialog(DIALOG_LOAD_FILE);
finish();
}
}
});
break;
}
if (directoryMode) {
builder.setPositiveButton(R.string.file_dir_dialog_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface d, int which) {
Intent result = new Intent();
result.putExtra(RESULT_DIR_SELECTED, path.getAbsolutePath());
setResult(RESULT_OK, result);
removeDialog(DIALOG_LOAD_FILE);
finish();
}
});
builder.setNegativeButton(R.string.file_dir_dialog_default, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface d, int which) {
Intent result = new Intent();
result.putExtra(RESULT_DIR_SELECTED, ""); //$NON-NLS-1$
setResult(RESULT_OK, result);
removeDialog(DIALOG_LOAD_FILE);
finish();
}
});
}
dialog = builder.show();
dialog.setCancelable(true);
dialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface d) {
finish();
}
});
return dialog;
}
}