编程实现Android文件浏览器,实现文件与文件夹的访问

一、设计思路

此实验是要对系统文件进行操作,属于对外部存储的操作范围。主要功能实现部分就要用到Android
File存储中对外部存储访问的相关方法。要想获取系统文件目录,首先要调用Environment 的
getExternalStorageState() 方法来判读外部存储设备是否可用,这里可以用一个 if
语句来进行判断,如果外部存储设备可用(可读写),则Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)返回true,否则给出相应的提示信息。

二、实验过程

在MainActivity中,首先根据Environment.getExternalStorageState()方法判断外部存储是否可用,如果可用,获取外部存储的根目录,然后调用文件管理类FileMgr
的方法获取子文件列表,将文件列表设置到listView自定义的Adapter
中。在onCreate()方法中,对listview的item设置了单击的监听事件onItemClick(……),当item被单击后,用getItem()方法获取对应的文件对象。如果该文件属于文件夹,则用setText(rootFile.getAbsolutePath())方法的获取子目录,并调用Adapter的noifyDataSetChanged()方法刷新页面显示。其中自定义Adapter和文件管理类的代码如下的第5部分展示。
然后在FileMgr中,调用了File原生的listFiles()方法获取文件的子文件集合,只不过通过文件名对隐藏文件做了过滤。在返回结果之前,使用自定义的Comparator对文件集合做了排序。代码如下的第5部分展示
当然,还需搜集要用到的图标文件,放到drawabl文件目录下。

三、源代码

3.1布局文件

"1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    android:id="@+id/txt_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        />
    android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="#00000000"
        android:divider="@drawable/line"
        android:layout_weight="1.14"
        />

view_list_item.xml

"1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">

    
    android:id="@+id/lvew_img"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_margin="8dp"
         />
    
    android:id="@+id/lview_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="20dp"
        android:paddingBottom="20dp"
        android:textColor="#FF0000"
        android:textSize="24sp" />

3.2 java程序文件

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.FileFilter;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private ListViewAdapter mAdapter;
    private TextView mTitle;
    private FileMgr fileMgr;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //用于显示当前文本的路径
        mTitle=(TextView)findViewById(R.id.txt_view);
        //获取ListView控件
        ListView listView = (ListView) findViewById(R.id.list_view);
        //自定义的Adapter
        mAdapter = new ListViewAdapter(this);
        init();
        listView.setAdapter(mAdapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
                //获取当前单击的文件
                File file = mAdapter.getItem(pos);
                //更新显示下级目录
                change(file);
            }
        });
    }
    private void init() {
        fileMgr = new FileMgr();
        //判断外部存储是否可用
        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            Toast.makeText(this, "the external storage is not avaliable", Toast.LENGTH_SHORT).show();
            return;
        }
        File rootFile = Environment.getExternalStorageDirectory();
        mTitle.setText(rootFile.getAbsolutePath());
        //获取当前目录的子文件列表
        List<File> files = fileMgr.getSubFiles(rootFile);
        mAdapter.updateFiles(files);
    }

    private void change(File file) {
        if (!file.isDirectory()) {
            return;
        }
        //更新路径的显示
        mTitle.setText(file.getAbsolutePath());
        //获取新的文件列表
        List<File> files = fileMgr.getSubFiles(file);
        //更新文件和视图显示
        mAdapter.updateFiles(files);
        mAdapter.notifyDataSetChanged();
    }
}

ListViewAdapter.java

package com.example.myapplication;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.io.File;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

public class ListViewAdapter extends BaseAdapter {
    private LayoutInflater flater;
    private List<File>mDatas;

    public ListViewAdapter(Context context) {
        flater = LayoutInflater.from(context);
        mDatas = new ArrayList<File>();
    }

    public void updateFiles(List<File> files) {
        mDatas.clear();
        mDatas.addAll(files);
    }

    public int getCount() {
        return (null == mDatas || mDatas.isEmpty()) ? 0 : mDatas.size();
    }

    @Override
    public File getItem(int pos) {
        if (null != mDatas && pos < mDatas.size()) {
            return mDatas.get(pos);
        }
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position,View convertView, ViewGroup parent) {
        if (null == convertView) {
            //为每一个子项加载布局
            convertView = flater.inflate(R.layout.view_list_item, null);
        }
        //获取 item 布局文件中的控件
        ImageView imageView = (ImageView) convertView.findViewById(R.id.lvew_img);
        TextView txtTitle = (TextView) convertView.findViewById(R.id.lview_title);

        File file = getItem(position);//根据position获取数据
        if (null!=file) {
            imageView.setImageResource(file.isDirectory() ? R.drawable.folder : R.drawable.file);
            txtTitle.setText(file.getName());
        }
        return convertView;
    }
}

FileMgr.java

package com.example.myapplication;

import java.io.File;
import java.io.FilenameFilter;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public class FileMgr {
    public List<File> getSubFiles(File file) {
        File[] files = file.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File f, String name) {
                return !name.startsWith(".");
            }
        });
        System.out.println("file:" + (null == files));
        if (null != files) {
            System.out.println("file mgr length:" + files.length);
        }
        List<File> result = Arrays.asList(files);
        Collections.sort(result, new CustomFileComparator());
        return result;
    }
}

CustomFileComparator.java

package com.example.myapplication;

import java.io.File;
import java.util.Comparator;

public class CustomFileComparator implements Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        File file1 = (File) o1;
        File file2 = (File) o2;

        if (file1.isDirectory()) {
            if (file2.isFile()) {
                return -1;
            }
            return file1.getName().compareTo(file2.getName());
        }
        if (file2.isDirectory()) {
            return 1;
        }
        return file1.getName().compareTo(file2.getName());
    }
}

案例代码资源:http://download.csdn.net/download/weixin_43624626/12352857

四、最终实现效果

点击运行生成的app , 界面如下:
编程实现Android文件浏览器,实现文件与文件夹的访问_第1张图片
点击Pictures 文件夹,显示如下:
编程实现Android文件浏览器,实现文件与文件夹的访问_第2张图片
点击 cache 文件夹,显示如下:
编程实现Android文件浏览器,实现文件与文件夹的访问_第3张图片

你可能感兴趣的:(Android)