`
ping8080
  • 浏览: 58984 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
文章分类
社区版块
存档分类
最新评论

文件资源管理

阅读更多

原文:http://blog.donews.com/zchening/archive/2011/03/09/490.aspx

原文2:http://book.chinaunix.net/showart.php?id=8116

 

这是一个有图标的文件资源管理器,也许在网上的基于Android的market上有很多比较精美的文件资源管理器,这里我拿这个出来讲并不在于我做的界面如何的精美,而相反我这里的重点并不在界面,我只是想通过这么个列子和大家一起分享Android开发中的一下知识点:(1)目录的遍历(2)自定义Adapter(3)如何取得文件类型,以及调用系统打开对应的文件。这三点也是本程序的关键点所在,如果将这三个知识点掌握了,我想理解这个应用程序也就不再话下。

那么现在让我们一起来阅读代码吧,首先我们知道Android API提供的ArrayAdapter对象只允许存入String数组或List对象,所以在显示文件列表时,只能以一段字符串来显示文件的名称,如果要同时显示文件夹和文件的图标,以及文件名称,甚至文件类型、大小等信息,则必须要自定义一个实现Adapter Interface的对象,就可以自定义想要呈现的Layout,达到同时显示图片文件ICON与多个文字信息的效果,Android API中提供了BaseAdapter(Android.widget.BaseAdapter)对象,只要继承此对象就可以实现出属于自己的Adapter。

实现此范例时,须要先准备文件图标的ICON图片文件,并保存在/res/drawable/文件夹下,图片文件路径如下:

1 /res/drawable/back01.png; 回到根目录的图标
2 /res/drawable/back02.png; 回到上一层的图标
3 /res/drawable/doc.png;     文件的图标
4 /res/drawable/folder.png;   文件夹的图标

运行效果图:

源码:

/* import程序略 */

 

public class EX05_15 extends ListActivity

{

  /* 对象声明

     items:存放显示的名称

     paths:存放文件路径

     rootPath:起始目录

  */

  private List<String> items=null;

  private List<String> paths=null;

  private String rootPath="/";

  private TextView mPath;

  private View myView;

  private EditText myEditText;

 

  @Override

  protected void onCreate(Bundle icicle)

  {

    super.onCreate(icicle);

    /* 加载main.xml Layout */

 

    setContentView(R.layout.main);

    /* 初始化mPath,用以显示目前路径 */

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

    getFileDir(rootPath);

  }

 

  /* 取得文件架构的方法 */

  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("b1");

      paths.add(rootPath);

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

      items.add("b2");

      paths.add(f.getParent());

    }

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

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

    {

      File file=files[i];

      items.add(file.getName());

      paths.add(file.getPath());

    }

 

    /* 使用自定义的MyAdapter来将数据传入ListActivity */

    setListAdapter(new MyAdapter(this,items,paths));

  }

 

  /* 设置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() */

        getFileDir(paths.get(position));

      }

      else

      {

        /* 如果是文件调用fileHandle() */

        fileHandle(file);

      }

    }

    else

    {

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

      new AlertDialog.Builder(this)

          .setTitle("Message")

          .setMessage("权限不足!")

          .setPositiveButton("OK",

            new DialogInterface.OnClickListener()

            {

              public void onClick(DialogInterface dialog,int which)

              {

              }

            }).show();

    }

  }

 

  /* 处理文件的方法 */

  private void fileHandle(final File file){

    /* 按下文件时的OnClickListener */

    OnClickListener listener1=new DialogInterface.OnClickListener()

    {

      public void onClick(DialogInterface dialog,int which)

      {

        if(which==0)

        {

          /* 选择的item为打开文件 */

          openFile(file);

        }

        else if(which==1)

        {

          /* 选择的item为更改文件名 */

          LayoutInflater factory=LayoutInflater.from(EX05_15.this);

          /* 初始化myChoiceView,使用rename_alert_dialoglayout */

          myView=factory.inflate(R.layout.rename_alert_dialog,null);

          myEditText=(EditText)myView.findViewById(R.id.mEdit);

          /* 将原始文件名先放入EditText */

          myEditText.setText(file.getName());

 

          /* new一个更改文件名的Dialog的确定按钮的listener */

          OnClickListener listener2=

          new DialogInterface.OnClickListener()

          {

            public void onClick(DialogInterface dialog, int which)

            {

              /* 取得修改后的文件路径 */

              String modName=myEditText.getText().toString();

              final String pFile=file.getParentFile().getPath()+"/";

              final String newPath=pFile+modName;

 

              /* 判断文件名是否已存在 */

              if(new File(newPath).exists())

              {

                /* 排除修改文件名时没修改直接送出的情况 */

                if(!modName.equals(file.getName()))

                {

                  /* 跳出Alert警告文件名重复,并确认是否修改 */

                  new AlertDialog.Builder(EX05_15.this)

                      .setTitle("注意!")

                      .setMessage("文件名已经存在,是否要覆盖?")

                      .setPositiveButton("确定",

                       new DialogInterface.OnClickListener()

                      {

                        public void onClick(DialogInterface dialog,

                                            int which)

                        {

                          /* 文件名重复仍然修改会覆盖掉已存在的文件 */

                          file.renameTo(new File(newPath));

                          /* 重新生成文件列表的ListView */

                          getFileDir(pFile);

                        }

                      })

                      .setNegativeButton("取消",

                       new DialogInterface.OnClickListener()

                      {

                        public void onClick(DialogInterface dialog,

                                            int which)

                        {

                        }

                      }).show();

                }

              }

              else

              {

                /* 文件名不存在直接做修改动作 */

                file.renameTo(new File(newPath));

                /* 重新生成文件列表的ListView */

                getFileDir(pFile);

              }

            }

          };

 

          /* create更改文件名时跳出的Dialog */

          AlertDialog renameDialog=

            new AlertDialog.Builder(EX05_15.this).create();

          renameDialog.setView(myView);

 

          /* 设置更改文件名按下确认后的Listener */

          renameDialog.setButton("确定",listener2);

          renameDialog.setButton2("取消",

          new DialogInterface.OnClickListener()

          {

            public void onClick(DialogInterface dialog, int which)

            {

            }

          });

          renameDialog.show();

        }

        else

        {

          /* 选择的item为删除文件 */

          new AlertDialog.Builder(EX05_15.this).setTitle("注意!")

              .setMessage("确定要删除文件吗?")

              .setPositiveButton("确定",

               new DialogInterface.OnClickListener()

              {

                public void onClick(DialogInterface dialog,

                                        int which)

                {         

                  /* 删除文件 */

                  file.delete();

                  getFileDir(file.getParent());

                }

              })

              .setNegativeButton("取消",

               new DialogInterface.OnClickListener()

              {

                public void onClick(DialogInterface dialog,

                                        int which)

                {

                }

              }).show();

        }

      }

    };

 

    /* 选择一个文件时,跳出要如何处理文件的ListDialog */

    String[] menu={"打开文件","更改文件名","删除文件"};

    new AlertDialog.Builder(EX05_15.this)

        .setTitle("你要做什么?")

        .setItems(menu,listener1)

        .setPositiveButton("取消",

         new DialogInterface.OnClickListener()

        {

          public void onClick(DialogInterface dialog, int which)

          {

          }

        })

        .show();

  }

 

  /* 在手机上打开文件的方法 */

  private void openFile(File f)

  {

    Intent intent = new Intent();

    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    intent.setAction(android.content.Intent.ACTION_VIEW);

 

    /* 调用getMIMEType()来取得MimeType */

    String type = getMIMEType(f);

    /* 设置intentfileMimeType */

    intent.setDataAndType(Uri.fromFile(f),type);

    startActivity(intent);

  }

 

  /* 判断文件MimeType的方法 */

  private String getMIMEType(File f)

  {

    String type="";

    String fName=f.getName();

    /* 取得扩展名 */

    String end=fName.substring(fName.lastIndexOf(".")+1,

                                    fName.length()).toLowerCase();

 

    /* 根据扩展名的类型决定MimeType */

    if(end.equals("m4a")||end.equals("mp3")||end.equals("mid")

       ||end.equals("xmf")||end.equals("ogg")||end.equals("wav"))

    {

      type = "audio";

    }

    else if(end.equals("3gp")||end.equals("mp4"))

    {

      type = "video";

    }

    else if(end.equals("jpg")||end.equals("gif")||end.equals("png")

             ||end.equals("jpeg")||end.equals("bmp"))

    {

      type = "image";

    }

    else

    {

      /* 如果无法直接打开,就跳出软件列表供用户选择 */

      type="*";

    }

    type += "/*";

    return type;

  }

}

 

src/irdc.ex05_15/MyAdapter.java

自定义的Adapter对象,并以file_row.xml作为Layout,程序中依照文件的类型来决定要显示的图标是什么。

 

/* import程序略 */

 

/* 自定义的Adapter,继承android.widget.BaseAdapter */

public class MyAdapter extends BaseAdapter

{

  /* 变量声明

     mIcon1:回到根目录的图片文件

     mIcon2:回到上一层的图片

     mIcon3:文件夹的图片文件

     mIcon4:文件的图片

  */

  private LayoutInflater mInflater;

  private Bitmap mIcon1;

  private Bitmap mIcon2;

  private Bitmap mIcon3;

  private Bitmap mIcon4;

  private List<String> items;

  private List<String> paths;

  /* MyAdapter的构造器,传入三个参数  */ 

  public MyAdapter(Context context,List<String> it,List<String> pa)

  {

    /* 参数初始化 */

    mInflater = LayoutInflater.from(context);

    items = it;

    paths = pa;

    mIcon1 = BitmapFactory.decodeResource(context.getResources(),

                                                  R.drawable.back01);

    mIcon2 = BitmapFactory.decodeResource(context.getResources(),

                                                  R.drawable.back02);

    mIcon3 = BitmapFactory.decodeResource(context.getResources(),

                                                  R.drawable.folder);

    mIcon4 = BitmapFactory.decodeResource(context.getResources(),

                                                  R.drawable.doc);

  }

 

  /* 因继承BaseAdapter,需重写以下方法 */

  @Override

  public int getCount()

  {

    return items.size();

  }

 

  @Override

  public Object getItem(int position)

  {

    return items.get(position);

  }

 

  @Override

  public long getItemId(int position)

  {

    return position;

  }

 

  @Override

  public View getView(int position,View convertView,ViewGroup par)

  {

    ViewHolder holder;

   

    if(convertView == null)

    {

      /* 使用自定义的file_row作为Layout */

      convertView = mInflater.inflate(R.layout.file_row, null);

      /* 初始化holdertexticon */

      holder = new ViewHolder();

      holder.text = (TextView) convertView.findViewById(R.id.text);

      holder.icon = (ImageView) convertView.findViewById(R.id.icon);

     

      convertView.setTag(holder);

    }

    else

    {

      holder = (ViewHolder) convertView.getTag();

    }

 

    File f=new File(paths.get(position).toString());

    /* 设置[回到根目录]的文字与icon */

    if(items.get(position).toString().equals("b1"))

    {

      holder.text.setText("Back to /");

      holder.icon.setImageBitmap(mIcon1);

    }

    /* 设置[回到上一层]的文字与icon */

    else if(items.get(position).toString().equals("b2"))

    {

      holder.text.setText("Back to ..");

      holder.icon.setImageBitmap(mIcon2);

    }

    /* 设置[文件或文件夹]的文字与icon */

    else

    {

      holder.text.setText(f.getName());

      if(f.isDirectory())

      {

        holder.icon.setImageBitmap(mIcon3);

      }

      else

      {

        holder.icon.setImageBitmap(mIcon4);

      }

    }

    return convertView;

  }

 

  /* class ViewHolder */

  private class ViewHolder

  {

    TextView text;

    ImageView icon;

  }

}

自定义的Adapter对象,并以file_row.xml作为Layout,程序中依照文件的类型来决定要显示的图标是什么。 file_row.xml
<!--?xml version="1.0" encoding="utf-8"?-->
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent">
  <imageview android:id="@+id/icon" android:layout_width="30dip" android:layout_height="30dip">
  </imageview>
  <textview android:id="@+id/text" android:layout_gravity="center_vertical" android:layout_width="0dip" android:layout_weight="1.0" android:layout_height="wrap_content" android:textcolor="@drawable/black">
  </textview>
</linearlayout>

写在最后:本范例重点在于如何通过实现自定义的Adapter对象来自定义想要呈现的Layout,以及如何在手机上实现打开文件的功能。

通过自定义的Adapter,可以在ListView中放入任何想要呈现的widget对象,如RadioButton、CheckBox、EditText等,如此一来,在开发程序时,就可以做更多样化得应用。

在主程序中自定义了openFile()这个方法来做打开文件的动作,程序内容如下

  /* 调用getMIMEType()来取得MimeType */
   String type = getMIMEType(f);
   /* 设置intent的file和MimeType */
   intent.setDataAndType(Uri.fromFile(f),type);
startActivity(intent);

其中使用intent.setDataAndType(Uri,type)来指定要打开的文件及文件的MIME Type,并以startActivity()的方式来打开文件。getMIMEType()这个方法中,依据文件的拓展名来设置文件的MIME Type,MIME Type格式为“文件类型/文件拓展名”,目前程序中针对部分类型的文件做MIME Type的判断,其余的文件则一律将MIME Type设置为“*/*”,当系统受到文件的类型为“*”时,会自动弹出应用程序的菜单,让用户自己选择要用哪个程序打开文件。

 

 

 

 

程序中使用java.io.FilerenameToFile newFile)来更改文件名称,需要注意的是,当修改后的文件名原本就已经存在时,程序会将原来的文件覆盖掉,且不会有任何的提示,这样等于是无意间删除了原来旧有的文件。为了预防这种状况发生,程序中先以file.exists()来判断是否有已经存在的文件,如果有,会先跳出警示的AlertDialog,请用户确认是否要覆盖旧文件。假如更改文件名,则可以预防文件无意间被删除的情况发生。

如果想让文件资源管理器的管理功能更强大,可以运用File对象提供的其他方法来实现,比如说,可用file.mkdir()来实现添加文件夹的功能;canRead()canWrite()可以让文件资源管理器具备权限控制的功能。

程序中使用了许多的AlertDialogAndroid API提供了android.app.AlertDialog.Builder对象,可以快速产生AlertDialog对象,以下介绍几种常用的方法,如表5-5所示。

5-5                                                    Mechod名称及功能

 

Method名称

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics