原创 Android第九站 众多豪华控件 文件搜寻

2011-1-27 18:57 6208 8 8 分类: 智能手机

目录

4.11 快速地搜索手机文件引擎

4.21 查找程序根目录下所有文件

 

 

4.11 快速地搜索手机文件引擎

范例说明

大家都应该用过操作系统中的文件搜索功能吧!它可以快速协助我们找到想要的文件。如果要在手机制作一个文件搜索的功能,又该如何实现呢?其实这个功能并不困难,Java I/O的API中提供了java.io.File对象,只要利用File对象的方法,再搭配Android的EditText、TextView等对象,就可以轻松做出一个手机的文件搜索引擎。

本范例中使用EditText、Button与TextView三种对象来实现此功能,用户将要搜索的文件名称或关键字输入EditText中,单击Button后,程序会在根目录中寻找符合的文件,并将搜索结果显示于TextView中;如果找不到符合的文件,则显示“找不到文件”。

范例程序

src/irdc.ex04_11/EX04_11.java

范例中以java.io.File对象来取得根目录下的文件,经过比较后,将符合结果的文件路径写入TextView中,若要在TextView中换行,需使用\n来作换行符号。

import java.io.File;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;


public class ex4_11 extends Activity {
  /*声明对象变量*/
   private Button mButton;
   private EditText mKeyword;
   private TextView mResult;
  
   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState)
   {
     super.onCreate(savedInstanceState);
     /*加载main.xml Layout */
     setContentView(R.layout.main);
    
   
  /* 初始化对象 */
     mKeyword=(EditText)findViewById(R.id.mKeyword);
     mButton=(Button)findViewById(R.id.mButton);
     mResult=(TextView) findViewById(R.id.mResult);
    
   
  /* 将mButton添加onClickListener */
     mButton.setOnClickListener(new Button.OnClickListener()
     {
       public void onClick(View v)
       {
      
  /*取得输入的关键字*/
         String keyword = mKeyword.getText().toString();
         if(keyword.equals("")){
           mResult.setText("请勿输入空白的关键字!!");
         }else{
         
mResult.setText(searchFile(keyword));
        }
       }
     });
   }
  
   /* 搜索文件的method */
   private String searchFile(String keyword)
   {
     String result="";
   
  File[] files=new File("/").listFiles();
     for( File f : files ){
    if(f.getName().indexOf(keyword)>=0){ 
      result+=f.getPath()+"\n";
    }
     }
    
if(result.equals("")) result="找不到文件!!";
     return result;
   }
 }

在本范例中,searchFile(String keyword)这个方法的功能为搜索根目录下符合关键字的文件。在搜索文件的过程中,只搜索根目录中的文件,并没有进一步再对子目录下的文件比对,如果要再强化这个文件搜索的功能,让它也能搜索包含子目录下的所有文件,可以在程序中利用File.isDirectory()这个方法来判断其是否为目录。如果是的话,就继续往下一层寻找;不是的话,就终止向下寻找的动作。这个做法在后面的范例中会有详细的示范,要注意的是手机硬件环境是否能负荷程序做大规模的文件搜索,毕竟手机的硬件配备(处理器、内存)是比不上一般计算机的。

另外,在范例中仅针对关键字做了空白检查,在比较文件名称时也没有忽略大小写(要大小写完全符合才搜索的出来),如果要让这个搜索功能更完备,当然可以多做一点变化。例如,检查关键字是否包含特殊的字符、可选择比较文件时是否忽略大小写、可选择要搜索的文件类型,甚至是可自己指定要搜索的目录等,就看各位要如何运用了。

4.21 查找程序根目录下所有文件

范例说明

在前面介绍的文件搜索范例中,示范了如何在根目录中搜索想找的文件,如果想要浏览根目录下所有的文件,包含子目录下所有的文件,实现类似“Windows文件资源管理器”的功能,又该如何实现呢?只要运用Java/IO中java.io.File对象,搭配Android的ListActivity,就可以实现一个手机版的文件资源管理器。

本范例将以ListActivity来显示文件列表,以TextView来显示当前路径,再搭配java.io.File实现出的方法来实现手机版的文件资源管理器。

<!--[endif]-->


范例程序

src/irdc.ex04_21/EX04_21.java

程序本身即是一个ListActivity对象,所以它必须继承的是ListActivity(android.app. List- Activity),而非Activity(android.app.Activity);getFileDir(String filePath)这个方法可以找出在filePath下的所有文件,并同时将“回到根目录”(Back to /)与“回到上一层”(Back to ../)这两个选项添加到item的最上面两条。

在取得filePath下所有文件后,程序将产生一个ArrayAdapter(Android.widget.ArrayAdapter)对象,并以setListAdapter()的方式指定给ListActivity,ListActivity即会将文件逐条列出,同时将目前所在路径显示在最上方的TextView里。

程序中重写了ListActivity的onListItemClick()这个方法,在单击显示的任何一个item时,以file.isDirectory()这个方法来判断该文件是否为目录,如果是的话,就再次调用getFileDir()来显示下一层目录里的文件;反之,则弹出Dialog告知此item是一个文件。

/* import程序略 */

 

public class EX04_21 extends ListActivity

{

  /* 对象声明

     items:存放显示的名称

     paths:存放文件路径

     rootPath:起始目录

  */

  private List<String> items=null;

  private List<String> paths=null;

  private String rootPath="/";

  private TextView mPath;

 

  /** Called when the activity is first created. */

  @Override

  protected void onCreate(Bundle icicle)

  {

    super.onCreate(icicle);

   

    /* 加载main.xml Layout */

    setContentView(R.layout.main);

    mPath=(TextView)findViewById(R.id.mPath);

   

    getFileDir(rootPath);

  }

 

  /* 取得文件架构的method */

  private void getFileDir(String filePath)

  {

    /* 设置目前所在路径 */

    mPath.setText(filePath);

   

    items=new ArrayList<String>();

    paths=new ArrayList<String>(); 

    File f=new File(filePath); 

    File[] files=f.listFiles();

    

    if(!filePath.equals(rootPath))

    {

      /* 第一笔设置为[回到根目录] */

      items.add("Back to "+rootPath);

      paths.add(rootPath);

      /* 第二笔设置为[回上层] */

      items.add("Back to ../");

      paths.add(f.getParent());

    }

 

    /* 将所有文件添加到ArrayList中 */

    for(int i=0;i<files.length;i++)

    {

      File file=files;

      items.add(file.getName());

      paths.add(file.getPath());

    }

   

    /* 声明一ArrayAdapter,使用file_row这个Layout,

       并将Adapter设置给此ListActivity */

    ArrayAdapter<String> fileList =

      new ArrayAdapter<String>(this,R.layout.file_row, items);

    setListAdapter(fileList);

  }

 

  /* 设置ListItem被按下时要做的动作 */

  @Override

  protected void onListItemClick

  (ListView l,View v,int position,long id)

  {

    File file = new File(paths.get(position));

    if(file.canRead())

    {

      if (file.isDirectory())

      {

        /* 如果是文件夹就再进去读取 */

        getFileDir(paths.get(position));

      }

      else

      {

        /* 如果是文件,则跳出AlertDialog */

        new AlertDialog.Builder(this)

            .setTitle("Message")

            .setMessage("["+file.getName()+"] is File!")

            .setPositiveButton("OK",

              new DialogInterface.OnClickListener()

              {

                public void onClick(DialogInterface dialog,int which)

                {

                }

              }).show();        

      }

    }

    else

    {

      /* 跳出AlertDialog显示权限不足 */

      new AlertDialog.Builder(this)

          .setTitle("Message")

          .setMessage("权限不足!")

          .setPositiveButton("OK",

            new DialogInterface.OnClickListener()

            {

              public void onClick(DialogInterface dialog,int which)

              {

              }

            }).show();    

    }

  }

}

res/layout/main.xml

Layout中定义了ListView。

 

  <ListView

    android:id="@android:id/list"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

  >

res/layout/file_row.xml

此Layout为事先定义要给ArrayAdapter使用的Layout,里面仅定义了一个TextView。

 

<?xml version="1.0" encoding="utf-8"?>

<TextView

  android:id="@+id/text1"

  xmlns:android="http://schemas.android.com/apk/res/android"

  android:layout_width="wrap_content"

  android:layout_height="20px"

  android:textSize="14sp"

</TextView>

扩展学习

范例中以ArrayAdapter的方式将数据指定给ListActivity:

 

ArrayAdapter<String> fileList =

new ArrayAdapter<String>(this,R.layout.file_row, items);

 

setListAdapter(fileList);

 

其中在声明ArrayAdapter时,构造器中的第二个参数需传入Layout的id,范例中传入的是R.layout.file_row,此layout为预先准备好的xml,如果不想预先准备Layout,只要将程序中传入Layout的部分改为Android.R.layout.layout_name,就可以直接使用Android默认的Layout了!

在file_row.xml这个layout中仅定义了一个TextView,也就是说,在ListActivity里的每一个ListItem,其实就是一个TextView;如果想要在文件列表时对Layout做一点变化,比如说,每个列出的文件前面加上一个图标,是目录的话,就显示文件夹的图片文件;是文件的话,就显示文件的图片文件。在本书后续的范例中就会介绍。

在前面一个范例的扩展学习中有提到,ListActivity可以不指定自定义的Layout,系统会默认一个全屏幕的List列表画面,以作为ListActivity的Layout,但在本例中需要一个TextView来显示目前所在的路径,所以仍然自定义了一个Layout,并以setContentView()来指定给ListActivity。再次提醒各位,自定义Layout中必须包含一个ListView的Widget,且必须指定android:id= "@android:id/list",否则将会导致程序运行时的错误。

在范例中,如果单击的item为文件时,会跳出Dialog告诉用户“This is aFile”,Java I/O的File对象提供了许多方法,可以取得文件的详细信息,只要善用这些方法,就可以强化跳出Dialog里的信息,让用户单击文件时,显示出文件详细信息的Dialog,以下列出几个方法供大家参考。

 

file.getName();                         /*取得文件名称*/

file.getPath();                         /*取得文件路径*/

new Timestamp(file.lastModified()); /*取得最后修改时间*/

file.canRead();                         /*文件是否可读取*/

file.canWrite();                            /*文件是否可写入*/

file.isHidden();                            /*文件是否为隐藏文件*/

 

 

 

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /2 下一条