Android 简单文件管理器
开发环境Android studio 4.1.2
运行环境 api 22
ps api 23及以上需动态添加sd卡权限,静态添加无效
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
package com.example.file_manage;import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** 实现文件管理器功能* 2021、3、29* 功能:点击文件夹,进入下一级;点击返回按钮,回到上一级,如果当前是根目录,则退出activity;*/
public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";TextView pathTv;ImageButton backBtn;ListView fileLv;File currentParent;//父目录File[] currentFiles; //当前文件夹的所有文件File root; //sd卡根目录// 用于动态添加权限private static final int REQUEST_EXTERNAL_STORAGE = 1;private static String[] PERMISSIONS_STORAGE = {"android.permission.READ_EXTERNAL_STORAGE","android.permission.WRITE_EXTERNAL_STORAGE" };@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);pathTv=findViewById(R.id.id_tv_filepath);backBtn=findViewById(R.id.id_btn_back);fileLv=findViewById(R.id.id_lv_file);// try { //动态添加读写sd卡的权限,6.0静态添加无效 api23以上
// //检测是否有写的权限
// int permission = ActivityCompat.checkSelfPermission(this,
// "android.permission.WRITE_EXTERNAL_STORAGE");
// if (permission != PackageManager.PERMISSION_GRANTED) {
// // 没有写的权限,去申请写的权限,会弹出对话框
// ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STORAGE);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }// 判断是否装载了sdcardboolean isLoadSDCard = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);if (isLoadSDCard) {
// 获取sdcard的根目录root = Environment.getExternalStorageDirectory();currentParent = root;
// 获取当前文件夹的所有文件currentFiles = currentParent.listFiles();Log.i(TAG, "onCreate: currentFiles:"+currentFiles.length);inflateListView(currentFiles);}else{Toast.makeText(this, "SD卡没有被装载。", Toast.LENGTH_SHORT).show();}setListener();}// 设置监听事件private void setListener() {fileLv.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {if (currentFiles[position].isFile()) {Toast.makeText(MainActivity.this, "无法打开此文件", Toast.LENGTH_SHORT).show();return;}
// 获取当前点击的文件夹当中的所有文件File[] temp = currentFiles[position].listFiles();if (temp == null || temp.length==0) {Toast.makeText(MainActivity.this, "当前文件夹没有内容或不能被访问。", Toast.LENGTH_SHORT).show();}else{
// 修改被点击的这项父目录currentParent = currentFiles[position];currentFiles=temp;
// 数据源发生改变,重新设置适配器内容inflateListView(currentFiles);}}});// 返回按钮事件backBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {
// 判断当前目录是否为sd卡的根目录,就直接退出activity
// 如果不是根目录,就获取当前目录的父目录,然后获得父目录的文件,
// 再重新加载listviewif (currentParent.getAbsolutePath().equals(root.getAbsolutePath())) {MainActivity.this.finish();}else{currentParent = currentParent.getParentFile();currentFiles = currentParent.listFiles();inflateListView(currentFiles);}}});}private void inflateListView(File[] currentFiles) {List<Map<String, Object>> list=new ArrayList<>();for (int i = 0; i < currentFiles.length; i++){Map<String, Object> map = new HashMap<>();map.put("filename", currentFiles[i].getName());if (currentFiles[i].isFile()) { //如果是文件,显示文件图标map.put("icon", R.mipmap.file);}else{ //如果是文件夹,显示文件夹图标map.put("icon", R.mipmap.folder);}list.add(map);}
// 创建适配器SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.item_file_explorer, new String[]{"filename", "icon"}, new int[]{R.id.item_tv, R.id.item_icon});fileLv.setAdapter(adapter);pathTv.setText("当前路径:"+currentParent.getAbsolutePath());}}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/id_tv_filepath"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="文件路径:/mnt/sdcard"/><ImageButtonandroid:id="@+id/id_btn_back"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/back"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"/><ListViewandroid:id="@+id/id_lv_file"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@id/id_tv_filepath"android:layout_above="@id/id_btn_back"android:divider="#000"android:dividerHeight="1dp"/></RelativeLayout>
item_file_explorer.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"android:padding="5dp"><ImageViewandroid:id="@+id/item_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/folder"/><TextViewandroid:id="@+id/item_tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="18sp"android:layout_marginLeft="20dp"android:text="6574654375265867"/></LinearLayout>