Оберіть діалогове вікно файлу [закрито]


146

Хтось знає про повне діалогове вікно вибору файлів? Можливо, там, де ви можете відфільтрувати всі файли, крім файлів із конкретним розширенням?

Я не знайшов нічого легкого, щоб легко втілитись в один із своїх проектів. Єдиним іншим варіантом, здається, є використання відкритих намірів OI FileManager, але для цього потрібно, щоб користувач вже встановив менеджер файлів.

Буду вдячний, якби хтось міг вказати Діалог, який дозволить користувачу переглядати папки та вибирати файл та повертати шлях.


5
Якщо, як ви кажете, "Інтернету потрібен такий приклад", то це ВАША можливість створити його для такої благородної мети. ТАК не є сайтом "орендувати кодер". З іншого боку, якщо ви намагаєтеся створити / використати діалог вибору файлів і зіткнутися з проблемами, то це місце, з яким ви маєте вирішити конкретний питання.
Cal Jacobson

1
перевірити цей dreamincode.net/forums/topic/…
DroidBot

33
Питання полягає в тому, чи існує щось подібне до ALLREADY, що є хорошим, тому що ви не хочете винаходити крок.
Велрок

9
Це питання не слід закривати. Я збирався опублікувати відповідь за допомогою aFileChooser ( github.com/iPaulPro/aFileChooser ), але не можу, тому сподіваємось, хто потребує цього коментаря.
Тіаго

2
Я згоден, це корисне питання. Я сподівався сприяти цій простої однокласної реалізації у відповідях: ninthavenue.com.au/simple-android-file-chooser
Роджер

Відповіді:


184

Потрібно просто перекрити onCreateDialogдіяльність.

//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;
}

4
Додайте можливість орієнтуватися по папках та переходити до батьківської папки, і ви отримали її
Еймон Фурньє,

48
Якщо ви не можете змінити вищевикладене для навігації по файловій системі, я не знаю, як ви в першу чергу прищепите її до свого додатка. Коли він вже схилив «правила» і написав код для вас, я впевнений, що ви насправді не збираєтесь утримувати викуп за це.
Блюмер

6
Я редагував код вище, щоб показати, як включити папки. Ви повинні мати можливість з'ясувати решту. Якщо ви виявите, що натиснутий файл - це каталог у onClick, просто встановіть новий шлях і зателефонуйте onCreateDialog ще раз.
Натан Шверман

1
Ей, що "Environmentmet", це те, що змінна, насправді я використовую ваш код, і він не в змозі виявити, що "середовище".
TRonZ

6
Не забудьте додати <використання-дозволу android: name = "android.permission.READ_EXTERNAL_STORAGE" /> дозвіл на Manifest
Zar E Ahmer

73

Спасибі за ідею! Ось модифіковане рішення:

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;
    }
}

Використовуйте його в активі onCreate (коментується параметр вибору каталогу):

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();
}

8
Чудовий клас помічників! Я знайшов один невеликий глюк - при першому запуску loadFileList () не буде фільтруватися за розширенням файлу, тому що він ще не встановив SetFileEndsWith. Я переробив конструктор, щоб прийняти третій параметр fileEnsWith, і встановив його в конструктор перед викликом loadFileList ().
Саутертон

привіт хороший код, спасибі чи може цей код вибрати декілька форматів файлів, тобто fileDialog.setFileEndsWith (". txt", ". pdf"); або fileDialog.setFileEndsWith ("fle / *"); будь ласка, answr
Аніта

Ні. Але це легко змінити. Проблема полягає в тому, що .setFileEndsWith () взагалі не працює, оскільки список файлів виділений у конструкторі. Вам потрібно змінити конструктор, щоб прийняти декілька вхідних даних, а потім змінити рядок: "boolean endWith = fileEndsWith! = Null? Filename.toLowerCase (). належним чином відповідати будь-якій структурі даних, яку ви вводите. Це досить тривіальна зміна.
Татариза

Усі ці жахливі списки слухачів і fireEvent (FireHandler <OMG>) виглядають непотрібними (чи хтось колись ними користувався?), Але код працює.
18446744073709551615

привіт, дякую за чудовий клас помічників. Як я можу встановитиCanceledOnTouchOutside для цього. Я додав у filedialog метод шоу, але я не працюю для мене
Dauezevy

15

Я створив, FolderLayoutщо може вам допомогти. Це посилання мені допомогло

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);
    }

}

І інтерфейс, IFolderItemListenerщоб додати, що робити, коли afileItem натисканні на

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
}

Також xml для визначення рядка

рядок.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"/>

Як використовувати у своїй програмі

У вашому 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>

У своїй діяльності

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();
    }

}

Імпортуйте потрібні бібліотеки. Сподіваюся, вони допоможуть вам ...


велике спасибі, що робить для мене роботу, просто простий файл, що вивчає діяльність без зайвого роздуття
Mike76

5

Нещодавно шукав веб-переглядач файлів / папок і вирішив здійснити нову діяльність в досліднику (бібліотека Android): https://github.com/vaal12/AndroidFileBrowser

Програма для відповідності тесту https://github.com/vaal12/FileBrowserTestApplication - це зразок використання.

Дозволяє вибирати каталоги та файли із структури файлів телефону.


перевірити це також: stackoverflow.com/a/59104787/3141844
Criss

3

Додавання до суміші: у менеджера файлів OI є публічна api, зареєстрована на openintents.org

http://www.openintents.org/filemanager

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


Наведене вище посилання вже не працює.
uaaquarius

Так, я знаю. Хто підтримував openintents.org, дозволив йому зламатись.
Едвард Фолк

Дякую Юозасу Контвайнісу, який з’ясував нове посилання.
Едвард Фолк

Також: чи існує спосіб пошуку або навіть перегляду зареєстрованих намірів?
Едвард Фолк

2

Я реалізував діалогове вікно вибору файлів Samsung, він надає можливість відкривати, зберігати файл, фільтр розширення файлів та створювати новий каталог у тому ж діалоговому вікні. Я думаю, що варто спробувати Ось посилання, на яке ви повинні увійти на сайт розробників Samsung, щоб переглянути рішення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.