Chọn hộp thoại tệp [đã đóng]


146

Có ai biết một hộp thoại chọn tập tin hoàn chỉnh? Có lẽ một trong những nơi bạn có thể lọc ra tất cả các tệp ngoại trừ những tệp có phần mở rộng cụ thể?

Tôi đã không tìm thấy bất cứ điều gì đủ nhẹ để thực hiện dễ dàng vào một trong các dự án của tôi. Tùy chọn duy nhất khác dường như đang sử dụng các ý định mở của OI File Manager, nhưng điều đó đòi hỏi người dùng đã cài đặt trình quản lý tệp.

Tôi sẽ biết ơn nếu ai đó có thể chỉ ra Hộp thoại cho phép người dùng duyệt các thư mục và chọn một tệp và trả về đường dẫn.


5
Nếu, như bạn nói, "Internet cần một ví dụ như vậy", thì đây là cơ hội CỦA BẠN để tạo ra một mục đích cao cả như vậy. SO không phải là một trang web "thuê một coder". Mặt khác, nếu bạn đang cố gắng xây dựng / sử dụng hộp thoại chọn tệp và gặp sự cố, thì đây là nơi đi kèm với câu hỏi cụ thể của bạn.
Cal Jacobson


33
Câu hỏi đặt ra là liệu cái gì đó giống như ALLREADY của nó tồn tại, đó là một thứ tốt, bởi vì bạn không muốn phát minh lại con trăn.
Velrok

9
Câu hỏi này không nên được đóng lại. Tôi sẽ đăng câu trả lời với aFileChooser ( github.com/iPaulPro/aFileChooser ) nhưng không thể, vì vậy hãy hy vọng những ai cần xem bình luận này.
Tiago

2
Tôi đồng ý, đây là một câu hỏi hữu ích. Tôi đã hy vọng đóng góp việc thực hiện một lớp đơn giản này cho các câu trả lời: ninthavenue.com.au/simple-android-file-chooser
Roger Keays

Câu trả lời:


184

Bạn chỉ cần ghi đè onCreateDialogtrong một Hoạt động.

//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
Thêm khả năng điều hướng các thư mục và đi đến thư mục mẹ và bạn đã có nó
Aymon Fournier

48
Nếu bạn không thể sửa đổi phần trên để điều hướng hệ thống tệp, tôi sẽ không biết bạn sẽ ghép nó vào ứng dụng của bạn như thế nào ngay từ đầu. Khi anh ấy đã bẻ cong "quy tắc" và viết mã cho bạn, tôi chắc chắn hy vọng bạn sẽ không thực sự giữ tiền chuộc cho việc đó.
Blumer

6
Tôi đã chỉnh sửa mã ở trên để hiển thị cách bao gồm các thư mục. Bạn sẽ có thể tìm ra phần còn lại. Nếu bạn phát hiện ra rằng tệp được nhấn là một thư mục trong onClick, chỉ cần đặt đường dẫn mới và gọi lại onCreateDialog.
Nathan Schwermann

1
Xin chào "Envirmet", đó có phải là một biến không, thực ra tôi đang sử dụng mã của bạn và nó không thể phát hiện ra "Môi trường" là gì.
TRonZ

6
Đừng quên thêm <used-allow android: name = "ERIC.READ_EXTERNAL_STORAGE" /> quyền vào Manifest
Zar E Ahmer

73

Thanx schwiz cho ý tưởng! Đây là giải pháp sửa đổi:

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

Sử dụng nó trên hoạt động onCreate (tùy chọn lựa chọn thư mục được nhận xét):

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
Lớp người trợ giúp tuyệt vời! Tôi đã tìm thấy một trục trặc nhỏ - trong lần chạy đầu tiên loadFileList () sẽ không lọc theo phần mở rộng tệp, bởi vì nó sẽ không được SetFileEndsWith đặt. Tôi đã làm lại hàm tạo để chấp nhận tệp tham số thứ baEnsWith và đặt nó trong hàm tạo trước lệnh gọi loadFileList ().
southerton

chào mã đẹp, cảm ơn. mã này có thể chọn nhiều định dạng tệp, ví dụ fileDialog.setFileEndsWith (". txt", ". pdf"); hoặc fileDialog.setFileEndsWith ("fle / *"); vui lòng trả lời
Anitha

Không. Nhưng, nó khá dễ sửa đổi. Vấn đề là .setFileEndsWith () hoàn toàn không hoạt động, vì danh sách tệp được phân bổ trong hàm tạo. Bạn cần thay đổi hàm tạo để chấp nhận nhiều đầu vào và sau đó thay đổi dòng: "boolean endWith = fileEndsWith! = Null? Filename.toLowerCase (). EndWith (fileEndsWith): true;" để phù hợp với bất kỳ cấu trúc dữ liệu nào bạn đặt vào. Đó là một thay đổi khá nhỏ.
Tatarize

Tất cả các danh sách người nghe đáng sợ và fireEvent (FireHandler <OMG>) trông không cần thiết (có ai đã từng sử dụng chúng chưa?), Nhưng mã hoạt động.
18446744073709551615

xin chào, cảm ơn vì lớp người trợ giúp tuyệt vời. Làm thế nào tôi có thể thiết lập HủyedOnTouchOutside cho việc này. Tôi đã thêm vào tệpialialog trong phương thức hiển thị nhưng tôi không làm việc cho tôi
Dauezevy

15

Tôi đã tạo ra FolderLayoutcó thể giúp bạn. Liên kết này đã giúp tôi

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>

Thư mụcLayout.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);
    }

}

Và một Giao diện IFolderItemListenerđể thêm những việc cần làm khi fileItemnhấp vào

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
}

Cũng là một xml để xác định hàng

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"/>

Cách sử dụng trong ứng dụng của bạn

Trong xml của bạn,

thư mục

<?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>

Trong hoạt động của bạn,

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

}

Nhập các thư viện cần thiết. Hy vọng những điều này sẽ giúp bạn ...


cảm ơn bạn rất nhiều, đó là công việc giúp tôi, chỉ là một hoạt động khám phá tập tin đơn giản mà không có bất kỳ sự phình to không cần thiết nào
Mike76

5

Gần đây tôi đã tìm kiếm một trình duyệt tệp / thư mục và quyết định thực hiện một hoạt động thám hiểm mới (thư viện Android): https://github.com/vaal12/AndroidFileBrowser

Ứng dụng Kiểm tra đối sánh https://github.com/vaal12/FileBrowserTestApplication- là một mẫu cách sử dụng.

Cho phép chọn thư mục và tập tin từ cấu trúc tập tin điện thoại.


cũng kiểm tra điều này: stackoverflow.com/a/59104787/3141844
Criss

3

Thêm vào hỗn hợp: Trình quản lý tệp OI có một api công khai được đăng ký tại openintents.org

http://www.openintents.org/filemanager

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


Các liên kết trên không hoạt động nữa.
uaaquarius

Vâng tôi biết. Bất cứ ai đang duy trì openintents.org đều để nó bị hỏng.
Edward Falk

Cảm ơn Juozas Kontvainis, người đã tìm ra liên kết mới.
Edward Falk

Ngoài ra: có cách nào để tìm kiếm, hoặc thậm chí duyệt các ý định đã đăng ký không?
Edward Falk

2

Tôi đã triển khai Hộp thoại Samsung File Selector, nó cung cấp khả năng mở, lưu tệp, bộ lọc mở rộng tệp và tạo thư mục mới trong cùng hộp thoại Tôi nghĩ rằng nó đáng để thử Đây là Liên kết bạn phải đăng nhập vào trang web của nhà phát triển Samsung để xem giải pháp

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.