Android应用中实现选择本地文件与目录的实例分享
程序员文章站
2024-02-26 16:53:10
文件选择器
今天给大家分享下文件选择器的作用 , 具体就是获取用户在在sd卡选中的文件/文件夹路径 ,类似于c#中openfiledialog控件(对c#的一站式开发还是...
文件选择器
今天给大家分享下文件选择器的作用 , 具体就是获取用户在在sd卡选中的文件/文件夹路径 ,类似于c#中openfiledialog控件(对c#的一站式开发还是念念不忘)。功能实现起来比较简单,主要是帮助大家节省开发时间。
网上流传较广的一个成品如下 <[android实例] 文件选择器>, 本文也是根据上面的成品修改而成,使其更易理解,效率更高。 除此之外,主要特色有:
1、我们监听了用户按下back键的事件,使其返回上一层目录;
2、针对不同的文件类型(文件vs文件夹 , 目标文件vs其他文件)做了特殊处理。
知识点一、 file 类的使用
文件选择器的主要功能是:浏览文件\文件夹、文件类型等;都是通过java file类来实现的。
知识点二、调用方法说明
使用了startactivityforresult()发起调用以及onactivityresult()方法接受回调后的信息。
截图如下:
其他的也没什么好说了,大家看看代码注释吧~~ so easy - - 。
filechooseractivity.java 实现文件选择的类 。
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(); } } }
界面依旧很丑陋,囧 ,大家可以根据需要在此基础上添加功能,下面选择目录也基本上同理。
目录选择器
chooserdialog.xml
<?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>
package hkp.dirchooser; import java.io.file; import java.util.arraylist; import java.util.list; import android.app.dialog; import android.content.context; import android.os.bundle; import android.os.environment; import android.os.handler; import android.view.gravity; import android.view.view; import android.widget.adapterview; import android.widget.adapterview.onitemclicklistener; import android.widget.arrayadapter; import android.widget.button; import android.widget.edittext; import android.widget.linearlayout; import android.widget.listview; import android.widget.textview; import android.widget.toast; public class dirchooserdialog extends dialog implements android.view.view.onclicklistener{ private listview list; arrayadapter<string> adapter; arraylist<string> arr=new arraylist<string>(); context context; private string path; private textview title; private edittext et; private button home,back,ok; private linearlayout titleview; private int type = 1; private string[] filetype = null; public final static int typeopen = 1; public final static int typesave = 2; /** * @param context * @param type 值为1表示创建打开目录类型的对话框,2为创建保存文件到目录类型的对话框 * @param filetype 要过滤的文件类型,null表示只选择目录 * @param resultpath 点ok按钮返回的结果,目录或者目录+文件名 */ public dirchooserdialog(context context,int type,string[]filetype,string resultpath) { super(context); // todo auto-generated constructor stub this.context = context; this.type = type; this.filetype = filetype; this.path = resultpath; } /* (non-javadoc) * @see android.app.dialog#dismiss() */ @override public void dismiss() { // todo auto-generated method stub super.dismiss(); } /* (non-javadoc) * @see android.app.dialog#oncreate(android.os.bundle) */ @override protected void oncreate(bundle savedinstancestate) { // todo auto-generated method stub super.oncreate(savedinstancestate); setcontentview(r.layout.chooserdialog); path = getrootdir(); arr = (arraylist<string>) getdirs(path); adapter = new arrayadapter<string>(context,android.r.layout.simple_list_item_1, arr); list = (listview)findviewbyid(r.id.list_dir); list.setadapter(adapter); list.setonitemclicklistener(lvlis); home = (button) findviewbyid(r.id.btn_home); home.setonclicklistener(this); back = (button) findviewbyid(r.id.btn_back); back.setonclicklistener(this); ok = (button) findviewbyid(r.id.btn_ok); ok.setonclicklistener(this); titleview = (linearlayout) findviewbyid(r.id.dir_layout); if(type == typeopen){ title = new textview(context); titleview.addview(title); title.settext(path); }else if(type == typesave){ et = new edittext(context); et.setwidth(240); et.setheight(70); et.setgravity(gravity.center); et.setpadding(0, 2, 0, 0); titleview.addview(et); et.settext("wffilename"); } // title = (textview) findviewbyid(r.id.dir_str); // title.settext(path); } //动态更新listview runnable add=new runnable(){ @override public void run() { // todo auto-generated method stub arr.clear(); //system.out.println("runnable path:"+path); //必须得用这种方法为arr赋值才能更新 list<string> temp = getdirs(path); for(int i = 0;i < temp.size();i++) arr.add(temp.get(i)); adapter.notifydatasetchanged(); } }; private onitemclicklistener lvlis=new onitemclicklistener(){ @override public void onitemclick(adapterview<?> arg0, view arg1, int arg2, long arg3) { string temp = (string) arg0.getitematposition(arg2); //system.out.println("onitemclick path1:"+path); if(temp.equals("..")) path = getsubdir(path); else if(path.equals("/")) path = path+temp; else path = path+"/"+temp; //system.out.println("onitemclick path2"+path); if(type == typeopen) title.settext(path); handler handler=new handler(); handler.post(add); } }; private list<string> getdirs(string ipath){ list<string> file = new arraylist<string>(); //system.out.println("getdirs path:"+ipath); file[] myfile = new file(ipath).listfiles(); if(myfile == null){ file.add(".."); }else for(file f: myfile){ //过滤目录 if(f.isdirectory()){ string tempf = f.tostring(); int pos = tempf.lastindexof("/"); string subtemp = tempf.substring(pos+1, tempf.length()); // string subtemp = tempf.substring(path.length(),tempf.length()); file.add(subtemp); //system.out.println("files in dir:"+subtemp); } //过滤知道类型的文件 if(f.isfile() && filetype != null){ for(int i = 0;i< filetype.length;i++){ int typestrlen = filetype[i].length(); string filename = f.getpath().substring(f.getpath().length()- typestrlen); if (filename.tolowercase().equals(filetype[i])) { file.add(f.tostring().substring(path.length()+1,f.tostring().length())); } } } } if(file.size()==0) file.add(".."); // system.out.println("file[0]:"+file.get(0)+" file size:"+file.size()); return file; } /* (non-javadoc) * @see android.view.view.onclicklistener#onclick(android.view.view) */ @override public void onclick(view v) { // todo auto-generated method stub if(v.getid() == home.getid()){ path = getrootdir(); if(type == typeopen) title.settext(path); handler handler=new handler(); handler.post(add); }else if(v.getid() == back.getid()){ path = getsubdir(path); if(type == typeopen) title.settext(path); handler handler=new handler(); handler.post(add); }else if(v.getid() == ok.getid()){ dismiss(); if(type == typesave) path = path+"/"+et.geteditabletext().tostring()+".wf"; toast.maketext(context, path, toast.length_short).show(); } } private string getsdpath(){ file sddir = null; boolean sdcardexist = environment.getexternalstoragestate() .equals(android.os.environment.media_mounted); //判断sd卡是否存在 if(sdcardexist) { sddir = environment.getexternalstoragedirectory();//获取根目录 } if(sddir == null){ //toast.maketext(context, "no sdcard inside!",toast.length_short).show(); return null; } return sddir.tostring(); } private string getrootdir(){ string root = "/"; path = getsdpath(); if (path == null) path="/"; return root; } private string getsubdir(string path){ string subpath = null; int pos = path.lastindexof("/"); if(pos == path.length()){ path = path.substring(0,path.length()-1); pos = path.lastindexof("/"); } subpath = path.substring(0,pos); if(pos == 0) subpath = path; return subpath; } }
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(); } }); } }
上一篇: Java用POI解析excel并获取所有单元格数据的实例
下一篇: 简介操作MySQL日志的一些方法