1 // Based on http://code.google.com/p/android-file-dialog/
3 // Copyright (c) 2011, 2012, Alexander Ponomarev <alexander.ponomarev.1@gmail.com>
4 // All rights reserved.
6 // Redistribution and use in source and binary forms, with or without modification,
7 // are permitted provided that the following conditions are met:
9 // Redistributions of source code must retain the above copyright notice, this list
10 // of conditions and the following disclaimer. Redistributions in binary form must
11 // reproduce the above copyright notice, this list of conditions and the following
12 // disclaimer in the documentation and/or other materials provided with the distribution.
13 // Neither the name of the <ORGANIZATION> nor the names of its contributors may be used
14 // to endorse or promote products derived from this software without specific prior
15 // written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
18 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
20 // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
22 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 import java.util.ArrayList;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.TreeMap;
36 import android.app.AlertDialog;
37 import android.app.ListActivity;
38 import android.content.DialogInterface;
39 import android.os.Bundle;
40 import android.view.KeyEvent;
41 import android.view.View;
42 import android.view.View.OnClickListener;
43 import android.widget.Button;
44 import android.widget.ListView;
45 import android.widget.SimpleAdapter;
46 import android.widget.TextView;
48 import com.gst_sdk_tutorials.tutorial_5.R;
51 * Activity para escolha de arquivos/diretorios.
56 public class FileDialog extends ListActivity {
59 * Chave de um item da lista de paths.
61 private static final String ITEM_KEY = "key";
64 * Imagem de um item da lista de paths (diretorio ou arquivo).
66 private static final String ITEM_IMAGE = "image";
71 private static final String ROOT = "/";
74 * Parametro de entrada da Activity: path inicial. Padrao: ROOT.
76 public static final String START_PATH = "START_PATH";
79 * Parametro de entrada da Activity: filtro de formatos de arquivos. Padrao:
82 public static final String FORMAT_FILTER = "FORMAT_FILTER";
85 * Parametro de saida da Activity: path escolhido. Padrao: null.
87 public static final String RESULT_PATH = "RESULT_PATH";
89 private List<String> path = null;
90 private TextView myPath;
91 private ArrayList<HashMap<String, Object>> mList;
93 private Button selectButton;
95 private String parentPath;
96 private String currentPath = ROOT;
98 private String[] formatFilter = null;
100 private File selectedFile;
101 private HashMap<String, Integer> lastPositions = new HashMap<String, Integer>();
104 * Called when the activity is first created. Configura todos os parametros
105 * de entrada e das VIEWS..
108 public void onCreate(Bundle savedInstanceState) {
109 super.onCreate(savedInstanceState);
110 setResult(RESULT_CANCELED, getIntent());
112 setContentView(R.layout.file_dialog_main);
113 myPath = (TextView) findViewById(R.id.path);
115 selectButton = (Button) findViewById(R.id.fdButtonSelect);
116 selectButton.setEnabled(false);
117 selectButton.setOnClickListener(new OnClickListener() {
119 public void onClick(View v) {
120 if (selectedFile != null) {
121 getIntent().putExtra(RESULT_PATH, selectedFile.getPath());
122 setResult(RESULT_OK, getIntent());
128 formatFilter = getIntent().getStringArrayExtra(FORMAT_FILTER);
130 final Button cancelButton = (Button) findViewById(R.id.fdButtonCancel);
131 cancelButton.setOnClickListener(new OnClickListener() {
133 public void onClick(View v) {
134 setResult(RESULT_CANCELED);
141 if (savedInstanceState != null) {
142 startPath = savedInstanceState.getString("currentPath");
144 startPath = getIntent().getStringExtra(START_PATH);
146 startPath = startPath != null ? startPath : ROOT;
149 ListView lv = (ListView) findViewById(android.R.id.list);
150 lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
153 private void getDir(String dirPath) {
155 boolean useAutoSelection = dirPath.length() < currentPath.length();
157 Integer position = lastPositions.get(parentPath);
161 if (position != null && useAutoSelection) {
162 getListView().setSelection(position);
168 * Monta a estrutura de arquivos e diretorios filhos do diretorio fornecido.
173 private void getDirImpl(final String dirPath) {
175 currentPath = dirPath;
177 final List<String> item = new ArrayList<String>();
178 path = new ArrayList<String>();
179 mList = new ArrayList<HashMap<String, Object>>();
181 File f = new File(currentPath);
182 File[] files = f.listFiles();
185 f = new File(currentPath);
186 files = f.listFiles();
188 myPath.setText(getText(R.string.location) + ": " + currentPath);
190 if (!currentPath.equals(ROOT)) {
193 addItem(ROOT, R.drawable.folder);
197 addItem("../", R.drawable.folder);
198 path.add(f.getParent());
199 parentPath = f.getParent();
203 TreeMap<String, String> dirsMap = new TreeMap<String, String>();
204 TreeMap<String, String> dirsPathMap = new TreeMap<String, String>();
205 TreeMap<String, String> filesMap = new TreeMap<String, String>();
206 TreeMap<String, String> filesPathMap = new TreeMap<String, String>();
207 for (File file : files) {
208 if (file.isDirectory()) {
209 String dirName = file.getName();
210 dirsMap.put(dirName, dirName);
211 dirsPathMap.put(dirName, file.getPath());
213 final String fileName = file.getName();
214 final String fileNameLwr = fileName.toLowerCase();
215 // se ha um filtro de formatos, utiliza-o
216 if (formatFilter != null) {
217 boolean contains = false;
218 for (int i = 0; i < formatFilter.length; i++) {
219 final String formatLwr = formatFilter[i].toLowerCase();
220 if (fileNameLwr.endsWith(formatLwr)) {
226 filesMap.put(fileName, fileName);
227 filesPathMap.put(fileName, file.getPath());
229 // senao, adiciona todos os arquivos
231 filesMap.put(fileName, fileName);
232 filesPathMap.put(fileName, file.getPath());
236 item.addAll(dirsMap.tailMap("").values());
237 item.addAll(filesMap.tailMap("").values());
238 path.addAll(dirsPathMap.tailMap("").values());
239 path.addAll(filesPathMap.tailMap("").values());
241 SimpleAdapter fileList = new SimpleAdapter(this, mList,
242 R.layout.file_dialog_row,
243 new String[] { ITEM_KEY, ITEM_IMAGE }, new int[] {
244 R.id.fdrowtext, R.id.fdrowimage });
246 for (String dir : dirsMap.tailMap("").values()) {
247 addItem(dir, R.drawable.folder);
250 for (String file : filesMap.tailMap("").values()) {
251 addItem(file, R.drawable.file);
254 fileList.notifyDataSetChanged();
256 setListAdapter(fileList);
260 private void addItem(String fileName, int imageId) {
261 HashMap<String, Object> item = new HashMap<String, Object>();
262 item.put(ITEM_KEY, fileName);
263 item.put(ITEM_IMAGE, imageId);
268 * Quando clica no item da lista, deve-se: 1) Se for diretorio, abre seus
269 * arquivos filhos; 2) Se puder escolher diretorio, define-o como sendo o
270 * path escolhido. 3) Se for arquivo, define-o como path escolhido. 4) Ativa
274 protected void onListItemClick(ListView l, View v, int position, long id) {
276 File file = new File(path.get(position));
278 if (file.isDirectory()) {
279 selectButton.setEnabled(false);
280 if (file.canRead()) {
281 lastPositions.put(currentPath, position);
282 getDir(path.get(position));
284 new AlertDialog.Builder(this)
285 .setIcon(android.R.drawable.stat_sys_warning)
287 "[" + file.getName() + "] "
288 + getText(R.string.cant_read_folder))
289 .setPositiveButton("OK",
290 new DialogInterface.OnClickListener() {
292 public void onClick(DialogInterface dialog,
299 if (selectedFile != null
300 && selectedFile.getPath().equals(file.getPath())) {
301 getIntent().putExtra(RESULT_PATH, selectedFile.getPath());
302 setResult(RESULT_OK, getIntent());
306 l.setItemChecked(position, true);
307 selectButton.setEnabled(true);
312 public boolean onKeyDown(int keyCode, KeyEvent event) {
313 if ((keyCode == KeyEvent.KEYCODE_BACK)) {
314 selectButton.setEnabled(false);
316 if (!currentPath.equals(ROOT)) {
319 return super.onKeyDown(keyCode, event);
324 return super.onKeyDown(keyCode, event);
329 protected void onSaveInstanceState(Bundle outState) {
330 outState.putString("currentPath", currentPath);
331 super.onSaveInstanceState(outState);