เลือกไฟล์โต้ตอบ [ปิด]


146

ไม่มีใครรู้ว่าโต้ตอบเลือกไฟล์ที่สมบูรณ์? อาจเป็นไฟล์ที่คุณสามารถกรองไฟล์ทั้งหมดยกเว้นไฟล์ที่มีนามสกุลเฉพาะได้หรือไม่

ฉันไม่พบสิ่งที่มีน้ำหนักเบาพอที่จะนำไปใช้กับโครงการของฉันได้อย่างง่ายดาย ตัวเลือกอื่น ๆ เท่านั้นที่ดูเหมือนว่ากำลังใช้ Intents แบบเปิดของ OI FileManager แต่ต้องการผู้ใช้ที่ติดตั้งตัวจัดการไฟล์ไว้แล้ว

ฉันจะขอบคุณถ้ามีคนสามารถชี้ไดอะล็อกที่อนุญาตให้ผู้ใช้เรียกดูโฟลเดอร์และเลือกไฟล์และส่งคืนพา ธ


5
ถ้าอย่างที่คุณพูด "อินเทอร์เน็ตต้องการตัวอย่าง" นี่เป็นโอกาสของคุณที่จะสร้างขึ้นมาเพื่อจุดประสงค์อันสูงส่ง ดังนั้นไม่ใช่ไซต์ "เช่า coder" ในทางกลับกันหากคุณกำลังพยายามสร้าง / ใช้กล่องโต้ตอบการเลือกไฟล์และพบปัญหานี่คือที่ที่จะมาพร้อมกับคำถามเฉพาะของคุณ
Cal Jacobson

1
ตรวจสอบdreamincode.net/forums/topic/
DroidBot

33
คำถามคือถ้ามีอะไรบางอย่างที่เหมือน ALLREADY อยู่ซึ่งเป็นสิ่งที่ดีเพราะคุณไม่ต้องการที่จะสร้างสิ่งใหม่
Velrok

9
คำถามนี้ไม่ควรปิด ฉันจะโพสต์คำตอบด้วย aFileChooser ( github.com/iPaulPro/aFileChooser ) แต่ทำไม่ได้ดังนั้นหวังว่าผู้ที่ต้องการเห็นความคิดเห็นนี้
Tiago

2
ฉันเห็นด้วยนี่เป็นคำถามที่มีประโยชน์ ฉันหวังว่าจะมีส่วนร่วมในการดำเนินการแบบชั้นเดียวที่ง่ายต่อการตอบคำถาม: ninthavenue.com.au/simple-android-file-chooser
Roger 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" นั่นคือตัวแปรจริงๆแล้วฉันใช้รหัสของคุณและมันไม่สามารถตรวจพบ "สิ่งแวดล้อม" ได้
TRonZ

6
อย่าลืมที่จะเพิ่ม <การใช้งานการอนุญาต android: name = "android.permission.READ_EXTERNAL_STORAGE" /> การอนุญาตให้ Manifest
Zar E Ahmer

73

Thanx 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 / *"); โปรดตอบ
Anitha

ไม่เลยมันง่ายที่จะแก้ไข ปัญหาคือว่า. setFileEndsWith () ไม่ทำงานเลยเพราะรายชื่อไฟล์ได้รับการจัดสรรในตัวสร้าง คุณต้องเปลี่ยนคอนสตรัคเตอร์เพื่อรับอินพุตหลายค่าจากนั้นเปลี่ยนบรรทัด: "boolean endsWith = fileEndsWith! = null? filename.toLowerCase (). endsWith (fileEndsWith): true;" เพื่อให้ตรงกับโครงสร้างข้อมูลใด ๆ ที่คุณใส่อย่างถูกต้องมันเป็นการเปลี่ยนแปลงเล็กน้อย
Tatarize

รายการผู้ฟังที่น่ากลัวเหล่านี้และ fireEvent (FireHandler <OMG>) ดูไม่จำเป็น (บางคนเคยใช้มาก่อน) แต่โค้ดใช้งานได้
18446744073709551615

สวัสดีขอบคุณสำหรับผู้ช่วยที่ดีฉันจะยกเลิกได้อย่างไรแตะที่ด้านนอกนี้ ฉันเพิ่มใน filialog ในวิธีการแสดง แต่ฉันไม่ทำงานสำหรับฉัน
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

กำลังมองหาเบราว์เซอร์ไฟล์ / โฟลเดอร์ด้วยตนเองเมื่อเร็ว ๆ นี้และตัดสินใจที่จะทำกิจกรรม explorer ใหม่ (ห้องสมุด Android): https://github.com/vaal12/AndroidFileBrowser

แอปพลิเคชันทดสอบการจับคู่https://github.com/vaal12/FileBrowserTestApplication- เป็นตัวอย่างวิธีการใช้

ช่วยให้การเลือกไดเรกทอรีและไฟล์จากโครงสร้างไฟล์โทรศัพท์


ตรวจสอบเรื่องนี้ด้วย: stackoverflow.com/a/59104787/3141844
Criss

3

การเพิ่มการผสมผสาน: OI File Manager มี api สาธารณะที่ลงทะเบียนที่ openintents.org

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

ฉันได้ติดตั้ง Samsung File Selector Dialog มันมีความสามารถในการเปิดบันทึกไฟล์ตัวกรองนามสกุลไฟล์และสร้างไดเรกทอรีใหม่ในกล่องโต้ตอบเดียวกันฉันคิดว่ามันน่าลองนี่คือลิงค์ที่ คุณต้องเข้าสู่เว็บไซต์นักพัฒนาของ Samsung เพื่อ ดูวิธีแก้ปัญหา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.