首页 > 代码库 > Android开发 打开文件 选择文件对话框

Android开发 打开文件 选择文件对话框

原文地址:http://blog.csdn.net/trbbadboy/article/details/7899424;

因项目需要打开文件,因此做了一个打开文件的对话框,现在把这部分的代码共享出来了。

首先是一个回调接口,该接口在文件选择完毕的通知调用者进行如果何种操作。文件接口声明,如下:

[java] view plaincopyprint?
  1. // filename: CallbackBundle.java  
  2. package com.example.openfiledemo;  
  3.   
  4. import android.os.Bundle;  
  5. // 简单的Bundle参数回调接口  
  6. public interface CallbackBundle {  
  7.     abstract void callback(Bundle bundle);  
  8. }  

然后的打开文件对话框的一下封装:

[java] view plaincopyprint?
  1. // filename: OpenFileDialog.java  
  2. package com.example.openfiledemo;  
  3.   
  4. import java.io.File;  
  5. import java.util.ArrayList;  
  6. import java.util.HashMap;  
  7. import java.util.List;  
  8. import java.util.Map;  
  9.   
  10. import android.app.Activity;  
  11. import android.app.AlertDialog;  
  12. import android.app.Dialog;  
  13. import android.content.Context;  
  14. import android.os.Bundle;  
  15. import android.view.View;  
  16. import android.widget.AdapterView;  
  17. import android.widget.ListView;  
  18. import android.widget.SimpleAdapter;  
  19. import android.widget.Toast;  
  20. import android.widget.AdapterView.OnItemClickListener;  
  21.   
  22. public class OpenFileDialog {  
  23.     public static String tag = "OpenFileDialog";  
  24.     static final public String sRoot = "/";   
  25.     static final public String sParent = "..";  
  26.     static final public String sFolder = ".";  
  27.     static final public String sEmpty = "";  
  28.     static final private String sOnErrorMsg = "No rights to access!";  
  29.       
  30.     // 参数说明  
  31.     // context:上下文  
  32.     // dialogid:对话框ID  
  33.     // title:对话框标题  
  34.     // callback:一个传递Bundle参数的回调接口  
  35.     // suffix:需要选择的文件后缀,比如需要选择wav、mp3文件的时候设置为".wav;.mp3;",注意最后需要一个分号(;)  
  36.     // images:用来根据后缀显示的图标资源ID。  
  37.         //  根目录图标的索引为sRoot;  
  38.         //  父目录的索引为sParent;  
  39.         //  文件夹的索引为sFolder;  
  40.         //  默认图标的索引为sEmpty;  
  41.         //  其他的直接根据后缀进行索引,比如.wav文件图标的索引为"wav"  
  42.     public static Dialog createDialog(int id, Context context, String title, CallbackBundle callback, String suffix, Map<String, Integer> images){  
  43.         AlertDialog.Builder builder = new AlertDialog.Builder(context);  
  44.         builder.setView(new FileSelectView(context, id, callback, suffix, images));  
  45.         Dialog dialog = builder.create();  
  46.         //dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);  
  47.         dialog.setTitle(title);  
  48.         return dialog;  
  49.     }  
  50.       
  51.     static class FileSelectView extends ListView implements OnItemClickListener{  
  52.           
  53.           
  54.         private CallbackBundle callback = null;  
  55.         private String path = sRoot;  
  56.         private List<Map<String, Object>> list = null;  
  57.         private int dialogid = 0;  
  58.           
  59.         private String suffix = null;  
  60.           
  61.         private Map<String, Integer> imagemap = null;  
  62.           
  63.         public FileSelectView(Context context, int dialogid, CallbackBundle callback, String suffix, Map<String, Integer> images) {  
  64.             super(context);  
  65.             this.imagemap = images;  
  66.             this.suffix = suffix==null?"":suffix.toLowerCase();  
  67.             this.callback = callback;  
  68.             this.dialogid = dialogid;  
  69.             this.setOnItemClickListener(this);  
  70.             refreshFileList();  
  71.         }  
  72.           
  73.         private String getSuffix(String filename){  
  74.             int dix = filename.lastIndexOf(‘.‘);  
  75.             if(dix<0){  
  76.                 return "";  
  77.             }  
  78.             else{  
  79.                 return filename.substring(dix+1);  
  80.             }  
  81.         }  
  82.           
  83.         private int getImageId(String s){  
  84.             if(imagemap == null){  
  85.                 return 0;  
  86.             }  
  87.             else if(imagemap.containsKey(s)){  
  88.                 return imagemap.get(s);  
  89.             }  
  90.             else if(imagemap.containsKey(sEmpty)){  
  91.                 return imagemap.get(sEmpty);  
  92.             }  
  93.             else {  
  94.                 return 0;  
  95.             }  
  96.         }  
  97.           
  98.         private int refreshFileList()  
  99.         {  
  100.             // 刷新文件列表  
  101.             File[] files = null;  
  102.             try{  
  103.                 files = new File(path).listFiles();  
  104.             }  
  105.             catch(Exception e){  
  106.                 files = null;  
  107.             }  
  108.             if(files==null){  
  109.                 // 访问出错  
  110.                 Toast.makeText(getContext(), sOnErrorMsg,Toast.LENGTH_SHORT).show();  
  111.                 return -1;  
  112.             }  
  113.             if(list != null){  
  114.                 list.clear();  
  115.             }  
  116.             else{  
  117.                 list = new ArrayList<Map<String, Object>>(files.length);  
  118.             }  
  119.               
  120.             // 用来先保存文件夹和文件夹的两个列表  
  121.             ArrayList<Map<String, Object>> lfolders = new ArrayList<Map<String, Object>>();  
  122.             ArrayList<Map<String, Object>> lfiles = new ArrayList<Map<String, Object>>();  
  123.               
  124.             if(!this.path.equals(sRoot)){  
  125.                 // 添加根目录 和 上一层目录  
  126.                 Map<String, Object> map = new HashMap<String, Object>();  
  127.                 map.put("name", sRoot);  
  128.                 map.put("path", sRoot);  
  129.                 map.put("img", getImageId(sRoot));  
  130.                 list.add(map);  
  131.                   
  132.                 map = new HashMap<String, Object>();  
  133.                 map.put("name", sParent);  
  134.                 map.put("path", path);  
  135.                 map.put("img", getImageId(sParent));  
  136.                 list.add(map);  
  137.             }  
  138.               
  139.             for(File file: files)  
  140.             {  
  141.                 if(file.isDirectory() && file.listFiles()!=null){  
  142.                     // 添加文件夹  
  143.                     Map<String, Object> map = new HashMap<String, Object>();  
  144.                     map.put("name", file.getName());  
  145.                     map.put("path", file.getPath());  
  146.                     map.put("img", getImageId(sFolder));  
  147.                     lfolders.add(map);  
  148.                 }  
  149.                 else if(file.isFile()){  
  150.                     // 添加文件  
  151.                     String sf = getSuffix(file.getName()).toLowerCase();  
  152.                     if(suffix == null || suffix.length()==0 || (sf.length()>0 && suffix.indexOf("."+sf+";")>=0)){  
  153.                         Map<String, Object> map = new HashMap<String, Object>();  
  154.                         map.put("name", file.getName());  
  155.                         map.put("path", file.getPath());  
  156.                         map.put("img", getImageId(sf));  
  157.                         lfiles.add(map);  
  158.                     }  
  159.                 }    
  160.             }  
  161.               
  162.             list.addAll(lfolders); // 先添加文件夹,确保文件夹显示在上面  
  163.             list.addAll(lfiles);    //再添加文件  
  164.               
  165.               
  166.             SimpleAdapter adapter = new SimpleAdapter(getContext(), list, R.layout.filedialogitem, new String[]{"img""name""path"}, new int[]{R.id.filedialogitem_img, R.id.filedialogitem_name, R.id.filedialogitem_path});  
  167.             this.setAdapter(adapter);  
  168.             return files.length;  
  169.         }  
  170.         @Override  
  171.         public void onItemClick(AdapterView<?> parent, View v, int position, long id) {  
  172.             // 条目选择  
  173.             String pt = (String) list.get(position).get("path");  
  174.             String fn = (String) list.get(position).get("name");  
  175.             if(fn.equals(sRoot) || fn.equals(sParent)){  
  176.                 // 如果是更目录或者上一层  
  177.                 File fl = new File(pt);  
  178.                 String ppt = fl.getParent();  
  179.                 if(ppt != null){  
  180.                     // 返回上一层  
  181.                     path = ppt;  
  182.                 }  
  183.                 else{  
  184.                     // 返回更目录  
  185.                     path = sRoot;  
  186.                 }  
  187.             }  
  188.             else{  
  189.                 File fl = new File(pt);  
  190.                 if(fl.isFile()){  
  191.                     // 如果是文件  
  192.                     ((Activity)getContext()).dismissDialog(this.dialogid); // 让文件夹对话框消失  
  193.                       
  194.                     // 设置回调的返回值  
  195.                     Bundle bundle = new Bundle();  
  196.                     bundle.putString("path", pt);  
  197.                     bundle.putString("name", fn);  
  198.                     // 调用事先设置的回调函数  
  199.                     this.callback.callback(bundle);  
  200.                     return;  
  201.                 }  
  202.                 else if(fl.isDirectory()){  
  203.                     // 如果是文件夹  
  204.                     // 那么进入选中的文件夹  
  205.                     path = pt;  
  206.                 }  
  207.             }  
  208.             this.refreshFileList();  
  209.         }  
  210.     }  
  211. }  


下面是文件条目的一个布局(文件名:filedialogitem.xml):

[html] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/vw1"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="wrap_content"  
  6.     android:background="#000000"  
  7.     android:orientation="horizontal"  
  8.     android:padding="4dp" >  
  9.   
  10.   
  11.     <ImageView  
  12.         android:id="@+id/filedialogitem_img"  
  13.         android:layout_width="32dp"  
  14.         android:layout_height="32dp"  
  15.         android:layout_margin="4dp"/>  
  16.    
  17.   
  18.   
  19.    <LinearLayout  
  20.        android:layout_width="wrap_content"  
  21.        android:layout_height="wrap_content"  
  22.        android:orientation="vertical" >  
  23.   
  24.   
  25.   
  26.   
  27.   
  28.         <TextView  
  29.             android:id="@+id/filedialogitem_name"  
  30.             android:layout_width="fill_parent"  
  31.             android:layout_height="wrap_content"  
  32.             android:textColor="#FFFFFF"  
  33.             android:textSize="18sp"  
  34.             android:textStyle="bold" />  
  35.   
  36.   
  37.         <TextView  
  38.             android:id="@+id/filedialogitem_path"  
  39.             android:layout_width="fill_parent"  
  40.             android:layout_height="wrap_content"  
  41.             android:paddingLeft="10dp"  
  42.             android:textColor="#FFFFFF"  
  43.             android:textSize="14sp" />  
  44.   
  45.     </LinearLayout>  
  46.   
  47. </LinearLayout>  

下面是使用的例子:

[java] view plaincopyprint?
  1. // filename: OpenFileDemo.java  
  2. package com.example.openfiledemo;  
  3.   
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.   
  7. import android.os.Bundle;  
  8. import android.app.Activity;  
  9. import android.app.Dialog;  
  10. import android.view.View;  
  11. import android.view.View.OnClickListener;  
  12.   
  13. public class OpenFileDemo extends Activity {  
  14.       
  15.     static private int openfileDialogId = 0;  
  16.       
  17.     @Override  
  18.     public void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.activity_open_file_demo);  
  21.           
  22.           
  23.         // 设置单击按钮时打开文件对话框  
  24.         findViewById(R.id.button_openfile).setOnClickListener(new OnClickListener() {  
  25.             @Override  
  26.             public void onClick(View arg0) {  
  27.                 showDialog(openfileDialogId);  
  28.             }  
  29.         });  
  30.     }  
  31.   
  32.     @Override  
  33.     protected Dialog onCreateDialog(int id) {  
  34.         if(id==openfileDialogId){  
  35.             Map<String, Integer> images = new HashMap<String, Integer>();  
  36.             // 下面几句设置各文件类型的图标, 需要你先把图标添加到资源文件夹  
  37.             images.put(OpenFileDialog.sRoot, R.drawable.filedialog_root);   // 根目录图标  
  38.             images.put(OpenFileDialog.sParent, R.drawable.filedialog_folder_up);    //返回上一层的图标  
  39.             images.put(OpenFileDialog.sFolder, R.drawable.filedialog_folder);   //文件夹图标  
  40.             images.put("wav", R.drawable.filedialog_wavfile);   //wav文件图标  
  41.             images.put(OpenFileDialog.sEmpty, R.drawable.filedialog_root);  
  42.             Dialog dialog = OpenFileDialog.createDialog(id, this"打开文件"new CallbackBundle() {  
  43.                 @Override  
  44.                 public void callback(Bundle bundle) {  
  45.                     String filepath = bundle.getString("path");  
  46.                     setTitle(filepath); // 把文件路径显示在标题上  
  47.                 }  
  48.             },   
  49.             ".wav;",  
  50.             images);  
  51.             return dialog;  
  52.         }  
  53.         return null;