轉(zhuǎn)載請(qǐng)注明作者及出處: http://blog.csdn.net/xieyan0811 1. android文件管理器介紹 android系統(tǒng)并不自帶文件管理器,但是很多情況下,我們有諸如從SD中打開文件的需要,就必須借助三方開發(fā)的資源管理器,常用的有AndExplorer等。這種情況下發(fā)布后,用戶還需要安裝依賴的軟件,非常麻煩。下面介紹在代碼中實(shí)現(xiàn)資源管理器,只需要一百行左右的一個(gè)類即可以最常用的文件選擇功能。 2. 相關(guān)知識(shí) 文件管理器一般以固定大小的對(duì)話框的方式出現(xiàn),使用ListView作為文件目錄的顯示載體。點(diǎn)選目錄測(cè)進(jìn)入,點(diǎn)選文件則將所選擇文件的Uri返回給調(diào)用它的Activity。ListView的使用是實(shí)現(xiàn)這個(gè)功能的重點(diǎn)。 3. 例程 1) 功能 當(dāng)用戶點(diǎn)擊按鈕時(shí),調(diào)出固定大小的文件管理器,默認(rèn)顯示的目錄是SD卡的根目錄。用戶選擇文件后,在界面上顯示該文件的路徑。 2) 可從此處下載可獨(dú)立運(yùn)行的代碼 http://download.csdn.net/source/3423094 3) 核心代碼及說明 a) 調(diào)用資源管理器 Intent intent = new Intent(); intent.putExtra("explorer_title", getString(R.string.dialog_read_from_dir)); // 設(shè)置文件管理器標(biāo)題 intent.setDataAndType(Uri.fromFile(new File("/sdcard")), "*/*"); // 設(shè)置起始文件夾和文件類型 intent.setClass(MyActivity.this, ExDialog.class); startActivityForResult(intent, REQUEST_EX); b) 從資源管理器接收數(shù)據(jù) 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) 文件管理器類的實(shí)現(xiàn) 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"); // 接收標(biāo)題內(nèi)容 Uri uri = intent.getData(); // 接收起始目錄 mDir = uri.getPath(); // 設(shè)置起始目錄 setTitle(title);
mData = getData(); // 向鏈表mData填充目錄的數(shù)據(jù) MyAdapter adapter = new MyAdapter(this); setListAdapter(adapter); // 設(shè)置MyAdapter類為ListView控件提供數(shù)據(jù)
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); // 設(shè)置對(duì)話框?yàn)楣潭ù笮?,不因進(jìn)出目錄變化 }
private List<Map<String, Object>> getData() { // 將目錄數(shù)據(jù)填充到鏈表中 List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); Map<String, Object> map = null; File f = new File(mDir); // 打開當(dāng)前目錄 File[] files = f.listFiles(); // 獲取當(dāng)前目錄中文件列表
if (!mDir.equals("/sdcard")) { // 不充許進(jìn)入/sdcard上層目錄 map = new HashMap<String, Object>(); // 加返回上層目錄項(xiàng) 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()) // 按不同類型顯示不同圖標(biāo) map.put("img", R.drawable.ex_folder); else map.put("img", R.drawable.ex_doc); list.add(map); } } return list; }
// 響應(yīng)用戶點(diǎn)擊列表項(xiàng)的事件 @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(); //點(diǎn)擊目錄時(shí)進(jìn)入子目錄 MyAdapter adapter = new MyAdapter(this); setListAdapter(adapter); } else { // 點(diǎn)擊文件時(shí)關(guān)閉文件管理器,并將選取結(jié)果返回 finishWithResult((String) mData.get(position).get("info")); } }
public final class ViewHolder { // 定義每個(gè)列表項(xiàng)所含內(nèi)容 public ImageView img; // 顯示圖片ID public TextView title; // 文件目錄名 public TextView info; // 文件目錄描述 }
public class MyAdapter extends BaseAdapter { // 實(shí)現(xiàn)列表內(nèi)容適配器 private LayoutInflater mInflater;
public MyAdapter(Context context) { this.mInflater = LayoutInflater.from(context); }
public int getCount() { // 獲取列表項(xiàng)個(gè)數(shù) return mData.size(); }
public Object getItem(int arg0) { return null; }
public long getItemId(int arg0) { return 0; }
// 設(shè)置每個(gè)列表項(xiàng)的顯示 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); // 設(shè)置列表項(xiàng)的布局 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")); // 根據(jù)位置position設(shè)置具體內(nèi)容 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的方式將結(jié)果返回調(diào)用類 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(); } }; 轉(zhuǎn)載請(qǐng)注明作者及出處: http://blog.csdn.net/xieyan0811
|