兩個Android選擇文件對話框

這個項目以及代碼中使用的未在下面代碼給出源碼的方法都在這裏:https://github.com/NashLegend/LegendUtils


第二種對話框的源碼在這裏:https://github.com/NashLegend/LegendExplorer/,這是一個文件瀏覽器源碼。




Android文件對話框,一般用的分兩種。

一是我們自己程序內使用的,當我們需要讓用戶選擇一個文件或文件夾進行上傳、下載或者其他操作時有時會用到。

二是系統的全局文件對話框,當一個程序發起一個要選擇的Intent,那麼這個對話框就會彈出,用戶進行操作後返回行距的文件或者文件夾,比如寫一封郵件如果想同時發送一個附件的時候,就會發起一個Intent,然後我們的選擇文件對話框會彈出,讓用戶來選擇文件。


這個文件對話框大約長下面這個樣子(圖標是不是很熟悉,這是直接取的ES文件瀏覽器的圖標),它可以實現文件、文件夾的單選、多選、混選,當用戶點擊確定時,返回一個ArrayList<File>:

wKioL1RQ5zrQlMBgAAHbXXa1Iqc992.jpg


下面是如何寫這個文件對話框。


首先我們需要一個,一個Dialog需要一個view來顯示,也就是我們看到的。我們給它起名FileDialogView。很顯然它需要兩個Button用於確定取消,一個ImageButton用於返回上級,多選的話還要再加一個【全部選擇、全部取消】的CheckBox(上圖爲單選文件夾的示例,所以沒有出現).一個EditText用於顯示當前路徑、以及最重要的——ListView以及它的adapter,我們叫這個adapter爲FileListAdapter。

下面是這個FileDialogView的代碼(這個項目不難,代碼裏面的註釋應該足夠清楚了……)。

/**
 * FileDialog的view
 * 
 * @author NashLegend
 */
public class FileDialogView extends FrameLayout implements OnClickListener,
		OnCheckedChangeListener {

	private FileListAdapter adapter;
	private ListView listView;//文件列表
	private EditText pathText;//當前路徑
	private ImageButton backButton;//返回上級按鈕
	private CheckBox selectAllButton;//全選按鈕

	private int fileMode = FileDialog.FILE_MODE_OPEN_MULTI;//選擇文件方式,默認爲文件、文件夾混選
	private String initialPath = "/";//用來指定剛打開時的目錄,默認爲根目錄

	private Button cancelButton;
	private Button okButton;

	public FileDialogView(Context context) {
		super(context);
		initView(context);
	}

	public FileDialogView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView(context);
	}

	public FileDialogView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initView(context);
	}

	/**
         * 初始化view
         */
	private void initView(Context context) {
		LayoutInflater inflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		inflater.inflate(R.layout.dialog_file, this);

		listView = (ListView) findViewById(R.id.listview_dialog_file);
		pathText = (EditText) findViewById(R.id.edittext_dialog_file_path);
		backButton = (ImageButton) findViewById(R.id.imagebutton_dialog_file_back);
		selectAllButton = (CheckBox) findViewById(R.id.checkbox_dialog_file_all);
		cancelButton = (Button) findViewById(R.id.button_dialog_file_cancel);
		okButton = (Button) findViewById(R.id.button_dialog_file_ok);

		backButton.setOnClickListener(this);
		cancelButton.setOnClickListener(this);
		okButton.setOnClickListener(this);
		selectAllButton.setOnCheckedChangeListener(this);
		pathText.setKeyListener(null);//不需要彈起鍵盤

		adapter = new FileListAdapter(context);
		adapter.setDialogView(this);
		listView.setAdapter(adapter);
	}

	/**
	 * 打開目錄
	 * 
	 * @param file 要打開的文件夾
	 *            
	 */
	public void openFolder(File file) {
		if (!file.exists() || !file.isDirectory()) {
			// 若不存在此目錄,則打開SD卡根目錄
			file = Environment.getExternalStorageDirectory();
		}
		//openFolder用來讀取文件列表詳見FileListAdapter的代碼
		adapter.openFolder(file);
	}

	/**
	 * 打開目錄
	 * 
	 * @param path
	 *            要打開的文件夾路徑
	 */
	public void openFolder(String path) {
		openFolder(new File(path));
	}

	/**
	 * 打開初始目錄
	 */
	public void openFolder() {
		openFolder(initialPath);
	}

	/**
	 * 返回上級目錄
	 */
	private void back2ParentLevel() {
		File file = adapter.getCurrentDirectory();
		// 如果當前目錄不爲空且父目錄不爲空,則打開父目錄
		if (file != null && file.getParentFile() != null) {
			openFolder(file.getParentFile());
		}
	}

	/**
	 * 選中當前目錄所有文件
	 */
	private void selectAll() {
		adapter.selectAll();
	}

	/**
	 * 取消選中當前目錄所有文件
	 */
	private void unselectAll() {
		adapter.unselectAll();
	}

	public void unselectCheckBox() {
		selectAllButton.setOnCheckedChangeListener(null);
		selectAllButton.setChecked(false);
		selectAllButton.setOnCheckedChangeListener(this);
	}

	/**
	 * @return 返回選中的文件列表
	 */
	public ArrayList<File> getSelectedFiles() {
		ArrayList<File> list = new ArrayList<File>();
		if (adapter.getSelectedFiles().size() > 0) {
			list = adapter.getSelectedFiles();
		} else {
		        //如果點擊確定的時候沒有選擇文件並且模式是選擇單個文件夾,那麼就返回當前目錄
			if (fileMode == FileDialog.FILE_MODE_OPEN_FOLDER_SINGLE) {
				list.add(adapter.getCurrentDirectory());
			}
		}
		return list;
	}

	@Override
	public void onClick(View v) {
		int id = v.getId();
		if (id == R.id.imagebutton_dialog_file_back) {
			back2ParentLevel();
		}
	}

	public EditText getPathText() {
		return pathText;
	}

	public int getFileMode() {
		return fileMode;
	}

	public void setFileMode(int fileMode) {
		this.fileMode = fileMode;
		if (fileMode > FileDialog.FILE_MODE_OPEN_FILE_MULTI) {
			// 單選模式應該看不到全選按鈕纔對
			selectAllButton.setVisibility(View.GONE);
		} else {
			selectAllButton.setVisibility(View.VISIBLE);
		}
	}

	public String getInitialPath() {
		return initialPath;
	}

	public void setInitialPath(String initialPath) {
		this.initialPath = initialPath;
	}

	@Override
	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
		if (selectAllButton.isChecked()) {
			selectAll();
		} else {
			unselectAll();
		}
	}

	public CheckBox getSelectAllButton() {
		return selectAllButton;
	}
}

FileDialogView代碼並不多,只負責了構建界面的任務。


下面是FileListAdapter的代碼,FileListAdapter負責讀取文件夾、全選、反選、排序、返回選中文件,數據對象爲FileItem:

package com.example.legendutils.BuildIn;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import com.example.legendutils.Dialogs.FileDialog;
import android.annotation.SuppressLint;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

public class FileListAdapter extends BaseAdapter {
    private ArrayList<FileItem> list = new ArrayList<FileItem>();
    private Context mContext;
    private File currentDirectory;
    private FileDialogView dialogView;

    public FileListAdapter(Context Context) {
        mContext = Context;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = new FileItemView(mContext);
            holder.fileItemView = (FileItemView) convertView;
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.fileItemView.setFileItem(list.get(position), this,
                dialogView.getFileMode());
        return holder.fileItemView;
    }

    class ViewHolder {
        FileItemView fileItemView;
    }

    public ArrayList<FileItem> getList() {
        return list;
    }

    public void setList(ArrayList<FileItem> list) {
        this.list = list;
    }

    /**
     * 打開文件夾,更新文件列表
     * 
     * @param file
     */
    public void openFolder(File file) {
        if (file != null && file.exists() && file.isDirectory()) {
            if (!file.equals(currentDirectory)) {
                // 與當前目錄不同
                currentDirectory = file;
                list.clear();
                File[] files = file.listFiles();
                if (files != null) {
                    for (int i = 0; i < files.length; i++) {
                        File tmpFile = files[i];
			if (tmpFile.isFile()
				&& (dialogView.getFileMode() == FileDialog.FILE_MODE_OPEN_FOLDER_MULTI || dialogView
				    .getFileMode() == FileDialog.FILE_MODE_OPEN_FOLDER_SINGLE)) {
				    //如果只能選擇文件夾並且當前文件不是文件夾,那則跳過
				continue;
			}                   
                        list.add(new FileItem(files[i]));
                    }
                }
                files = null;
                sortList();
                notifyDataSetChanged();
            }
        }
        //改變FileDialogView的當前路徑顯示
        dialogView.getPathText().setText(file.getAbsolutePath());
    }

    /**
     * 選擇當前目錄下所有文件
     */
    public void selectAll() {
        int mode = dialogView.getFileMode();
        if (mode > FileDialog.FILE_MODE_OPEN_FILE_MULTI) {
            // 這個if不會發生,我爲啥要寫……
            return;
        }
        for (Iterator<FileItem> iterator = list.iterator(); iterator.hasNext();) {
            FileItem fileItem = (FileItem) iterator.next();

            if (mode == FileDialog.FILE_MODE_OPEN_FILE_MULTI
                    && fileItem.isDirectory()) {
                // fileItem是目錄,但是隻能選擇文件,則跳過
                continue;
            }
            if (mode == FileDialog.FILE_MODE_OPEN_FOLDER_MULTI
                    && !fileItem.isDirectory()) {
                // fileItem是文件,但是隻能選擇目錄,則跳過
                continue;
            }

            fileItem.setSelected(true);
        }
        notifyDataSetChanged();
    }

    /**
     * 取消所有文件的選中狀態
     */
    public void unselectAll() {
        for (Iterator<FileItem> iterator = list.iterator(); iterator.hasNext();) {
            FileItem fileItem = (FileItem) iterator.next();
            fileItem.setSelected(false);
        }
        notifyDataSetChanged();
    }

    /**
     * 選中一個文件,只在選中時調用,取消選中不調用,且只由FileItemView調用
     * 
     * @param fileItem
     */
    public void selectOne(FileItem fileItem) {
        int mode = dialogView.getFileMode();
        if (mode > FileDialog.FILE_MODE_OPEN_FILE_MULTI) {
            // 如果是單選
            if (mode == FileDialog.FILE_MODE_OPEN_FILE_SINGLE
                    && fileItem.isDirectory()) {
                // fileItem是目錄,但是隻能選擇文件,則返回
                return;
            }
            if (mode == FileDialog.FILE_MODE_OPEN_FOLDER_SINGLE
                    && !fileItem.isDirectory()) {
                // fileItem是文件,但是隻能選擇目錄,則返回
                return;
            }
            for (Iterator<FileItem> iterator = list.iterator(); iterator
                    .hasNext();) {
                FileItem tmpItem = (FileItem) iterator.next();
                if (tmpItem.equals(fileItem)) {
                    tmpItem.setSelected(true);
                } else {
                    tmpItem.setSelected(false);
                }
            }
        } else {
            // 如果是多選
            if (mode == FileDialog.FILE_MODE_OPEN_FILE_MULTI
                    && fileItem.isDirectory()) {
                // fileItem是目錄,但是隻能選擇文件,則返回
                return;
            }
            if (mode == FileDialog.FILE_MODE_OPEN_FOLDER_MULTI
                    && !fileItem.isDirectory()) {
                // fileItem是文件,但是隻能選擇目錄,則返回
                return;
            }
            fileItem.setSelected(true);
        }

        notifyDataSetChanged();
    }

    public void sortList() {
        FileItemComparator comparator = new FileItemComparator();
        Collections.sort(list, comparator);
    }

    /**
     * 取消一個的選擇,其他邏輯都在FileItemView裏面
     */
    public void unselectOne() {
        dialogView.unselectCheckBox();
    }

    /**
     * @return 選中的文件列表
     */
    public ArrayList<File> getSelectedFiles() {
        ArrayList<File> selectedFiles = new ArrayList<File>();
        for (Iterator<FileItem> iterator = list.iterator(); iterator.hasNext();) {
            FileItem file = iterator.next();// 強制轉換爲File
            if (file.isSelected()) {
                selectedFiles.add(file);
            }
        }
        return selectedFiles;
    }

    public class FileItemComparator implements Comparator<FileItem> {

        @Override
        public int compare(FileItem lhs, FileItem rhs) {
            if (lhs.isDirectory() != rhs.isDirectory()) {
                // 如果一個是文件,一個是文件夾,優先按照類型排序
                if (lhs.isDirectory()) {
                    return -1;
                } else {
                    return 1;
                }
            } else {
                // 如果同是文件夾或者文件,則按名稱排序
                return lhs.getName().toLowerCase().compareTo(rhs.getName().toLowerCase());
            }
        }
    }

    public File getCurrentDirectory() {
        return currentDirectory;
    }

    public FileDialogView getDialogView() {
        return dialogView;
    }

    public void setDialogView(FileDialogView dialogView) {
        this.dialogView = dialogView;
    }

}

下面是FileItemView,它是ListView的元素,用來顯示每一個文件。數據對象爲FileItem

/**
 * 文件列表單個item的view
 * 
 * @author NashLegend
 */
public class FileItemView extends FrameLayout implements OnClickListener,
		OnCheckedChangeListener {

	private ImageView icon;//文件圖標
	private TextView title;//文件名
	private CheckBox checkBox;//選擇按鈕
	private ViewGroup rootFileItemView;//FileItemView的xml文件的根view
	private FileListAdapter adapter;
	private int fileMode = FileDialog.FILE_MODE_OPEN_MULTI;
	private boolean selectable = true;

	private FileItem fileItem;

	public FileItemView(Context context) {
		super(context);
		LayoutInflater inflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		inflater.inflate(R.layout.view_file_item, this);
		icon = (ImageView) findViewById(R.id.image_file_icon);
		title = (TextView) findViewById(R.id.text_file_title);
		rootFileItemView = (ViewGroup) findViewById(R.id.rootFileItemView);
		checkBox = (CheckBox) findViewById(R.id.checkbox_file_item_select);
		setOnClickListener(this);
	}

	public FileItem getFileItem() {
		return fileItem;
	}

	public void setFileItem(FileItem fileItem, FileListAdapter adapter,
			int fileMode) {
		this.fileItem = fileItem;
		this.adapter = adapter;
		this.fileMode = fileMode;
		icon.setImageResource(fileItem.getIcon());
		title.setText(fileItem.getName());
		toggleSelectState();

		if (!fileItem.isDirectory()
				&& (fileMode == FileDialog.FILE_MODE_OPEN_FOLDER_MULTI || fileMode == FileDialog.FILE_MODE_OPEN_FOLDER_SINGLE)) {
			//如果選擇模式與當前文件類型不符,則設計爲不可選擇,比如在只可選擇文件平時,文件不可選
			checkBox.setEnabled(false);
			selectable = false;
			checkBox.setOnCheckedChangeListener(null);
			return;
		}

		if (fileItem.isDirectory()
				&& (fileMode == FileDialog.FILE_MODE_OPEN_FILE_MULTI || fileMode == FileDialog.FILE_MODE_OPEN_FILE_SINGLE)) {
			//如果選擇模式與當前文件類型不符,則設計爲不可選擇,比如在只可選擇文件時,文件夾不可選
			checkBox.setEnabled(false);
			selectable = false;
			checkBox.setOnCheckedChangeListener(null);
			return;
		}
		selectable = true;
		checkBox.setEnabled(true);
		checkBox.setOnCheckedChangeListener(this);
	}

	/**
	 * 切換選中、未選中狀態,fileItem.setSelected(boolean)先發生;
	 */
	public void toggleSelectState() {
		if (fileItem.isSelected()) {
			rootFileItemView
					.setBackgroundResource(R.drawable.bg_file_item_select);
		} else {
			rootFileItemView
					.setBackgroundResource(R.drawable.bg_file_item_normal);
		}
		checkBox.setOnCheckedChangeListener(null);
		checkBox.setChecked(fileItem.isSelected());
		checkBox.setOnCheckedChangeListener(this);
	}

	@Override
	public void onClick(View v) {
		if (v.getId() != R.id.checkbox_file_item_select) {
		        //被點擊時,如果是文件夾則打開文件夾,如果是文件則選中文件
			if (fileItem.isDirectory()) {
				openFolder();
			} else {
				// 選中一個
				selectOne();
			}
		}
	}

	public void selectOne() {//選中一個文件(夾)
		if (selectable) {
			if (fileItem.isSelected()) {
				// 取消選中狀態,只在FileItemView就可以
				fileItem.setSelected(!fileItem.isSelected());
				toggleSelectState();
				adapter.unselectOne();
			} else {
				// 如果要選中某個FileItem,則必須要在adapter裏面進行,因爲如果是單選的話,還要取消其他的選中狀態
				adapter.selectOne(fileItem);
			}
		}
	}

	/**
	 * 打開文件夾
	 */
	public void openFolder() {
		adapter.openFolder(fileItem);
	}

	public FileListAdapter getAdapter() {
		return adapter;
	}

	@Override
	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
		if (isChecked) {
			adapter.selectOne(fileItem);
		} else {
			fileItem.setSelected(false);
			rootFileItemView
					.setBackgroundResource(R.drawable.bg_file_item_normal);
			adapter.unselectOne();
		}
	}

	public int getFileMode() {
		return fileMode;
	}
}

上面所使用的數據對象FileItem其實很簡單,只是一個繼承了File,並僅僅多了icon字段和selected字段的類。這裏不寫出來了,詳見上面的地址。


現在有了View,只要把它放到Dialog裏就可以了,Dialog很簡單了,我們仍然依照系統的Dialog寫一個Builder以方便使用。代碼如下:

public class FileDialog extends Dialog {

	/**
	 * 以打開文件模式打開文件對話框,有可能是文件夾也有可能是文件,可多選,最終返回值爲一個File對象列表。
	 */
	public static final int FILE_MODE_OPEN_MULTI = 0;

	/**
	 * 以打開文件模式打開文件對話框,只能選擇文件夾而不是文件,可多選,最終返回值爲一個File對象列表。
	 */
	public static final int FILE_MODE_OPEN_FOLDER_MULTI = 1;

	/**
	 * 以打開文件模式打開文件對話框,只能選擇文件而不是文件夾,可多選,最終返回值爲一個File對象列表。
	 */
	public static final int FILE_MODE_OPEN_FILE_MULTI = 2;

	/**
	 * 以打開文件模式打開文件對話框,有可能是文件夾也有可能是文件,最終返回值爲一個長度爲1的File對象列表。
	 */
	public static final int FILE_MODE_OPEN_SINGLE = 3;

	/**
	 * 以打開文件模式打開文件對話框,只能選擇文件夾而不是文件,最終返回值爲一個長度爲1的File對象列表。
	 */
	public static final int FILE_MODE_OPEN_FOLDER_SINGLE = 4;

	/**
	 * 以打開文件模式打開文件對話框,只能選擇文件而不是文件夾,最終返回值爲一個長度爲1的File對象列表。
	 */
	public static final int FILE_MODE_OPEN_FILE_SINGLE = 5;

	public FileDialog(Context context) {
		super(context);
	}

	public FileDialog(Context context, int theme) {
		super(context, theme);
	}

	public FileDialog(Context context, boolean cancelable,
			OnCancelListener cancelListener) {
		super(context, cancelable, cancelListener);
	}

	public interface FileDialogListener {
		public void onFileSelected(ArrayList<File> files);

		public void onFileCanceled();
	}

	public static class Builder {
		private int fileMode = FileDialog.FILE_MODE_OPEN_MULTI;
		private String initialPath = Environment.getExternalStorageDirectory()
				.getAbsolutePath();
		private FileDialogListener fileSelectListener;
		private FileDialogView dialogView;
		private Context context;
		private boolean canceledOnTouchOutside = true;
		private boolean cancelable = true;
		private String title = "選擇文件";

		public Builder(Context context) {
			this.context = context;
		}

		public Builder setCanceledOnTouchOutside(boolean flag) {
			canceledOnTouchOutside = flag;
			return this;
		}

		public Builder setCancelable(boolean flag) {
			cancelable = flag;
			return this;
		}

		public Builder setFileMode(int fileMode) {
			this.fileMode = fileMode;
			return this;
		}

		public Builder setInitialPath(String initialPath) {
			this.initialPath = initialPath;
			return this;
		}

		public Builder setTitle(String title) {
			this.title = title;
			return this;
		}

		public Builder setFileSelectListener(
				FileDialogListener fileSelectListener) {
			this.fileSelectListener = fileSelectListener;
			return this;
		}

		/**
		 * 必須強制設置dialog的大小,因爲ListView大小必須確定,否則ListView的Adapter的getView會執行很多遍,
		 * 次數取決於listview最終能顯示多少項。
		 * 
		 * @return
		 */
		public FileDialog create(int width, int height) {
			final FileDialog dialog = new FileDialog(context);
			dialogView = new FileDialogView(context);
			dialogView.setFileMode(fileMode);
			dialogView.setInitialPath(initialPath);
			dialogView.openFolder();
			dialog.setTitle(title);
			dialog.setCancelable(cancelable);
			dialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
			dialog.setContentView(dialogView, new LayoutParams(
					LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
			if (width > 0 && height > 0) {
				dialog.getWindow().setLayout(width, height);
			}
			Button okButton = (Button) dialogView
					.findViewById(R.id.button_dialog_file_ok);
			Button cancelButton = (Button) dialogView
					.findViewById(R.id.button_dialog_file_cancel);
			okButton.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {
					// 點擊確定按鈕,返回文件列表
					if (fileSelectListener != null) {
						if (dialogView.getSelectedFiles().size() > 0) {
							fileSelectListener.onFileSelected(dialogView
									.getSelectedFiles());
						} else {
							fileSelectListener.onFileCanceled();
						}
					}
					dialog.dismiss();
				}
			});
			cancelButton.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {
				        //點擊取消按鈕,直接dismiss
					if (fileSelectListener != null) {
						fileSelectListener.onFileCanceled();
					}
					dialog.dismiss();
				}
			});
			return dialog;
		}

		/**
		 * 使得FileDialog大小和activity一樣,在Activity創建完成之前,返回的數字可能不對
		 * 
		 * @param activity
		 * @return
		 */
		public FileDialog create(Activity activity) {
		        //下面這兩個方法是獲得窗口的寬高,方法不在這裏貼出了,詳情見上面給出的項目地址
			int width = DisplayUtil.getWindowWidth(activity);
			int height = DisplayUtil.getWindowHeight(activity);
			return create(width, height);
		}

	}

}


如何使用它:


FileDialog dialog = new FileDialog.Builder(getActivity())
				.setFileMode(FileDialog.FILE_MODE_OPEN_FOLDER_SINGLE)
				.setCancelable(true).setCanceledOnTouchOutside(false)
				.setTitle("selectFolder")
				.setFileSelectListener(new FileDialogListener() {

					@Override
					public void onFileSelected(ArrayList<File> files) {
						if (files.size() > 0) {
							copy2Folder(getSelectedFiles(), files.get(0));
						}
					}

					@Override
					public void onFileCanceled() {
						ToastUtil.showToast(getActivity(), "Copy Cancelled!");
					}
				}).create(getActivity());
		dialog.show();





至於第二種接收系統通知其實在同小異,核心代碼都跟上面一樣,唯一的區別是,它其實是一個Activity,我們叫它PickerActivity,使用了FileDialogView的Activity,而上面的是Dialog……

要接收打開文件的Intent,要在AndroidMenifest.xml的這個Activity節點***冊IntentFilter。如下:

            <intent-filter>
                <action android:name="android.intent.action.GET_CONTENT" />

                <category android:name="android.intent.category.OPENABLE" />
                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="*/*" />
            </intent-filter>

PickerActivity代碼,跟FileDialog基本差不多。

public class PickerActivity extends Activity {

	private FileDialogView pickerView;
	private Button cancelButton;
	private Button okButton;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_picker);
		setTitle("Pick A File");
		Intent intent = getIntent();
		if (intent != null
				&& Intent.ACTION_GET_CONTENT.equals(intent.getAction())) {
			pickerView = (FileDialogView) findViewById(R.id.picker);
			pickerView.setFileMode(FileDialog.FILE_MODE_OPEN_FILE_SINGLE);
			pickerView.setInitialPath(Environment.getExternalStorageDirectory()
					.getAbsolutePath());
			pickerView.openFolder();
			cancelButton = (Button) pickerView
					.findViewById(com.example.legendutils.R.id.button_dialog_file_cancel);
			okButton = (Button) pickerView
					.findViewById(com.example.legendutils.R.id.button_dialog_file_ok);
			cancelButton.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					setResult(RESULT_CANCELED);
					finish();
				}
			});
			okButton.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					ArrayList<File> files = pickerView.getSelectedFiles();
					if (files != null && files.size() > 0) {
						File file = files.get(0);
						Intent intent = new Intent();
						Uri uri = Uri.fromFile(file);
						intent.setData(uri);
						setResult(RESULT_OK, intent);
						finish();
					}
				}
			});
		}

	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章