文件管理器项目概述:管理SD卡目录功能及涉及知识点,含布局设计讲解

文件管理器项目概述:管理SD卡目录功能及涉及知识点,含布局设计讲解

一、项目概述

本次带来的文件管理器具备对 SD 卡目录进行管理的能力。其主要功能有新建文件(夹),可以查看文件(夹),能够搜索文件(夹),还能删除文件(夹),并且可以回到根目录。在涉及的知识点方面,包含动态申请权限、自定义 Dialog、自定义菜单、文件系统操作以及适配器等。

二、开发环境

三、详细设计 1、布局设计

我们先来看主页面的布局情况:它的父标签是 RelativeLayout,而相对布局在布置位置方面是最为合适的。在替代之前,需要在 theme 中将主题设置为 Theme.MaterialComponents.Light.NoActionBar。然后,在 MainActivity 中添加代码,以使用 Toolbar 替代原生的 ActionBar。

  // 绑定并设置工具栏
  Toolbar toolbar = findViewById(R.id.toolbar);
  setSupportActionBar(toolbar);

接着放置一个 TextView 来显示文件路径,之后是最为常用的 ListView 以显示文件列表,最后是一个布局,其父标签为 LinearLayout,在这个布局中描绘了一个搜索框。

我们接着来看自定义对话框的布局情况,这是非常清晰明了的。它的作用就是让用户去输入文件的名称,之后再新建文件。

2、程序运行时申请权限

Android6.0 之后需要在运行过程中申请读写外部存储的权限(属于危险权限)。第一步是在 AndroidManifest.xml 里添加我们所需要的权限。

    <uses-permission android:name="android 权限中的 READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android 权限中的 WRITE_EXTERNAL_STORAGE"/>

运行时权限的核心在于,在程序运行过程中,需由用户授权我们去执行某些危险操作,而程序自身不可以擅自去执行这些危险操作。所以,第一步是先判断用户是否已经给予我们授权,这借助的是 ContextCompat.checkSelfPermission()方法。checkSelfPermission()方法接收两个参数。第一个参数是 Context,即上下文。第二个参数是具体的权限名,例如读外存的权限名是 Manifest.permission.READ_EXTERNAL_STORAGE。接着,我们将方法的返回值与 PackageManager.PERMISSION_GRANTED 进行比较。若相等,则说明用户已经授权;若不相等,则表示用户没有授权。

如果已经获得了授权,那就简单了。可以直接去执行查看文件的逻辑操作。我们将这部分操作封装到了 initFile()方法当中。如果没有获得授权,就需要调用 ActivityCompat.requestPermissions() 方法去向用户申请授权。该方法接收 3 个参数,其中第一个参数是 Activity 实例,第二个参数是一个 String 数组,第三个参数是请求码,只要是唯一值就行,这里传入的是 1。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int myPermission = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE);
        if (myPermission != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "请求读取SD卡权限", Toast.LENGTH_SHORT).show();
            // 动态申请权限,请求码为1
            ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        } else {
            initFile();
        }
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 同意权限则初始化文件列表
                    initFile();
                } else {
                    // 拒绝权限
                    Toast.makeText(this, "你拒绝了读写SD卡权限", Toast.LENGTH_SHORT).show();
                    // 退出应用
                    finish();
                }
                break;
            default:
                break;
        }
    }

3、查看文件

用户同意权限后,首先判断手机中是否装载了 sd 卡。若有 sd 卡,就获取 SD 卡的根目录,将当前父目录设为 root,进而获取当前目录下的所有文件。接着通过 for 循环获取所有文件的键值对,并添加到列表中。之后创建和设置适配器,至此就完成了。

    private void initFile() {
        // 判断手机中是否装载了sd卡
        boolean isLoadSDCard = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if (isLoadSDCard) {
            // 获取SD卡的根目录
            root = Environment.getExternalStorageDirectory();
            // 当前父目录为root
            currentParent = root;
            // 获取当前目录的所有文件
            currentFiles = currentParent.listFiles();
            // 加载列表
            inflatelv(currentFiles);
        } else {
            Toast.makeText(this, "SD卡没有被装载", Toast.LENGTH_SHORT).show();
        }
        // 设置列表子项监听器
        setListener();
    }

4、删除文件

文件夹需要先删除目录下的所有文件,接着删除当前文件夹;文件则直接删除当前文件。通过 deleteFile()来进行文件删除,该函数接收的参数是文件对象。在完成删除操作之后,需要重新设置适配器。

   // 如果是文件夹先删除目录下所有文件
   if (!currentFiles[i].isFile()) {
       File[] files = currentFiles[i].listFiles();
       for (int index = 0; index < files.length; index++) {
           deleteFile(files[index].getName());
       }
   }
   // 删除当前文件(夹)
   if (currentFiles[i].delete()) {
       Toast.makeText(view.getContext(), "删除成功", Toast.LENGTH_SHORT).show();
       currentFiles = currentParent.listFiles();
       // 数据源发生改变,重新设置适配器内容
       inflatelv(currentFiles);
   }

5、搜索文件

搜索的原理较为简单。首先进行关键词筛选,通过 contains()方法来判断是否包含关键词。接着,把通过 for 循环得到的列表里的每一个文件对象都放进 File 数组中。最后,重新设置适配器。

 // 搜索按钮进行数据筛选,显示关键词数据源
 ivSearch.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
         String searchName = etSearch.getText().toString().trim();
         List<File> tempFiles = new ArrayList<>();
         for (int i = 0; i < currentFiles.length; i++) {
             if (currentFiles[i].getName().contains(searchName))
                 tempFiles.add(currentFiles[i]);
         }
         File[] files = new File[tempFiles.size()];
         for (int i = 0; i < tempFiles.size(); i++) {
             files[i] = tempFiles.get(i);
         }
         inflatelv(files);
     }
 });

6、新建文件

file.createNewFile()方法的作用是新建文件,这里的 file 指的是准备新建的文件对象;mkdir()方法是用于创建文件夹的,此处在创建文件夹时,file 指的是准备新建的文件夹对象。通过调用 File 的构造方法,并传入文件路径作为参数。

   // 创建个新文件对象,参数为文件路径
   File file = new File(currentParent.getAbsolutePath() + "/" + filename);
   // 创建新文件夹
   file.mkdir();
   newBuildRefresh();
   alertDialog.dismiss();

四、运行演示

启动模拟器后运行 app,进入应用时首先会申请访问 SD 卡的权限。若拒绝该权限,就无法使用应用;若选择允许,便可进入应用。

可以看到屏幕中间显示着 SD 卡的所有目录,并且当前路径是/storage/emulated/0。在屏幕的顶部工具栏中,左侧是应用名称,右侧是功能键,这些功能键分别是返回上级菜单、返回根目录以及新建目录。而屏幕的底部则是搜索栏。

单击子项,若为文件则会提示“无法打开文件”;若为文件夹,为空时会提示“文件夹为空”,不为空则会进入下一级目录。此刻我们进入了 Picture 目录。

4、长按子项,弹出对话框,点击确定即可删除文件或文件夹。

点击新建按钮。然后在下拉菜单中选择文件。接着输入文件名称。再点击新建按钮。如果输入的文件名重复,系统会进行提示。如果文件名不重复,就可以新建成功。

6、在搜索框输入test,点击搜索按钮,出现搜索结果。

7、点击搜索框的关闭按钮,清空搜索结果,显示原先的目录。

点击返回键,能够返回到上级目录。同时,还可以使用中间的根目录键,直接返回根目录。倘若当前处于根目录状态,再次点击返回键的话,就会退出应用。

五、源码获取

想要立刻获取这篇文章的源代码吗?没问题!有两种方式可供选择:一是直接点击下方的 CSDN 专属下载链接,便可轻松获得;二是只需动动手指关注公众号《萌新加油站》,然后回复下方关键词,即可解锁!快来探寻你的技术宝藏,开启编程新征程吧!

1️⃣直接点击右侧链接下载源代码Android文件管理器

2️⃣关注公众号《 萌新加油站 》

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

27阅读

java中冒号,java双冒号

2026年09月06日

26阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

28阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

25阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

25阅读