Wählen Sie Dateidialog [geschlossen]

146

Kennt jemand einen vollständigen Dialog zum Auswählen von Dateien? Vielleicht eine, bei der Sie alle Dateien außer denen mit bestimmten Erweiterungen herausfiltern können?

Ich habe nichts gefunden, das leicht genug ist, um es einfach in eines meiner Projekte zu implementieren. Die einzige andere Option scheint die Verwendung der offenen Absichten von OI FileManager zu sein. Dies setzt jedoch voraus, dass der Benutzer den Dateimanager bereits installiert hat.

Ich wäre dankbar, wenn jemand auf einen Dialog hinweisen könnte, der es dem Benutzer ermöglicht, Ordner zu durchsuchen, eine Datei auszuwählen und den Pfad zurückzugeben.

Aymon Fournier
quelle
5
Wenn, wie Sie sagen, "das Internet ein solches Beispiel braucht", dann ist dies IHRE Gelegenheit, eines für einen so noblen Zweck zu schaffen. SO ist keine "Rent a Coder" -Seite. Wenn Sie jedoch versuchen, einen Dateiauswahldialog zu erstellen / zu verwenden und auf Probleme stoßen, ist dies der richtige Ort für Ihre spezielle Frage.
Cal Jacobson
1
Überprüfen Sie diese dreamincode.net/forums/topic/…
DroidBot
33
Die Frage ist, ob so etwas wie ALLREADY existiert, was gut ist, weil Sie das Weel nicht neu erfinden wollen.
Velrok
9
Diese Frage sollte nicht geschlossen werden. Ich wollte eine Antwort mit aFileChooser ( github.com/iPaulPro/aFileChooser ) posten , kann es aber nicht. Hoffen wir also, dass diejenigen, die diesen Kommentar benötigen, ihn sehen.
Tiago
2
Ich stimme zu, das ist eine nützliche Frage. Ich hatte gehofft, diese einfache Implementierung in einer einzigen Klasse zu den Antworten beitragen zu können
Roger Keays

Antworten:

184

Sie müssen nur onCreateDialogeine Aktivität überschreiben .

//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;
}
Nathan Schwermann
quelle
4
Fügen Sie die Möglichkeit hinzu, in Ordnern zu navigieren und zum übergeordneten Ordner zu wechseln, und Sie haben es
Aymon Fournier
48
Wenn Sie das oben Gesagte nicht ändern können, um im Dateisystem zu navigieren, weiß ich nicht, wie Sie es überhaupt in Ihre App integrieren sollen. Wenn er bereits die "Regeln" gebogen und den Code für Sie geschrieben hat, hoffe ich, dass Sie das Kopfgeld-Lösegeld dafür nicht wirklich halten werden.
Blumer
6
Ich habe den obigen Code bearbeitet, um zu zeigen, wie die Ordner eingeschlossen werden. Sie sollten in der Lage sein, den Rest herauszufinden. Wenn Sie feststellen, dass die gedrückte Datei ein Verzeichnis in onClick ist, legen Sie einfach den neuen Pfad fest und rufen Sie onCreateDialog erneut auf.
Nathan Schwermann
1
Hey, was ist "Environmet", ist das eine Variable, eigentlich verwende ich Ihren Code und es ist nicht in der Lage zu erkennen, was "Umgebung" ist.
TRonZ
6
Vergessen Sie nicht, dem Manifest
Zar E Ahmer
73

Danke schwiz für die Idee! Hier ist modifizierte Lösung:

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

Verwenden Sie es für die Aktivität onCreate (Verzeichnisauswahloption ist kommentiert):

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();
}
Kirill Mikhailov
quelle
8
Tolle Helferklasse! Ich habe einen kleinen Fehler gefunden: Beim ersten Start wird loadFileList () nicht nach Dateierweiterung gefiltert, da es noch nicht von SetFileEndsWith festgelegt wurde. Ich habe den Konstruktor überarbeitet, um den dritten Parameter fileEnsWith zu akzeptieren, und ihn vor dem Aufruf von loadFileList () im Konstruktor festgelegt.
Southton
Hallo netter Code, danke. Kann dieser Code mehrere Dateiformate auswählen, z. B. fileDialog.setFileEndsWith (". txt", ". pdf")? oder fileDialog.setFileEndsWith ("fle / *"); Bitte antworten Sie
Anitha
Nein, aber es ist ziemlich einfach zu ändern. Das Problem ist, dass .setFileEndsWith () überhaupt nicht funktioniert, da die Dateiliste im Konstruktor zugewiesen ist. Sie müssen den Konstruktor ändern, um mehrere Eingaben zu akzeptieren, und dann die Zeile ändern: "boolean EndsWith = fileEndsWith! = Null? Dateiname.toLowerCase (). EndsWith (fileEndsWith): true;" Es ist eine ziemlich triviale Änderung, um die Datenstruktur, in die Sie sie eingefügt haben, richtig abzugleichen.
Tatarize
Alle diese gefürchteten Listener und fireEvent (FireHandler <OMG>) sehen unnötig aus (hat sie jemals jemand verwendet?), Aber der Code funktioniert.
18446744073709551615
Hallo, danke für die tolle Helferklasse. Wie kann ichCanceledOnTouchOutside dafür einstellen? Ich habe im Felddialog in der Show-Methode hinzugefügt, aber ich arbeite nicht für mich
Dauezevy
15

Ich habe geschaffen, FolderLayoutwas Ihnen helfen kann. Dieser Link hat mir geholfen

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

}

Und eine Schnittstelle, IFolderItemListenerum hinzuzufügen, was zu tun ist, wenn afileItem geklickt wird

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
}

Auch eine XML zum Definieren der Zeile

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

Verwendung in Ihrer Anwendung

In Ihrer 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>

In Ihrer Aktivität,

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

}

Importieren Sie die benötigten Bibliotheken. Hoffe diese helfen dir ...

sonu thomas
quelle
Vielen Dank, das macht den Job für mich, nur eine einfache Datei Erkundung Aktivität ohne unnötiges
Aufblähen
5

Ich habe kürzlich selbst nach einem Datei- / Ordnerbrowser gesucht und mich für eine neue Explorer-Aktivität (Android-Bibliothek) entschieden: https://github.com/vaal12/AndroidFileBrowser

Die passende Testanwendung https://github.com/vaal12/FileBrowserTestApplication- ist ein Beispiel für die Verwendung.

Ermöglicht das Auswählen von Verzeichnissen und Dateien aus der Telefondateistruktur.

Alexey Vassiliev
quelle
Überprüfen Sie dies auch: stackoverflow.com/a/59104787/3141844
Criss
3

Hinzufügen zum Mix: Der OI File Manager verfügt über eine öffentliche API, die unter openintents.org registriert ist

http://www.openintents.org/filemanager

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

Edward Falk
quelle
Der obige Link funktioniert nicht mehr.
Uaaquarius
Ja, ich weiß. Wer openintents.org gepflegt hat, hat es kaputt machen lassen.
Edward Falk
Vielen Dank an Juozas Kontvainis, der den neuen Link herausgefunden hat.
Edward Falk
Außerdem: Gibt es eine Möglichkeit, die registrierten Absichten zu suchen oder sogar zu durchsuchen?
Edward Falk
2

Ich habe das Samsung-Dateiauswahldialogfeld implementiert. Es bietet die Möglichkeit, Dateien zu öffnen, zu speichern, Dateierweiterungen zu filtern und neue Verzeichnisse in demselben Dialogfeld zu erstellen. Ich denke, es lohnt sich, es auszuprobieren. Hier ist der Link, bei dem Sie sich bei der Samsung-Entwicklerseite anmelden müssen Lösung anzeigen

Firas Shrourou
quelle