Android文件管理器的源码实现

1.     Android文件管理器介绍
android系统并不自带文件管理器,但是很多情况下,我们有诸如从SD中打开文件的需要,就必须借助三方开发的资源管理器,常用的有AndExplorer等。这种情况下发布后,用户还需要安装依赖的软件,非常麻烦。下面介绍在代码中实现资源管理器,只需要一百行左右的一个类即可以最常用的文件选择功能。

2.     相关知识
文件管理器一般以固定大小的对话框的方式出现,使用ListView作为文件目录的显示载体。点选目录测进入,点选文件则将所选择文件的Uri返回给调用它的Activity。ListView的使用是实现这个功能的重点。

3.     例程

1)         功能
当用户点击按钮时,调出固定大小的文件管理器,默认显示的目录是SD卡的根目录。用户选择文件后,在界面上显示该文件的路径。

2)         可从此处下载可独立运行的代码

免费下载地址在

用户名与密码都是

具体下载目录在 /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();
         }
};

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwwyxg.html