1. Android文件管理器介紹
android系統並不自帶文件管理器,但是很多情況下,我們有諸如從SD中打開文件的需要,就必須借助三方開發的資源管理器,常用的有AndExplorer等。這種情況下發布後,用戶還需要安裝依賴的軟件,非常麻煩。下面介紹在代碼中實現資源管理器,只需要一百行左右的一個類即可以最常用的文件選擇功能。
2. 相關知識
文件管理器一般以固定大小的對話框的方式出現,使用ListView作為文件目錄的顯示載體。點選目錄測進入,點選文件則將所選擇文件的Uri返回給調用它的Activity。ListView的使用是實現這個功能的重點。
3. 例程
1) 功能
當用戶點擊按鈕時,調出固定大小的文件管理器,默認顯示的目錄是SD卡的根目錄。用戶選擇文件後,在界面上顯示該文件的路徑。
2) 可從此處下載可獨立運行的代碼
免費下載地址在 http://linux.linuxidc.com/
用戶名與密碼都是www.linuxidc.com
具體下載目錄在 /pub/Android源碼集錦/2011年/10月/Android文件管理器的源碼實現/
3) 核心代碼及說明
a) 調用資源管理器
Intent intent = new Intent();
intent.putExtra("explorer_title",
getString(R.string.dialog_read_from_dir)); // 設置文件管理器標題
intent.setDataAndType(Uri.fromFile(new File("/sdcard")), "*/*"); // 設置起始文件夾和文件類型
intent.setClass(MyActivity.this, ExDialog.class);
startActivityForResult(intent, REQUEST_EX);
b) 從資源管理器接收數據
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
String path;
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_EX) {
Uri uri = intent.getData(); // 接收用戶所選文件的路徑
TextView text = (TextView) findViewById(R.id.text);
text.setText("select: " + uri); // 在界面上顯示路徑
}
}
}
c) 文件管理器類的實現
public class ExDialog extends ListActivity { // ListActivity自帶List控件
private List<Map<String, Object>> mData;
private String mDir = "/sdcard";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = this.getIntent();
Bundle bl = intent.getExtras();
String title = bl.getString("explorer_title"); // 接收標題內容
Uri uri = intent.getData(); // 接收起始目錄
mDir = uri.getPath(); // 設置起始目錄
setTitle(title);
mData = getData(); // 向鏈表mData填充目錄的數據
MyAdapter adapter = new MyAdapter(this);
setListAdapter(adapter); // 設置MyAdapter類為ListView控件提供數據
WindowManager m = getWindowManager();
Display d = m.getDefaultDisplay();
LayoutParams p = getWindow().getAttributes();
p.height = (int) (d.getHeight() * 0.8);
p.width = (int) (d.getWidth() * 0.95);
getWindow().setAttributes(p); // 設置對話框為固定大小,不因進出目錄變化
}
private List<Map<String, Object>> getData() { // 將目錄數據填充到鏈表中
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
Map<String, Object> map = null;
File f = new File(mDir); // 打開當前目錄
File[] files = f.listFiles(); // 獲取當前目錄中文件列表
if (!mDir.equals("/sdcard")) { // 不充許進入/sdcard上層目錄
map = new HashMap<String, Object>(); // 加返回上層目錄項
map.put("title", "Back to ../");
map.put("info", f.getParent());
map.put("img", R.drawable.ex_folder);
list.add(map);
}
if (files != null) { // 將目錄中文件填加到列表中
for (int i = 0; i < files.length; i++) {
map = new HashMap<String, Object>();
map.put("title", files[i].getName());
map.put("info", files[i].getPath());
if (files[i].isDirectory()) // 按不同類型顯示不同圖標
map.put("img", R.drawable.ex_folder);
else
map.put("img", R.drawable.ex_doc);
list.add(map);
}
}
return list;
}
// 響應用戶點擊列表項的事件
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Log.d("MyListView4-click", (String) mData.get(position).get("info"));
if ((Integer) mData.get(position).get("img") == R.drawable.ex_folder) {
mDir = (String) mData.get(position).get("info");
mData = getData(); //點擊目錄時進入子目錄
MyAdapter adapter = new MyAdapter(this);
setListAdapter(adapter);
} else { // 點擊文件時關閉文件管理器,並將選取結果返回
finishWithResult((String) mData.get(position).get("info"));
}
}
public final class ViewHolder { // 定義每個列表項所含內容
public ImageView img; // 顯示圖片ID
public TextView title; // 文件目錄名
public TextView info; // 文件目錄描述
}
public class MyAdapter extends BaseAdapter { // 實現列表內容適配器
private LayoutInflater mInflater;
public MyAdapter(Context context) {
this.mInflater = LayoutInflater.from(context);
}
public int getCount() { // 獲取列表項個數
return mData.size();
}
public Object getItem(int arg0) {
return null;
}
public long getItemId(int arg0) {
return 0;
}
// 設置每個列表項的顯示
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.listview, null); // 設置列表項的布局
holder.img = (ImageView) convertView.findViewById(R.id.img);
holder.title = (TextView) convertView.findViewById(R.id.title);
holder.info = (TextView) convertView.findViewById(R.id.info);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.img.setBackgroundResource((Integer) Data.get(position).get(
"img")); // 根據位置position設置具體內容
holder.title.setText((String) Data.get(position).get("title"));
holder.info.setText((String) mData.get(position).get("info"));
return convertView;
}
}
private void finishWithResult(String path) {
Bundle conData = new Bundle();
conData.putString("results", "Thanks Thanks");
Intent intent = new Intent(); // 以intent的方式將結果返回調用類
intent.putExtras(conData);
Uri startDir = Uri.fromFile(new File(path));
intent.setDataAndType(startDir,
"vnd.android.cursor.dir/lysesoft.andexplorer.file");
setResult(RESULT_OK, intent);
finish();
}
};