Android文件选择器 路径选择 支持安卓4.4 ~ 13 支持Android/data目录访问 支持SD卡 适配Android11

Android文件路径选择器

Android上进行文件选择或操作的第三方库,自动申请存储权限,支持 Android4.4 ~ 13,再也不用为了适配各种版本而苦恼了,快速集成,一句代码搞定,完善的文档,支持无root权限访问和操作Android/data和Android/obb目录(适配Android 13),支持SD卡,高度自定义UI满足你的所有需求,使用非常灵活,支持国际化,对于Android文件选择你只需要关注你的业务代码即可其他的都交给它。

特性

  • 自动申请存储权限
  • 安卓 4.4 ~ 13
  • Android/data和Android/obb目录访问和操作
  • SD卡
  • 高度自定义UI
  • 国际化
  • 搜索功能

前言

在开始之前可以给项目一个Star吗?非常感谢,你的支持是我唯一的动力。欢迎Star和Issues!
项目地址:
Github地址
Gitee地址

demo演示:

系统版本:Android 13
下载链接:体验APP

pathSelectorDemo.gif

一、快速开始

第1步:添加仓库:
  • 如果你的项目 Gradle 配置是在 7.0 以下,需要在 build.gradle 文件中加入
allprojects {
    repositories {
        ...
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}
  • 如果你的 Gradle 配置是 7.0 及以上,则需要在 settings.gradle 文件中加入
dependencyResolutionManagement {
    repositories {
    	...
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}
第2步:添加远程依赖:
  • 配置完远程仓库后,在项目 app 模块下的 build.gradle 文件中加入远程依赖
dependencies {
    ...
    // 请将"版本"替换成具体的版本号,如 1.1.14
    implementation 'io.github.molihuan:pathselector:版本'
}
第3步:基本用法示范:
//如果没有权限会自动申请权限
PathSelector.build(this, MConstants.BUILD_DIALOG)//Dialog构建方式
        .setMorePopupItemListeners(
                new CommonItemListener("OK") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {

                        StringBuilder builder = new StringBuilder();
                        builder.append("you selected:\n");
                        for (FileBean fileBean : selectedFiles) {
                            builder.append(fileBean.getPath() + "\n");
                        }
                        Mtools.toast(builder.toString());

                        return false;
                    }
                }
        )
        .show();//开始构建

二、基本设置

打开调试模式
//开启调试模式,生产环境请关闭
PathSelectorConfig.setDebug(true);
//或者PathSelector.setDebug(true);
1、Activity构建模式:
//Activity构建方式
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_ACTIVITY)
        .setRequestCode(635)
        .setMorePopupItemListeners(
                new CommonItemListener("OK") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {

                        StringBuilder builder = new StringBuilder();
                        builder.append("you selected:\n");
                        for (FileBean fileBean : selectedFiles) {
                            builder.append(fileBean.getPath() + "\n");
                        }
                        Mtools.toast(builder.toString());

                        return false;
                    }
                }
        )
        .show();
2、Fragment构建模式:
第1步:在你需要显示的布局文件xml中使用FrameLayout占位
<FrameLayout
    android:id="@+id/fragment_select_show_area"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
第2步:编写代码
//获取PathSelectFragment实例然后在onBackPressed中处理返回按钮点击事件
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_FRAGMENT)
        .setFrameLayoutId(R.id.fragment_select_show_area)//加载位置,FrameLayout的ID
        .setMorePopupItemListeners(
                new CommonItemListener("OK") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {

                        StringBuilder builder = new StringBuilder();
                        builder.append("you selected:\n");
                        for (FileBean fileBean : selectedFiles) {
                            builder.append(fileBean.getPath() + "\n");
                        }
                        
                        Mtools.toast(builder.toString());
                        return false;
                    }
                }
        )
        .show();//开始构建
第3步:重写onBackPressed()方法让路径选择器优先处理返回按钮点击事件
非常重要!!!
非常重要!!!
非常重要!!!
重要的事情说三遍
@Override
public void onBackPressed() {

    //让PathSelectFragment先处理返回按钮点击事件
    if (selector != null && selector.onBackPressed()) {
        return;
    }
    ......
    super.onBackPressed();
}
3、Dialog构建模式 & 常用设置:
//获取PathSelectFragment实例然后在onBackPressed中处理返回按钮点击事件
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
        //.setBuildType(MConstants.BUILD_DIALOG)//已经在build中已经设置了
        //.setContext(this)//已经在build中已经设置了
        .setRootPath("/storage/emulated/0/")//初始路径
        .setShowSelectStorageBtn(true)//是否显示内部存储选择按钮
        .setShowTitlebarFragment(true)//是否显示标题栏
        .setShowTabbarFragment(true)//是否显示面包屑
        .setAlwaysShowHandleFragment(true)//是否总是显示长按弹出选项
        .setShowFileTypes("", "mp3", "mp4")//只显示(没有后缀)或(后缀为mp3)或(后缀为mp4)的文件
        .setSelectFileTypes("", "mp3")//只能选择(没有后缀)或(后缀为mp3)的文件
        .setMaxCount(3)//最多可以选择3个文件,默认是-1不限制
        .setRadio()//单选
        .setSortType(MConstants.SORT_NAME_ASC)//按名称排序
        .setTitlebarMainTitle(new FontBean("My Selector"))//设置标题栏主标题,还可以设置字体大小,颜色等
        .setTitlebarBG(Color.GREEN)//设置标题栏颜色
        .setFileItemListener(//设置文件item点击回调(点击是文件才会回调,如果点击是文件夹则不会)
                new FileItemListener() {
                    @Override
                    public boolean onClick(View v, FileBean file, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        Mtools.toast("you clicked path:\n" + file.getPath());
                        return false;
                    }
                }
        )
        .setMorePopupItemListeners(//设置右上角选项回调
                new CommonItemListener("SelectAll") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        pathSelectFragment.selectAllFile(true);
                        return false;
                    }
                },
                new CommonItemListener("DeselectAll") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        pathSelectFragment.selectAllFile(false);
                        return false;
                    }
                }
        )
        .setHandleItemListeners(//设置长按弹出选项回调
                new CommonItemListener("OK") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        StringBuilder builder = new StringBuilder();
                        builder.append("you selected:\n");
                        for (FileBean fileBean : selectedFiles) {
                            builder.append(fileBean.getPath() + "\n");
                        }
                        Mtools.toast(builder.toString());
                        return false;
                    }
                },
                new CommonItemListener("cancel") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        pathSelectFragment.openCloseMultipleMode(false);
                        return false;
                    }
                }
        )
        .show();

三、高级设置(自定义UI)

UI布局:

UiLayout.png

1、自定义选项样式(以HandleItem为例子)
方式1:通过FontBean来设置样式
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
        .setHandleItemListeners(//设置长按弹出选项回调
                //FontBean可以设置文本、字的大小、字的颜色、字左边的图标
    			//R.drawable.ic_test_mlh是你自己的图片资源id
                new CommonItemListener(new FontBean("OK", 18, Color.RED, R.drawable.ic_test_mlh)) {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        Mtools.toast("You Click");
                        return false;
                    }
                }
        )
        .show();
什么?这种方式还不能满足你,那么试试方式2
方式2:重写CommonItemListener的setViewStyle方法来自定义样式
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
        .setHandleItemListeners(
                //重写CommonItemListener的setViewStyle方法来自定义样式
                new CommonItemListener("OK") {
                    @Override
                    public boolean setViewStyle(RelativeLayout container, ImageView leftImg, TextView textView) {
                        textView.setTextSize(18);
                        textView.setTextColor(Color.RED);
                        //默认是不显示图标的
                        leftImg.setVisibility(View.VISIBLE);
                        leftImg.setImageResource(R.drawable.ic_test_mlh);
                        leftImg.getLayoutParams().width = 90;
                        leftImg.getLayoutParams().height = 90;
                        return true;
                    }

                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        Mtools.toast("You Click");
                        return false;
                    }
                }
        )
        .show();
什么?什么?这种方式还不能满足你,那么你来写UI它来帮你添加,试试高度自定义UI
2、高度自定义UI(以Titlebar为例子):
第1步:新建一个布局文件,如:fragment_custom_titlebar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:id="@+id/my_btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="btn1" />

    <Button
        android:id="@+id/my_btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="selectAll" />
    
</LinearLayout>
第2步:新建一个类,如:CustomTitlebarFragment.class使其继承AbstractTitlebarFragment并关联第1步中的布局文件
public class CustomTitlebarFragment extends AbstractTitlebarFragment {
    private Button btn1;
    private Button btn2;
    
    @Override
    public int setFragmentViewId() {
        return R.layout.fragment_custom_titlebar;
    }

    @Override
    public void getComponents(View view) {
        btn1 = view.findViewById(R.id.my_btn1);
        btn2 = view.findViewById(R.id.my_btn2);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Mtools.toast("The current path is:\n" + psf.getCurrentPath());
            }
        });
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                psf.selectAllFile(true);
            }
        });
    }
}
第3步:编写代码
//获取PathSelectFragment实例然后在onBackPressed中处理返回按钮点击事件
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
        .setTitlebarFragment(new CustomTitlebarFragment())
        .show();

四、接口与方法(尽量看源码,都写了注释,懒得写文档)

IConfigDataBuilder
方法注释备注
setFrameLayoutId(int id)设置加载位置FrameLayoutID当构建模式为MConstants.BUILD_FRAGMENT时必须设置
setRequestCode(int code)设置请求码当构建模式为MConstants.BUILD_ACTIVITY时必须设置
setRootPath(String path)设置开始默认路径默认为内部存储根路径
setMaxCount(int maxCount)设置最大选择数量不设置默认为-1 即无限
setShowFileTypes(String… fileTypes)设置显示文件类型没有后缀请用""
setSelectFileTypes(String… fileTypes)设置选择文件类型没有后缀请用""
setSortType(int sortType)设置排序规则类型请看MConstants
setRadio()设置单选默认多选
setShowSelectStorageBtn(boolean var)设置是否显示内部存储选择按钮默认true
setShowTitlebarFragment(boolean var)是否显示标题栏默认true
setShowTabbarFragment(boolean var)是否显示面包屑默认true
setAlwaysShowHandleFragment(boolean var)是否总是显示长按弹出选项默认false
setTitlebarMainTitle(FontBean titlebarMainTitle)设置标题栏主标题还可以设置字体大小,颜色等
setTitlebarBG(Integer titlebarBG)设置标题栏背景颜色
setFileItemListener(FileItemListener fileItemListener)设置文件item点击回调点击是文件才会回调,如果点击是文件夹则不会
setMorePopupItemListeners(CommonItemListener… morePopupItemListener)设置右上角选项回调
setHandleItemListeners(CommonItemListener… handleItemListener)设置长按弹出选项回调
setTitlebarFragment(AbstractTitlebarFragment titlebarFragment)设置自定义标题栏UI自己的Fragment必须继承AbstractTitlebarFragment
setHandleFragment(AbstractHandleFragment handleFragment)设置长按弹出自定义UI自己的Fragment必须继承AbstractHandleFragment
start()开始构建必须调用

五、!!!特别注意 !!!

分区存储
该库以及适配了分区存储,不需要额外适配,你只需要写你的业务代码即可,其他的交给它。
  • 注意该库已经在库的AndroidManifest.xml中添加了:

    <!-- 外部存储的写权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!-- 安卓11额外权限 -->
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />
    <!-- 已经适配了分区存储特性 -->
    <application
            android:preserveLegacyExternalStorage="true"
            android:requestLegacyExternalStorage="true"
            >
    
  • 可能会报错:

    Execution failed for task ':app:processDebugMainManifest'.
    > Manifest merger failed with multiple errors, see logs
    

    请在你的项目中的AndroidManifest.xml设置一致

版本升级
  • 新版本往往解决了旧版本的一些问题、增加了性能、可扩展性…建议升级新版本
  • 请注意因为重构了项目导致了旧版本与新版本不兼容。1.0.x升级1.1.x为非兼容升级,请注意学习新的API
体积过大
  • 已经集成了Blankj/AndroidUtilCode

    如果项目对大小有严格要求请自行下载源码并精简AndroidUtilCode模块

代码混淆
  • 一般来说无需配置,会自动导入混淆规则

特别鸣谢

开源项目以及其依赖项目。

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值