Choisissez la boîte de dialogue de fichier [fermée]

146

Est-ce que quelqu'un connaît une boîte de dialogue de sélection de fichier complète? Peut-être un où vous pouvez filtrer tous les fichiers à l'exception de ceux avec des extensions spécifiques?

Je n'ai rien trouvé d'assez léger pour être implémenté facilement dans l'un de mes projets. La seule autre option semble utiliser les intentions ouvertes d'OI FileManager, mais cela nécessite que l'utilisateur ait déjà installé le gestionnaire de fichiers.

Je serais reconnaissant si quelqu'un pouvait indiquer une boîte de dialogue qui permettrait à l'utilisateur de parcourir les dossiers et de sélectionner un fichier et de renvoyer le chemin.

Aymon Fournier
la source
5
Si, comme vous le dites, «Internet a besoin d'un tel exemple», alors c'est VOTRE opportunité d'en créer un dans un but aussi noble. SO n'est pas un site de "louer un codeur". D'un autre côté, si vous essayez de créer / utiliser une boîte de dialogue de sélection de fichiers et que vous rencontrez des problèmes, c'est ici que vous devez poser votre question spécifique.
Cal Jacobson
1
Vérifiez ce dreamincode.net/forums/topic/…
DroidBot
33
La question est de savoir si quelque chose comme son ALLREADY existe, ce qui est bon, car vous ne voulez pas réinventer le weel.
Velrok
9
Cette question ne doit pas être close. J'allais publier une réponse avec aFileChooser ( github.com/iPaulPro/aFileChooser ) mais je ne peux pas, alors espérons que ceux qui ont besoin de voir ce commentaire.
Tiago
2
Je suis d'accord, c'est une question utile. J'espérais contribuer cette implémentation simple à classe unique aux réponses: ninthavenue.com.au/simple-android-file-chooser
Roger Keays

Réponses:

184

Il vous suffit de remplacer onCreateDialogdans une activité.

//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
la source
4
Ajoutez la possibilité de naviguer dans les dossiers et de monter dans le dossier parent, et vous l'avez compris
Aymon Fournier
48
Si vous ne pouvez pas modifier ce qui précède pour naviguer dans le système de fichiers, je ne sais pas comment vous allez le greffer dans votre application en premier lieu. Quand il a déjà plié les «règles» et écrit le code pour vous, j'espère que vous n'allez pas vraiment détenir la rançon de prime pour cela.
Blumer
6
J'ai modifié le code ci-dessus pour montrer comment inclure les dossiers. Vous devriez pouvoir comprendre le reste. Si vous détectez que le fichier sélectionné est un répertoire dans onClick, définissez simplement le nouveau chemin et appelez à nouveau onCreateDialog.
Nathan Schwermann
1
Hé ce qui est "Environmet", est-ce une variable, en fait j'utilise votre code et il n'est pas capable de détecter ce que "Environnement".
TRonZ
6
N'oubliez pas d'ajouter l'autorisation <uses-permission android: name = "android.permission.READ_EXTERNAL_STORAGE" /> à Manifest
Zar E Ahmer
73

Merci schwiz pour l'idée! Voici la solution modifiée:

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

Utilisez-le sur l'activité onCreate (l'option de sélection de répertoire est commentée):

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
la source
8
Grande classe d'aide! J'ai trouvé un petit problème - lors de la première exécution, loadFileList () ne filtrera pas par extension de fichier, car il ne serait pas encore défini par SetFileEndsWith. J'ai retravaillé le constructeur pour accepter le troisième paramètre fileEnsWith, et l'ai défini dans le constructeur avant l'appel de loadFileList ().
Southerton
salut joli code, merci. ce code peut-il choisir plusieurs formats de fichier, c'est-à-dire fileDialog.setFileEndsWith (". txt", ". pdf"); ou fileDialog.setFileEndsWith ("fle / *"); s'il vous plaît answr
Anitha
Non, mais c'est assez facile à modifier. Le problème est que .setFileEndsWith () ne fonctionne pas du tout, car la liste de fichiers est allouée dans le constructeur. Vous devez changer le constructeur pour accepter plusieurs entrées, puis changer la ligne: "boolean endsWith = fileEndsWith! = Null? Filename.toLowerCase (). EndsWith (fileEndsWith): true;" pour correspondre correctement à la structure de données dans laquelle vous l'avez mise. C'est un changement assez trivial.
Tatarize le
Toutes ces listes d'écouteurs redoutées et fireEvent (FireHandler <OMG>) semblent inutiles (est-ce que quelqu'un les a déjà utilisés?), Mais le code fonctionne.
18446744073709551615
salut, merci pour la grande classe d'aide. Comment puis-je définirCanceledOnTouchOutside pour cela. J'ai ajouté dans fileialog dans la méthode d'exposition mais je ne fonctionne pas pour moi
Dauezevy
15

J'ai créé FolderLayoutce qui peut vous aider. Ce lien m'a aidé

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

}

Et une interface IFolderItemListenerpour ajouter quoi faire quand unfileItem on clique sur un

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
}

Aussi un xml pour définir la ligne

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

Comment utiliser dans votre application

Dans votre xml,

dossiers.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>

Dans votre activité,

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

}

Importez les bibliothèques nécessaires. J'espère que cela vous aidera ...

sonu thomas
la source
merci beaucoup qui fait le travail pour moi, juste une simple activité d'exploration de fichiers sans
ballonnement
5

Je cherchais moi-même un navigateur de fichiers / dossiers récemment et j'ai décidé de créer une nouvelle activité d'exploration (bibliothèque Android): https://github.com/vaal12/AndroidFileBrowser

L'application de test de correspondance https://github.com/vaal12/FileBrowserTestApplication- est un exemple d'utilisation.

Permet de sélectionner des répertoires et des fichiers à partir de la structure de fichiers du téléphone.

Alexey Vassiliev
la source
vérifiez ceci aussi: stackoverflow.com/a/59104787/3141844
Criss
3

Ajout au mix: le gestionnaire de fichiers OI a une API publique enregistrée sur openintents.org

http://www.openintents.org/filemanager

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

Edward Falk
la source
Le lien ci-dessus ne fonctionne plus.
uaaquarius
Oui je sais. Celui qui maintenait openintents.org l'a laissé tomber.
Edward Falk
Merci à Juozas Kontvainis qui a trouvé le nouveau lien.
Edward Falk
Aussi: existe-t-il un moyen de rechercher, ou même de parcourir les intentions enregistrées?
Edward Falk
2

J'ai implémenté la boîte de dialogue du sélecteur de fichiers Samsung, elle offre la possibilité d'ouvrir, d'enregistrer un fichier, de filtrer l'extension de fichier et de créer un nouveau répertoire dans la même boîte de dialogue Je pense que cela vaut la peine d'essayer Voici le lien que vous devez vous connecter au site des développeurs Samsung pour voir la solution

Firas Shrourou
la source