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

文件选择器
今天给大家分享下文件选择器的作用 , 具体就是获取用户在在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(); 

      }
    });
  }
}
(0)

相关推荐

  • Android 文件选择的实现代码

    打开文件选择器 复制代码 代码如下: private void showFileChooser() {    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);     intent.setType("*/*");     intent.addCategory(Intent.CATEGORY_OPENABLE); try {        startActivityForResult( Intent.createChooser(

  • Android文件选择器ExFilePicker的使用方法

    在新版的android中(如Android 7.0+),文件选择由于权限限制,Uri变化,文件资源路径格式改版等等,变得比较复杂起来,比如,得在Androidmanifest配置FileProvider完了还得写xml目录下的文件path这些等等.一些第三方的文件选择器,就算没有上面这些动作,一般也得在Androidmanifest写几个Activity.而ExFilePicker则无需上面的繁琐操作,一不需要在Androidmanifest里面定义FileProvider,二不需要写xml文件

  • android通过蓝牙接收文件打开时无法自动选择合适的应用程序

    通过蓝牙接收文件,从历史传输记录打开,无法自动选择合适的应用程序 但是从file manager打开这个新接收的文件,是可以选择对应的应用程序(比如video player打开.3gp..mp4文件) 历史传输记录打开download的文件,是通过接收文件时对方传过来的mime type来选择适合的APP打开该文件 如果出现提示"未支持格式的文件",或者使用了错误的APP来打开该文件 原因在于发送方发送文件时填的mime type存在问题 如下的log是mtk接收方的log,请注意黄色

  • android中写一个内部类来选择文件夹中指定的图片类型实例说明

    复制代码 代码如下: /**本类是用来选择文件夹中是.jpg类型的图片*/ private class JpgFileFilter implements FilenameFilter{ @Override public boolean accept(File dir, String filename) { // TODO Auto-generated method stub return filename.endsWith(".jpg"); } }

  • android选择视频文件上传到后台服务器

    本文实例为大家分享了android选择视频文件上传到后台服务器的具体代码,供大家参考,具体内容如下 选择本地视频文件 附上Demo 首先第一步打开打开相册选择视频文件: Intent intent = new Intent(); intent.setType("video/*"); intent.setAction(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); ((Activity)

  • Android 文件选择器详解及实例代码

    本文给大家讲解下Android文件选择器的使用.实际上就是获取用户在SD卡中选择的文件或文件夹的路径,这很像C#中的OpenFileDialog控件. 此实例的实现过程很简单,这样可以让大家快速的熟悉Android文件选择器,提高开发效率. 网上曾经见到过一个关于文件选择器的实例,很多人都看过,本实例是根据它修改而成的,但更容易理解,效率也更高,另外,本实例有自己的特点:   1.监听了用户按下Back键的事件,使其返回上一层目录.        2.针对不同的文件类型(文件vs文件夹 , 目标

  • Android第三方文件选择器aFileChooser使用方法详解

    aFileChooser是android平台上的一个第三方文件选择器,其在github上的项目主页是:https://github.com/iPaulPro/aFileChooser aFileChooser实现了在Android平台上高度可定制化的文件选择功能,aFileChooser在自己的项目代码中使用也比较简单. 写一个简单例子加以说明. (1) 首先要配置Androidmanifest.xml文件: <activity android:name="com.ipaulpro.afi

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

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

  • js 获取本地文件及目录的方法(推荐)

    Javascript是网页制作中离不开的脚本语言,依靠它,一个网页的内容才生动活泼.富有朝气.但也许你还没有发现并应用它的一些更高级的功能吧?比如,对文件和文件夹进行读.写和删除,就象在VB.VC等高级语言中经常做的工作一样.怎么样,你是否需要了解这方面的知识?那就请跟我来,本文将详细描述如何使用Javascript语言进行文件操作. 一.功能实现核心:FileSystemObject 对象 其实,要在Javascript中实现文件操作功能,主要就是依靠FileSystemobject对象.在详

  • python3写的简单本地文件上传服务器实例

    python是个很好玩的东西?好吧我随口说的,反正因为各种原因(其实到底是啥我也不知道),简单的学习了下python,然后写了一个上传文件上服务器的小玩具练手. 大概功能是这样: 1.获取本地文件列表(包括文件夹) 2.检查服务器上是否存在,不存在直接上传,存在的话,文件夹无视,文件比较大小,大小不一致则覆盖,最后检查服务器上是否存在本地没有的文件,存在则删除 3.之后增加了忽略列表,忽略文件类型 4.然后增加了重启tomcat,但是这个功能未进行测试 大概就是这个样子,哦了,丢代码丢代码 #!

  • javascript读取本地文件和目录方法详解

    JavaScript是网页制作中离不开的脚本语言,依靠它,一个网页的内容才生动活泼.富有朝气.但也许你还没有发现并应用它的一些更高级的功能吧?比如,对文件和文件夹进行读.写和删除,就象在VB.VC等高级语言中经常做的工作一样.怎么样,你是否需要了解这方面的知识?那就请跟我来,本文将详细描述如何使用Javascript语言进行文件操作. 一.功能实现核心:FileSystemObject 对象 其实,要在Javascript中实现文件操作功能,主要就是依靠FileSystemobject对象.在详

  • Android开发中通过手机号+短信验证码登录的实例代码

    首先,需要一个电话号码,目前很多账户都是将账户名设置成手机号,然后点击按钮获取手机验证码. 其次,你需要后台给你手机短信的验证接口,各个公司用的不一样,这个身为前端,不需要你来考虑,你只要让你后台给你写好接口,你直接调用就好了. activity_login.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.andr

  • Java编程中最基础的文件和目录操作方法详解

    文件操作 平常经常使用JAVA对文件进行读写等操作,这里汇总一下常用的文件操作. 1.创建文件 public static boolean createFile(String filePath){ boolean result = false; File file = new File(filePath); if(!file.exists()){ try { result = file.createNewFile(); } catch (IOException e) { e.printStack

  • Android 复制文本内容到系统剪贴板的最简单实例(分享)

    这个例子很简单,直接上截图和代码. 布局文件activity_copy.xml代码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layou

  • 详解Android studio中正确引入so文件的方法

    相信很多朋友在使用Android studio开发中,遇到过如何引入第三方so文件的问题,然而第三方官方仅仅给出了ADT环境下的集成方式. Android studio中默认使用的是gradle编译方式,与ADT编辑方式不一样,那么so文件应当如何引入呢? 其实很简单.这里以集成JPUSH为例,看一下so文件如何引入到编译环境,最终到JNI直接可以调用该so文件. 首先,在我们的Module的根目录中建立libs目录,将jpush集成SDK中的so文件分别拷入,截图如下: 然后就是编写我们的bu

  • Android开发中libs和jinLibs文件夹的作用详解

    前言 相信各位Android开发中们在Android 开发中经常和这两个文件夹打交道,以前一直迷迷糊糊的使用,没去想过.最近遇到了一些问题,仔细研究了一下,特此记录分享.下面话不多说了,来一起看看详细的介绍吧. libs: librarys 用来存放三方库的地方,比如 *.jar 和 *.aar. 在 Project 视图下能看到, Android 视图下看不到. jniLibs: java native interface librarys Android Studio 新添加的,默认用来存放

  • Android中实现下载URL地址的网络资源的实例分享

    通过URL来获取网络资源并下载资源简单实例: package com.android.xiong.urltest; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import android.app.Activity; import android.gra

随机推荐