Android应用中实现选择本地文件与目录的实例分享

时间:2022-01-14 02:49:38

文件选择器
今天给大家分享下文件选择器的作用 , 具体就是获取用户在在sd卡选中的文件/文件夹路径 ,类似于c#中openfiledialog控件(对c#的一站式开发还是念念不忘)。功能实现起来比较简单,主要是帮助大家节省开发时间。
网上流传较广的一个成品如下 <[android实例] 文件选择器>, 本文也是根据上面的成品修改而成,使其更易理解,效率更高。 除此之外,主要特色有:
1、我们监听了用户按下back键的事件,使其返回上一层目录;
2、针对不同的文件类型(文件vs文件夹 , 目标文件vs其他文件)做了特殊处理。
知识点一、 file 类的使用
文件选择器的主要功能是:浏览文件文件夹、文件类型等;都是通过java file类来实现的。

知识点二、调用方法说明  
使用了startactivityforresult()发起调用以及onactivityresult()方法接受回调后的信息。
截图如下:

Android应用中实现选择本地文件与目录的实例分享

其他的也没什么好说了,大家看看代码注释吧~~  so easy  - - 。

filechooseractivity.java 实现文件选择的类 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
public class copyoffilechooseractivity extends activity {
   
  private string msdcardrootpath ; //sdcard 根路径
  private string mlastfilepath ;  //当前显示的路径
   
  private arraylist<fileinfo> mfilelists ;
  private filechooseradapter madatper ;
   
  //配置适配器
  private void setgridviewadapter(string filepath) {
    updatefileitems(filepath);
    madatper = new filechooseradapter(this , mfilelists);
    mgridview.setadapter(madatper);
  }
  //根据路径更新数据,并且通知adatper数据改变
  private void updatefileitems(string filepath) {
    mlastfilepath = filepath ;
    mtvpath.settext(mlastfilepath);
     
    if(mfilelists == null)
      mfilelists = new arraylist<fileinfo>() ;
    if(!mfilelists.isempty())
      mfilelists.clear() ;
     
    file[] files = folderscan(filepath);
    if(files == null
      return ;
    for (int i = 0; i < files.length; i++) {
      if(files[i].ishidden()) // 不显示隐藏文件
        continue ;
       
      string fileabsolutepath = files[i].getabsolutepath() ;
      string filename = files[i].getname();
      boolean isdirectory = false ;
      if (files[i].isdirectory()){
        isdirectory = true ;
      }
      fileinfo fileinfo = new fileinfo(fileabsolutepath , filename , isdirectory) ;
      //添加至列表
      mfilelists.add(fileinfo);
    }
    //when first enter , the object of madatper don't initialized
    if(madatper != null)
      madatper.notifydatasetchanged(); //重新刷新
  }
  //获得当前路径的所有文件
  private file[] folderscan(string path) {
    file file = new file(path);
    file[] files = file.listfiles();
    return files;
  }
  private adapterview.onitemclicklistener mitemclicklistener = new onitemclicklistener() {
    public void onitemclick(adapterview<?> adapterview, view view, int position,
        long id) {
      fileinfo fileinfo = (fileinfo)(((filechooseradapter)adapterview.getadapter()).getitem(position));
      if(fileinfo.isdirectory())  //点击项为文件夹, 显示该文件夹下所有文件
        updatefileitems(fileinfo.getfilepath()) ;
      else if(fileinfo.ispptfile()){ //是ppt文件 , 则将该路径通知给调用者
        intent intent = new intent();
        intent.putextra(extra_file_chooser, fileinfo.getfilepath());
        setresult(result_ok , intent);
        finish();
      }
      else //其他文件.....
        toast(gettext(r.string.open_file_error_format));
      }
    }
  };
  public boolean onkeydown(int keycode , keyevent event){
    if(event.getaction() == keyevent.action_down && event.getkeycode()
      == keyevent.keycode_back){
      backprocess();  
      return true ;
    }
    return super.onkeydown(keycode, event);
  }
  //返回上一层目录的操作
  public void backprocess(){
    //判断当前路径是不是sdcard路径 , 如果不是,则返回到上一层。
    if (!mlastfilepath.equals(msdcardrootpath)) { 
      file thisfile = new file(mlastfilepath);
      string parentfilepath = thisfile.getparent();
      updatefileitems(parentfilepath);
    
    else //是sdcard路径 ,直接结束
      setresult(result_canceled);
      finish();
    }
  }
}

界面依旧很丑陋,囧 ,大家可以根据需要在此基础上添加功能,下面选择目录也基本上同理。

目录选择器

Android应用中实现选择本地文件与目录的实例分享

Android应用中实现选择本地文件与目录的实例分享

Android应用中实现选择本地文件与目录的实例分享

Android应用中实现选择本地文件与目录的实例分享

chooserdialog.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  >
 
  <linearlayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="40dip">
  <button 
    android:layout_width="40dip"
    android:layout_height="40dip"
    android:text="home"
    android:id="@+id/btn_home"
    android:layout_gravity="left"
    android:layout_weight="1"
  />
  <linearlayout android:layout_width="140dip"
    android:layout_height="35dip"
    android:id="@+id/dir_layout"
    android:gravity="center"
    android:layout_weight="1">
    </linearlayout>
  <!-- <textview 
    android:layout_width="140dip"
    android:layout_height="35dip"
    android:id="@+id/dir_str"
    android:gravity="center"
    android:layout_weight="1"
  /> -->
  <button 
    android:layout_width="40dip"
    android:layout_height="40dip"
    android:text="back"
    android:id="@+id/btn_back"
    android:layout_gravity="right"
    android:layout_weight="1"
  />
  </linearlayout>
  <listview 
    android:layout_width="fill_parent"
    android:layout_height="300dip"
    android:id="@+id/list_dir"
  />
  <button 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/btn_ok"
    android:text="ok"/>
</linearlayout>
  1. package hkp.dirchooser; 
  2. import java.io.file; 
  3. import java.util.arraylist; 
  4. import java.util.list; 
  5.   
  6. import android.app.dialog; 
  7. import android.content.context; 
  8. import android.os.bundle; 
  9. import android.os.environment; 
  10. import android.os.handler; 
  11. import android.view.gravity; 
  12. import android.view.view; 
  13. import android.widget.adapterview; 
  14. import android.widget.adapterview.onitemclicklistener; 
  15. import android.widget.arrayadapter; 
  16. import android.widget.button; 
  17. import android.widget.edittext; 
  18. import android.widget.linearlayout; 
  19. import android.widget.listview; 
  20. import android.widget.textview; 
  21. import android.widget.toast; 
  22.   
  23.  
  24. public class dirchooserdialog extends dialog implements android.view.view.onclicklistener{  
  25.     
  26.   private listview list; 
  27.   arrayadapter<string> adapter; 
  28.   arraylist<string> arr=new arraylist<string>(); 
  29.     
  30.   context context; 
  31.   private string path; 
  32.     
  33.   private textview title; 
  34.   private edittext et; 
  35.   private button home,back,ok; 
  36.   private linearlayout titleview; 
  37.     
  38.   private int type = 1; 
  39.   private string[] filetype = null
  40.     
  41.   public final static int typeopen = 1; 
  42.   public final static int typesave = 2; 
  43.     
  44.   /** 
  45.    * @param context 
  46.    * @param type 值为1表示创建打开目录类型的对话框,2为创建保存文件到目录类型的对话框 
  47.    * @param filetype 要过滤的文件类型,null表示只选择目录 
  48.    * @param resultpath 点ok按钮返回的结果,目录或者目录+文件名 
  49.    */ 
  50.   public dirchooserdialog(context context,int type,string[]filetype,string resultpath) { 
  51.     super(context); 
  52.     // todo auto-generated constructor stub 
  53.     this.context = context; 
  54.     this.type = type; 
  55.     this.filetype = filetype; 
  56.     this.path = resultpath; 
  57.   } 
  58.   /* (non-javadoc) 
  59.    * @see android.app.dialog#dismiss() 
  60.    */ 
  61.   @override 
  62.   public void dismiss() { 
  63.     // todo auto-generated method stub 
  64.     super.dismiss(); 
  65.   } 
  66.   /* (non-javadoc) 
  67.    * @see android.app.dialog#oncreate(android.os.bundle) 
  68.    */ 
  69.   @override 
  70.   protected void oncreate(bundle savedinstancestate) { 
  71.     // todo auto-generated method stub 
  72.     super.oncreate(savedinstancestate); 
  73.     setcontentview(r.layout.chooserdialog); 
  74.       
  75.     path = getrootdir(); 
  76.     arr = (arraylist<string>) getdirs(path); 
  77.     adapter = new arrayadapter<string>(context,android.r.layout.simple_list_item_1, arr);  
  78.       
  79.     list = (listview)findviewbyid(r.id.list_dir); 
  80.     list.setadapter(adapter); 
  81.       
  82.     list.setonitemclicklistener(lvlis); 
  83.   
  84.     home = (button) findviewbyid(r.id.btn_home); 
  85.     home.setonclicklistener(this); 
  86.       
  87.     back = (button) findviewbyid(r.id.btn_back); 
  88.     back.setonclicklistener(this); 
  89.       
  90.     ok = (button) findviewbyid(r.id.btn_ok); 
  91.     ok.setonclicklistener(this); 
  92.       
  93.     titleview = (linearlayout) findviewbyid(r.id.dir_layout); 
  94.       
  95.     if(type == typeopen){ 
  96.       title = new textview(context); 
  97.       titleview.addview(title); 
  98.       title.settext(path); 
  99.     }else if(type == typesave){ 
  100.       et = new edittext(context); 
  101.       et.setwidth(240); 
  102.       et.setheight(70); 
  103.       et.setgravity(gravity.center); 
  104.       et.setpadding(0, 2, 0, 0); 
  105.       titleview.addview(et); 
  106.       et.settext("wffilename"); 
  107.     } 
  108. //   title = (textview) findviewbyid(r.id.dir_str); 
  109. //   title.settext(path); 
  110.       
  111.   } 
  112.   //动态更新listview 
  113.   runnable add=new runnable(){ 
  114.   
  115.     @override 
  116.     public void run() { 
  117.       // todo auto-generated method stub 
  118.       arr.clear(); 
  119. //system.out.println("runnable path:"+path); 
  120.   
  121.       //必须得用这种方法为arr赋值才能更新 
  122.       list<string> temp = getdirs(path); 
  123.       for(int i = 0;i < temp.size();i++) 
  124.         arr.add(temp.get(i)); 
  125.       adapter.notifydatasetchanged(); 
  126.     }     
  127.   }; 
  128.     
  129.   private onitemclicklistener lvlis=new onitemclicklistener(){ 
  130.     @override 
  131.     public void onitemclick(adapterview<?> arg0, view arg1, int arg2, 
  132.         long arg3) { 
  133.       string temp = (string) arg0.getitematposition(arg2); 
  134. //system.out.println("onitemclick path1:"+path);       
  135.       if(temp.equals("..")) 
  136.         path = getsubdir(path); 
  137.       else if(path.equals("/")) 
  138.         path = path+temp; 
  139.       else 
  140.         path = path+"/"+temp; 
  141.         
  142. //system.out.println("onitemclick path2"+path);  
  143.       if(type == typeopen) 
  144.         title.settext(path); 
  145.         
  146.       handler handler=new handler(); 
  147.       handler.post(add); 
  148.     } 
  149.   }; 
  150.     
  151.   private list<string> getdirs(string ipath){ 
  152.     list<string> file = new arraylist<string>(); 
  153. //system.out.println("getdirs path:"+ipath);     
  154.     file[] myfile = new file(ipath).listfiles(); 
  155.     if(myfile == null){ 
  156.       file.add(".."); 
  157.         
  158.     }else 
  159.       for(file f: myfile){ 
  160.         //过滤目录 
  161.         if(f.isdirectory()){ 
  162.           string tempf = f.tostring(); 
  163.           int pos = tempf.lastindexof("/"); 
  164.           string subtemp = tempf.substring(pos+1, tempf.length()); 
  165. //         string subtemp = tempf.substring(path.length(),tempf.length()); 
  166.           file.add(subtemp);  
  167. //system.out.println("files in dir:"+subtemp); 
  168.         } 
  169.         //过滤知道类型的文件 
  170.         if(f.isfile() && filetype != null){ 
  171.           for(int i = 0;i< filetype.length;i++){ 
  172.             int typestrlen = filetype[i].length(); 
  173.               
  174.             string filename = f.getpath().substring(f.getpath().length()- typestrlen); 
  175.             if (filename.tolowercase().equals(filetype[i])) { 
  176.               file.add(f.tostring().substring(path.length()+1,f.tostring().length()));   
  177.             } 
  178.           } 
  179.         } 
  180.       } 
  181.       
  182.     if(file.size()==0) 
  183.       file.add(".."); 
  184.       
  185. //   system.out.println("file[0]:"+file.get(0)+" file size:"+file.size()); 
  186.     return file; 
  187.   } 
  188.   /* (non-javadoc) 
  189.    * @see android.view.view.onclicklistener#onclick(android.view.view) 
  190.    */ 
  191.   @override 
  192.   public void onclick(view v) { 
  193.     // todo auto-generated method stub 
  194.     if(v.getid() == home.getid()){ 
  195.       path = getrootdir(); 
  196.       if(type == typeopen) 
  197.         title.settext(path);       
  198.       handler handler=new handler(); 
  199.       handler.post(add); 
  200.     }else if(v.getid() == back.getid()){ 
  201.       path = getsubdir(path); 
  202.       if(type == typeopen) 
  203.         title.settext(path);       
  204.       handler handler=new handler(); 
  205.       handler.post(add); 
  206.     }else if(v.getid() == ok.getid()){ 
  207.       dismiss(); 
  208.       if(type == typesave) 
  209.         path = path+"/"+et.geteditabletext().tostring()+".wf"
  210.       toast.maketext(context, path, toast.length_short).show(); 
  211.     } 
  212.         
  213.       
  214.   } 
  215.     
  216.   private string getsdpath(){  
  217.       file sddir = null;  
  218.       boolean sdcardexist = environment.getexternalstoragestate()   
  219.                 .equals(android.os.environment.media_mounted);  //判断sd卡是否存在  
  220.       if(sdcardexist)   
  221.       {                 
  222.        sddir = environment.getexternalstoragedirectory();//获取根目录  
  223.      }   
  224.       if(sddir == null){ 
  225. //toast.maketext(context, "no sdcard inside!",toast.length_short).show(); 
  226.         return null
  227.       } 
  228.       return sddir.tostring();  
  229.         
  230.   }  
  231.     
  232.   private string getrootdir(){ 
  233.     string root = "/"
  234.       
  235.     path = getsdpath(); 
  236.     if (path == null
  237.       path="/"
  238.       
  239.     return root; 
  240.   } 
  241.     
  242.   private string getsubdir(string path){ 
  243.     string subpath = null
  244.       
  245.     int pos = path.lastindexof("/"); 
  246.       
  247.     if(pos == path.length()){ 
  248.       path = path.substring(0,path.length()-1); 
  249.       pos = path.lastindexof("/"); 
  250.     } 
  251.       
  252.     subpath = path.substring(0,pos); 
  253.       
  254.     if(pos == 0) 
  255.       subpath = path; 
  256.       
  257.     return subpath; 
  258.   } 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package hkp.dirchooser;
 
import android.app.activity;
import android.os.bundle;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;
 
public class mainactivity extends activity {
  /** called when the activity is first created. */
  @override
  public void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.main);
    button btn = (button) findviewbyid(r.id.btn_open);
    btn.setonclicklistener(new onclicklistener() {
       
      @override
      public void onclick(view v) {
        // todo auto-generated method stub
        string path = null;
        string [] filetype = {"dst"};//要过滤的文件类型列表
        dirchooserdialog dlg = new dirchooserdialog(mainactivity.this,2,filetype,path);
        dlg.settitle("choose dst file dir");
        dlg.show();
         
      }
    });
  }
}