파일 대화 상자를 선택하십시오.


146

완전한 파일 선택 대화 상자를 아는 사람이 있습니까? 특정 확장자를 가진 파일을 제외한 모든 파일을 걸러 낼 수있는 곳이 있습니까?

내 프로젝트 중 하나에 쉽게 구현할 수있을 정도로 가벼운 것을 찾지 못했습니다. 유일한 다른 옵션은 OI FileManager의 열린 의도를 사용하는 것으로 보이지만 사용자에게 이미 파일 관리자가 설치되어 있어야합니다.

사용자가 폴더를 탐색하고 파일을 선택하고 경로를 반환 할 수있는 대화 상자를 지적 할 수 있다면 감사 할 것입니다.


5
"인터넷에 그러한 예가 필요하다"고한다면, 그러한 고귀한 목적을 위해 인터넷을 만들 수있는 기회입니다. SO는 "코더 대여"사이트가 아닙니다. 반면에 파일 선택 대화 상자를 작성 / 사용하려고 시도하고 문제가 발생하면 여기에 특정 질문이 있습니다.
Cal Jacobson


33
문제는 ALLREADY와 같은 것이 존재하는 경우입니다. 이는 웰을 재발 명하고 싶지 않기 때문에 좋은 것입니다.
Velrok

9
이 질문은 종결되어서는 안됩니다. aFileChooser ( github.com/iPaulPro/aFileChooser ) 로 답변을 게시하려고 했지만 그렇게 할 수 없으므로이 의견을 보길 바랍니다.
Tiago

2
동의합니다. 이것은 유용한 질문입니다. 나는 대답이 간단한 단일 클래스 구현에 기여하기 위해 기대했다 : ninthavenue.com.au/simple-android-file-chooser
로저 Keays

답변:


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
폴더를 탐색하고 상위 폴더로 이동하는 기능을 추가하면 폴더를 얻을 수 있습니다.
Aymon Fournier

48
파일 시스템을 탐색하기 위해 위의 내용을 수정할 수 없다면 처음에 앱에 파일을 이식하는 방법을 모르겠습니다. 그가 이미 "규칙"을 구부리고 당신을 위해 코드를 작성했을 때, 나는 당신이 그 현상금 몸값을 실제로 보유하지 않기를 바랍니다.
Blumer

6
폴더를 포함하는 방법을 보여주기 위해 위의 코드를 편집했습니다. 나머지는 알아낼 수 있어야합니다. 누른 파일이 onClick의 디렉토리임을 감지하면 새 경로를 설정하고 onCreateDialog를 다시 호출하십시오.
Nathan Schwermann

1
"Environmet"이란 변수는 실제로 코드를 사용하고 있으며 "Environment"가 무엇인지 감지 할 수 없다는 것입니다.
TRonZ

6
Manifest에 <uses-permission android : name = "android.permission.READ_EXTERNAL_STORAGE"/> 권한을 추가하는 것을 잊지 마십시오
Zar E Ahmer

73

아이디어를위한 감사합니다 schwiz! 다음은 수정 된 솔루션입니다.

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 () 호출 전에 생성자에서 설정하도록 생성자를 재 작업했습니다.
Southerton

안녕하세요 좋은 코드, 감사합니다. 이 코드는 여러 파일 형식을 선택할 수 있습니다. 즉 fileDialog.setFileEndsWith ( ". txt", ". pdf"); 또는 fileDialog.setFileEndsWith ( "fle / *"); answr
Anitha

아니요. 그러나 수정하기는 매우 쉽습니다. 문제는 파일 목록이 생성자에 할당되어 있기 때문에 .setFileEndsWith ()가 전혀 작동하지 않는다는 것입니다. 여러 입력을 허용하도록 생성자를 변경 한 다음 행을 변경해야합니다. "boolean endsWith = fileEndsWith! = null? filename.toLowerCase (). endsWith (fileEndsWith) : true;" 데이터 구조에 상관없이 정확하게 일치시킬 수 있습니다. 아주 간단한 변화입니다.
Tatarize

이 두려운 청취자 목록과 fireEvent (FireHandler <OMG>)는 모두 불필요하게 보이지만 (누군가 사용 했습니까?) 코드는 작동합니다.
18446744073709551615

안녕하세요, 훌륭한 도우미 수업에 감사드립니다 .CanceledOnTouchOutside를 어떻게 설정할 수 있습니까? 나는 show 메소드에서 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할 때 수행 할 작업을 추가 하는 인터페이스fileItem

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

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

응용 프로그램에서 사용하는 방법

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 파일 관리자는 openintents.org에 공개 API를 등록했습니다.

http://www.openintents.org/filemanager

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


위의 링크는 더 이상 작동하지 않습니다.
uaaquarius

예, 알아요 openintents.org를 관리하는 사람은 누구나 그것을 무너 뜨 렸습니다.
Edward Falk

새로운 링크를 찾은 Juozas Kontvainis에게 감사드립니다.
Edward Falk

또한 : 등록 된 의도를 검색하거나 탐색 할 수있는 방법이 있습니까?
Edward Falk

2

내가 선택기 대화 상자 삼성 파일을 구현, 파일 저장 열 수있는 기능, 파일 확장자 필터를 제공하고, 나는 그것이 가치가 여기하려고 생각 같은 대화 상자에서 새 디렉토리를 생성 링크 당신이 삼성 개발자 사이트에 로그인해야 해결책을보십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.