#1 上传文件至 ''

Merged
cookiess merged 1 commits from cookiess-patch-1 into master 1 year ago
  1. +17
    -0
      .gitignore
  2. +201
    -0
      LICENSE
  3. +567
    -2
      README.md
  4. +563
    -0
      README_EN.md
  5. +41
    -0
      build.gradle
  6. +172
    -0
      gradlew
  7. +84
    -0
      gradlew.bat
  8. +4
    -0
      settings.gradle

+ 17
- 0
.gitignore View File

@@ -0,0 +1,17 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
gradles
gradle.properties

+ 201
- 0
LICENSE View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [2020] molihuan
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

+ 567
- 2
README.md View File

@@ -1,2 +1,567 @@
# mlhfilesele

<p align="center">
<img src="https://s2.loli.net/2022/12/14/WoYwfehDNHbMzIZ.png" alt="Banner" />
</p>
<h1 align="center">mlhfileselector</h1>
[![Maven Central](https://img.shields.io/maven-central/v/io.github.molihuan/pathselector.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.github.molihuan%22%20AND%20a:%22pathselector%22)[![jitpack](https://jitpack.io/v/molihuan/mlhfileselectorlib.svg)](https://jitpack.io/#molihuan/mlhfileselectorlib)![API: 19-33 (shields.io)](https://img.shields.io/badge/API-19--33-green)[![license: Apache-2.0 (shields.io)](https://img.shields.io/badge/license-Apache--2.0-brightgreen)](https://github.com/molihuan/mlhfileselectorlib/blob/master/LICENSE)[![Star](https://img.shields.io/github/stars/molihuan/mlhfileselectorlib.svg)](https://github.com/molihuan/mlhfileselectorlib)[![bilibili: 玲莫利 (shields.io)](https://img.shields.io/badge/bilibili-玲莫利-orange)](https://space.bilibili.com/454222981)[![CSDN: molihuan (shields.io)](https://img.shields.io/badge/CSDN-molihuan-blue)](https://blog.csdn.net/molihuan)
<h3 align="center">Andriod上提供文件或路径选择的第三方库</h3>
<p align="center">自动申请存储权限,支持安卓4.4 ~ 13,支持Android/data和Android/obb目录访问,</p>
<p align="center">支持自定义UI,支持SD卡。</p>
<p align="center">(Library that provides file or path selection on Android, automatically apply for storage permission, support Android 4.4 to 13, support Android/data and Android/obb directory access, support custom UI,support SD card.The Keyword:file selector operator android/data android 11 android 13)</p>
## 语言(Language)
#### **[中文](./README.md)** | [English](./README_EN.md)
## 为什么选择我
自动申请存储权限,支持 Android4.4 ~ 13,再也不用为了适配各种版本而苦恼了,快速集成,一句代码搞定,完善的文档,支持无root权限访问和操作Android/data和Android/obb目录(适配Android 13),支持SD卡,高度自定义UI满足你的所有需求,使用非常灵活,支持国际化,对于Android文件选择你只需要关注你的业务代码即可其他的都交给它。
## 特性
- [x] 自动申请存储权限(可以控制)
- [x] 安卓 4.4 ~ 13
- [x] Android/data和Android/obb目录访问和操作
- [x] SD卡
- [x] 高度自定义UI
- [x] 国际化
- [ ] 搜索功能
- [x] 自定义图标
- [ ] 显示隐藏文件
## 前言
#### 在开始之前可以给项目一个Star吗?非常感谢,你的支持是我唯一的动力。欢迎Star和Issues!
#### 欢迎Pr,请Pr提交到dev分支
#### 项目地址:
##### [Github地址](https://github.com/molihuan/mlhfileselectorlib)
##### [Gitee地址](https://gitee.com/molihuan/mlhfileselectorlib)
## demo演示:
#### 系统版本:Android 13
#### 下载链接:[体验APP](https://github.com/molihuan/mlhfileselectorlib/tree/master/app/release)
![pathSelectorDemo.gif](https://s2.loli.net/2022/12/14/QSGrIvwzYKhZuMe.gif)
## 一、快速开始
#### 第1步:添加仓库:
- ##### 如果你的项目 Gradle 配置是在 `7.0 以下`,需要在 `build.gradle` 文件中加入
```java
allprojects {
repositories {
...
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
```
- ##### 如果你的 Gradle 配置是 `7.0 及以上`,则需要在 `settings.gradle` 文件中加入
```java
dependencyResolutionManagement {
repositories {
...
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
```
#### 第2步:添加远程依赖:
- ##### 配置完远程仓库后,在项目 app 模块下的 `build.gradle` 文件中加入远程依赖
- ##### 最新发布版:[![Maven Central](https://img.shields.io/maven-central/v/io.github.molihuan/pathselector.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.github.molihuan%22%20AND%20a:%22pathselector%22)
```java
dependencies {
...
// 请将"版本"替换成具体的版本号,如 1.1.11
implementation 'io.github.molihuan:pathselector:版本'
}
```
#### 第3步:基本用法示范:
```java
//如果没有权限会自动申请权限
PathSelector.build(this, MConstants.BUILD_DIALOG)//Dialog构建方式
.setMorePopupItemListeners(
new CommonItemListener("OK") {
@Override
public boolean onClick(View v, TextView tv, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
/**取消dialog弹窗
* pathSelectFragment.dismiss();
*/
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();//开始构建
```
## 二、基本设置
#### 打开调试模式
```java
//开启调试模式,生产环境请关闭
PathSelectorConfig.setDebug(true);
//或者PathSelector.setDebug(true);
```
#### 1、Activity构建模式:
```java
//Activity构建方式
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_ACTIVITY)
.setRequestCode(635)
.setMorePopupItemListeners(
new CommonItemListener("OK") {
@Override
public boolean onClick(View v, TextView tv, 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占位
```xml
<FrameLayout
android:id="@+id/fragment_select_show_area"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
```
##### 第2步:编写代码
```java
//获取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, TextView tv, 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()方法让路径选择器优先处理返回按钮点击事件
<h5 style="color:red"> 非常重要!!!</h5>
<h5 style="color:red"> 非常重要!!!</h5>
<h5 style="color:red"> 非常重要!!!</h5>
##### 重要的事情说三遍
```java
@Override
public void onBackPressed() {
//让PathSelectFragment先处理返回按钮点击事件
if (selector != null && selector.onBackPressed()) {
return;
}
......
super.onBackPressed();
}
```
#### 3、Dialog构建模式 & 常用设置:
```java
//获取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()//单选(如果需要单选文件夹请使用setMaxCount(0)来替换)
.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, TextView tv, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
pathSelectFragment.selectAllFile(true);
return false;
}
},
new CommonItemListener("DeselectAll") {
@Override
public boolean onClick(View v, TextView tv, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
pathSelectFragment.selectAllFile(false);
return false;
}
}
)
.setHandleItemListeners(//设置长按弹出选项回调
new CommonItemListener("OK") {
@Override
public boolean onClick(View v, TextView tv, 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, TextView tv, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
pathSelectFragment.openCloseMultipleMode(false);
return false;
}
}
)
.show();
```
## 三、高级设置(自定义UI)
#### UI布局:
![UiLayout.png](https://s2.loli.net/2022/12/14/Yw8bamgrtNC9yiW.png)
#### 1、自定义选项样式(以HandleItem为例子)
##### 方式1:通过FontBean来设置样式
```java
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, TextView tv, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
Mtools.toast("You Click");
return false;
}
}
)
.show();
```
<h5 style="color:red"> 什么?这种方式还不能满足你,那么试试方式2</h5>
##### 方式2:重写CommonItemListener的setViewStyle方法来自定义样式
```java
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, TextView tv, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
Mtools.toast("You Click");
return false;
}
}
)
.show();
```
<h4 style="color:red"> 什么?什么?这种方式还不能满足你,那么你来写UI它来帮你添加,试试高度自定义UI</h4>
#### 2、高度自定义UI(以Titlebar为例子):
##### 第1步:新建一个布局文件,如:fragment_custom_titlebar.xml
```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步中的布局文件
```java
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步:编写代码
```java
//获取PathSelectFragment实例然后在onBackPressed中处理返回按钮点击事件
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
.setTitlebarFragment(new CustomTitlebarFragment())
.show();
```
#### 3、自定义列表item图标
```java
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
.setFileBeanController(new AbstractFileBeanController() {
@Override
public int getFileBeanImageResource(boolean isDir, String extension, FileBean fileBean) {
int resourceId;
switch (extension) {
case "jpg":
case "jpeg":
case "png":
//开发者自己的图片资源id
resourceId = R.drawable.ic_launcher_foreground;
break;
case "mp3":
resourceId = R.drawable.ic_launcher_foreground;
break;
case "mp4":
//也可以使用默认的图片资源id
resourceId = com.molihuan.pathselector.R.mipmap.movie;
break;
default:
if (isDir) {
//开发者自己的图片资源id
resourceId = R.drawable.ml192;
} else {
resourceId = R.drawable.ic_launcher_background;
}
break;
}
return resourceId;
}
})
.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() | 设置单选(如果需要单选文件夹请使用setMaxCount(0)来替换) | 默认多选 |
| 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`中添加了:
```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"
>
```
- 可能会报错:
```java
Execution failed for task ':app:processDebugMainManifest'.
> Manifest merger failed with multiple errors, see logs
```
请在你的项目中的`AndroidManifest.xml`设置一致
#### 包含Android Support库
- 如果你的项目使用Androidx库,因为此库引用了[getActivity/XXPermissions](https://github.com/getActivity/XXPermissions)库,其包含旧版Support库,会导致冲突而报错。解决办法为在project主目录下的gradle.properties中添加
```
android.enableJetifier=true
```
#### 版本升级
- 新版本往往解决了旧版本的一些问题、增加了性能、可扩展性......建议升级新版本
- 请注意因为重构了项目导致了旧版本与新版本不兼容。1.0.x升级1.1.x为非兼容升级,请注意学习新的API
#### 体积过大
- 已经集成了[Blankj/AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode)
如果项目对大小有严格要求请自行下载源码并精简AndroidUtilCode模块
#### 代码混淆
- 一般来说无需配置,会自动导入混淆规则
# 特别鸣谢
- [getActivity/XXPermissions](https://github.com/getActivity/XXPermissions)
- [CymChad/BaseRecyclerViewAdapterHelper](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)
- [Blankj/AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode)
- [xuexiangjys/XTask](https://github.com/xuexiangjys/XTask)
- [ZLYang110/FileSelector](https://github.com/ZLYang110/FileSelector)
- [zzy0516alex/FileSelectorRelease](https://github.com/zzy0516alex/FileSelectorRelease)
- [folderv/androidDataWithoutRootAPI33](https://github.com/folderv/androidDataWithoutRootAPI33)
开源项目以及其依赖项目。
### LICENSE
```
Copyright [2020] molihuan
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```

+ 563
- 0
README_EN.md View File

@@ -0,0 +1,563 @@
<p align="center">
<img src="https://s2.loli.net/2022/12/14/WoYwfehDNHbMzIZ.png" alt="Banner" />
</p>
<h1 align="center">mlhfileselector</h1>
[![Maven Central](https://img.shields.io/maven-central/v/io.github.molihuan/pathselector.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.github.molihuan%22%20AND%20a:%22pathselector%22)[![jitpack](https://jitpack.io/v/molihuan/mlhfileselectorlib.svg)](https://jitpack.io/#molihuan/mlhfileselectorlib)![API: 19-33 (shields.io)](https://img.shields.io/badge/API-19--33-green)[![license: Apache-2.0 (shields.io)](https://img.shields.io/badge/license-Apache--2.0-brightgreen)](https://github.com/molihuan/mlhfileselectorlib/blob/master/LICENSE)[![Star](https://img.shields.io/github/stars/molihuan/mlhfileselectorlib.svg)](https://github.com/molihuan/mlhfileselectorlib)[![bilibili: 玲莫利 (shields.io)](https://img.shields.io/badge/bilibili-玲莫利-orange)](https://space.bilibili.com/454222981)[![CSDN: molihuan (shields.io)](https://img.shields.io/badge/CSDN-molihuan-blue)](https://blog.csdn.net/molihuan)
<h3 align="center">Library that provides file or path selection on Android</h3>
<p align="center">Automatically apply for storage permission, support Android 4.4 to 13, support Android/data and Android/obb directory access,</p>
<p align="center">support custom UI,support SD card.</p>
<p align="center">(The Keyword:file selector operator android/data android 11 android 13)</p>
## Language(语言)
#### **[Chinese](./README.md)** | [English](./README_EN.md)
## Why choose me?
Automatically apply storage permission, support Android4.4 ~ 13, no longer need to struggle to adapt to various versions, fast integration, a code to get it done, perfect documentation, support no root access and operation of Android/data and Android/obb directory (adapted to Android 13), support SD card, highly customizable UI to meet all your needs, use Very flexible, support internationalization, for Android file selection you just need to focus on your business code and leave the rest to it.
## Characteristics
- [x] Automatically request storage permissions(Can control)
- [x] Android 4.4 ~ 13
- [x] Android/data and Android/obb directory access and manipulation
- [x] SD Card
- [x] Highly customizable UI
- [x] Internationalization
- [ ] Search function
- [x] Custom icon
- [ ] Show hidden files
## Preface
#### Can you give the project a Star before starting? Thank you very much, your support is the only thing that keeps me going. Welcome Star and Issues!
#### Welcome to Pr, please submit to the dev branch
#### Project Address:
##### [Github](https://github.com/molihuan/mlhfileselectorlib)
##### [Gitee](https://gitee.com/molihuan/mlhfileselectorlib)
## Demo:
#### Android version:Android 13
#### Download Links:[Experience App](https://github.com/molihuan/mlhfileselectorlib/tree/master/app/release)
![pathSelectorDemo.gif](https://s2.loli.net/2022/12/14/QSGrIvwzYKhZuMe.gif)
## I. Quick start
#### Step 1: Add the repository:
- ##### If your project Gradle configuration is under `7.0`, you need to add to the `build.gradle` file
```java
allprojects {
repositories {
...
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
```
- ##### If your Gradle configuration is `7.0 and above`, you need to add to your `settings.gradle` file
```java
dependencyResolutionManagement {
repositories {
...
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
```
#### Step 2: Add the remote dependency:
- ##### After configuring the remote repository, add the remote dependency to the `build.gradle` file under the project app module
- ##### Latest Release:[![Maven Central](https://img.shields.io/maven-central/v/io.github.molihuan/pathselector.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.github.molihuan%22%20AND%20a:%22pathselector%22)
```java
dependencies {
...
// Please replace "version" with a specific version number, e.g. 1.1.11
implementation 'io.github.molihuan:pathselector:version'
}
```
#### Step 3: Demonstration of basic usage:
```java
//Permissions will be requested automatically if you don't have them
PathSelector.build(this, MConstants.BUILD_DIALOG)//Dialog build mode
.setMorePopupItemListeners(
new CommonItemListener("OK") {
@Override
public boolean onClick(View v, TextView tv, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
/**Dialog dismiss
* pathSelectFragment.dismiss();
*/
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();//Start building
```
## II. Basic settings
#### Turn on debug mode
```java
//Turn on debug mode, please turn off production environment
PathSelectorConfig.setDebug(true);
//or use PathSelector.setDebug(true);
```
#### 1、Activity build mode:
```java
//Activity build mode
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_ACTIVITY)
.setRequestCode(635)
.setMorePopupItemListeners(
new CommonItemListener("OK") {
@Override
public boolean onClick(View v, TextView tv, 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 build mode:
##### Step 1: Use FrameLayout placeholders in the xml of the layout file you need to display
```xml
<FrameLayout
android:id="@+id/fragment_select_show_area"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
```
##### Step 2: Write the code
```java
//Get the PathSelectFragment instance and then handle the back button click event in onBackPressed
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_FRAGMENT)
.setFrameLayoutId(R.id.fragment_select_show_area)//Load position, ID of FrameLayout
.setMorePopupItemListeners(
new CommonItemListener("OK") {
@Override
public boolean onClick(View v, TextView tv, 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();
```
##### Step 3: Override the onBackPressed() method to let the path selector take precedence over the return button click event
<h5 style="color:red"> Very important!!!</h5>
<h5 style="color:red"> Very important!!!</h5>
<h5 style="color:red"> Very important!!!</h5>
##### Important things are to be repeated for 3 times
```java
@Override
public void onBackPressed() {
//Let PathSelectFragment handle the return button click event first
if (selector != null && selector.onBackPressed()) {
return;
}
......
super.onBackPressed();
}
```
#### 3、Dialog build mode & common settings.
```java
//Get the PathSelectFragment instance and then handle the back button click event in onBackPressed
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
//.setBuildType(MConstants.BUILD_DIALOG)//Already set in the build
//.setContext(this)//Already set in the build
.setRootPath("/storage/emulated/0/")//Initial path
.setShowSelectStorageBtn(true)//Whether to display internal storage selection button
.setShowTitlebarFragment(true)//Whether to display the title bar
.setShowTabbarFragment(true)//Whether to show breadcrumbs
.setAlwaysShowHandleFragment(true)//Whether to always show the long press pop-up option
.setShowFileTypes("", "mp3", "mp4")//Show only files with (no suffix) or (mp3 suffix) or (mp4 suffix)
.setSelectFileTypes("", "mp3")//Only files with (no suffix) or (mp3 suffix) can be selected
.setMaxCount(3)//You can select up to 3 files. The default is - 1 unlimited
.setRadio()//Single choice(Use setMaxCount(0) to replace it if you need a single-selected folder)
.setSortType(MConstants.SORT_NAME_ASC)//Sort by name
.setTitlebarMainTitle(new FontBean("My Selector"))//Set the title bar main title, you can also set the font size, color, etc.
.setTitlebarBG(Color.GREEN)//Set the title bar background color
.setFileItemListener(//Set the callback for the file item click (it will be called back only if it is a file, but not if it is a folder)
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(//Set the top right option callback
new CommonItemListener("SelectAll") {
@Override
public boolean onClick(View v, TextView tv, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
pathSelectFragment.selectAllFile(true);
return false;
}
},
new CommonItemListener("DeselectAll") {
@Override
public boolean onClick(View v, TextView tv, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
pathSelectFragment.selectAllFile(false);
return false;
}
}
)
.setHandleItemListeners(//Set long press pop-up option callback
new CommonItemListener("OK") {
@Override
public boolean onClick(View v, TextView tv, 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, TextView tv, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
pathSelectFragment.openCloseMultipleMode(false);
return false;
}
}
)
.show();
```
## III. Advanced settings (custom UI)
#### UI:
![UiLayout.png](https://s2.loli.net/2022/12/14/Yw8bamgrtNC9yiW.png)
#### 1、custom option style (HandleItem as an example)
##### Way 1:Set the style by FontBean
```java
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
.setHandleItemListeners(//Set long press pop-up option callback
//FontBean can set the text, the size of the word, the color of the word, and the icon to the left of the word
//R.drawable.ic_test_mlh is your own image resource id
new CommonItemListener(new FontBean("OK", 18, Color.RED, R.drawable.ic_test_mlh)) {
@Override
public boolean onClick(View v, TextView tv, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
Mtools.toast("You Click");
return false;
}
}
)
.show();
```
<h5 style="color:red"> What? This way is not enough for you, then try way 2</h5>
##### Way 2: Override CommonItemListener's setViewStyle method to customize the style
```java
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
.setHandleItemListeners(
//Override CommonItemListener's setViewStyle method to customize the style
new CommonItemListener("OK") {
@Override
public boolean setViewStyle(RelativeLayout container, ImageView leftImg, TextView textView) {
textView.setTextSize(18);
textView.setTextColor(Color.RED);
//Icons are not displayed by default
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, TextView tv, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
Mtools.toast("You Click");
return false;
}
}
)
.show();
```
<h4 style="color:red"> What? What? This way is not enough for you, then you write the UI it to help you add, try the highly customizable UI</h4>
#### 2、Highly customizable UI (using Titlebar as an example):
##### Step 1: Create a new layout file, such as:fragment_custom_titlebar.xml
```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>
```
##### Step 2: Create a new class such as:CustomTitlebarFragment.class so that it extends AbstractTitlebarFragment and associates the layout file in step 1
```java
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);
}
});
}
}
```
##### Step 3: Write the code
```java
//Get the PathSelectFragment instance and then handle the back button click event in onBackPressed
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
.setTitlebarFragment(new CustomTitlebarFragment())
.show();
```
#### 3、Customize list item icons
```java
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
.setFileBeanController(new AbstractFileBeanController() {
@Override
public int getFileBeanImageResource(boolean isDir, String extension, FileBean fileBean) {
int resourceId;
switch (extension) {
case "jpg":
case "jpeg":
case "png":
//Developer's own image resource id
resourceId = R.drawable.ic_launcher_foreground;
break;
case "mp3":
resourceId = R.drawable.ic_launcher_foreground;
break;
case "mp4":
//You can also use the default image resource id
resourceId = com.molihuan.pathselector.R.mipmap.movie;
break;
default:
if (isDir) {
//Developer's own image resource id
resourceId = R.drawable.ml192;
} else {
resourceId = R.drawable.ic_launcher_background;
}
break;
}
return resourceId;
}
})
.show();
```
## IV.Interface and methods (try to see the source code, are written comments, lazy to write the document)
##### IConfigDataBuilder
| Method | Role | Comment |
| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| setFrameLayoutId(int id) | Set load location FrameLayout ID | Must be set when the build mode is MConstants.BUILD_FRAGMENT |
| setRequestCode(int code) | Set request code | Must be set when build mode is MConstants.BUILD_ACTIVITY |
| setRootPath(String path) | Set default path to start | Default is the internal storage root path |
| setMaxCount(int maxCount) | Set the maximum number of selections | No setting default is -1 i.e. no limit |
| setShowFileTypes(String... fileTypes) | Set the display file type | No suffix please use "" |
| setSelectFileTypes(String... fileTypes) | Set the selection file type | No suffix please use "" |
| setSortType(int sortType) | Set sorting rules | See MConstants for types |
| setRadio() | Set radio selection(Use setMaxCount(0) to replace it if you need a single-selected folder) | Default Multiple Choice |
| setShowSelectStorageBtn(boolean var) | Set whether to display the internal storage selection button | Default true |
| setShowTitlebarFragment(boolean var) | Whether to display the title bar | Default true |
| setShowTabbarFragment(boolean var) | Whether to show breadcrumbs | Default true |
| setAlwaysShowHandleFragment(boolean var) | Whether to always show the long press pop-up option | Default false |
| setTitlebarMainTitle(FontBean titlebarMainTitle) | Set the main title of the title bar | You can also set the font size, color, etc. |
| setTitlebarBG(Integer titlebarBG) | Set the title bar background color | |
| setFileItemListener(FileItemListener fileItemListener) | Set file item clickback | The callback will be made only if you click on a file, but not if you click on a folder. |
| setMorePopupItemListeners(CommonItemListener... morePopupItemListener) | Set the top right option callback | |
| setHandleItemListeners(CommonItemListener... handleItemListener) | Set long press popup option callback | |
| setTitlebarFragment(AbstractTitlebarFragment titlebarFragment) | Set custom title bar UI | Your own Fragment must extend AbstractTitlebarFragment |
| setHandleFragment(AbstractHandleFragment handleFragment) | Set long press to pop up custom UI | Your own Fragment must extend AbstractHandleFragment |
| start() | Start building | Must be called |
| ...... | ...... | ...... |
## V. !!! Special attention !!!
#### Partition Storage
##### The library is also adapted to partitioned storage, no additional adaptation is needed, you just need to write your business code and leave the rest to it.
- Note that the library has been added to the library's `AndroidManifest.xml`:
```xml
<!-- Write access to external storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android 11 extra permissions -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<!-- Partitioned storage features have been adapted -->
<application
android:preserveLegacyExternalStorage="true"
android:requestLegacyExternalStorage="true"
>
```
- Error may be reported:
```java
Execution failed for task ':app:processDebugMainManifest'.
> Manifest merger failed with multiple errors, see logs
```
Please set the `AndroidManifest.xml` in your project to be consistent
#### Includes android.support library
- If your project uses Androidx library, because this library references the [getActivity/XXPermissions](https://github.com/getActivity/XXPermissions) library, which contains the android.support library, it will cause a conflict and report an error. The solution is to add the following to the gradle.properties in the project's home directory
```
android.enableJetifier=true
```
#### Version Upgrade
- The new version often solves some of the problems of the old version, increases performance, scalability ...... It is recommended to upgrade to a new version
- Please note that the old version is not compatible with the new version due to the refactoring of the project. 1.0.x upgrade 1.1.x is a non-compatible upgrade, please pay attention to learn the new API
#### Excessive volume
- Already integrated with [Blankj/AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode)
If the project has strict requirements on size, please download the source code and streamline the AndroidUtilCode module.
#### Code obfuscation
- Generally no configuration is required, obfuscation rules are imported automatically
# Special Thanks
- [getActivity/XXPermissions](https://github.com/getActivity/XXPermissions)
- [CymChad/BaseRecyclerViewAdapterHelper](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)
- [Blankj/AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode)
- [xuexiangjys/XTask](https://github.com/xuexiangjys/XTask)
- [ZLYang110/FileSelector](https://github.com/ZLYang110/FileSelector)
- [zzy0516alex/FileSelectorRelease](https://github.com/zzy0516alex/FileSelectorRelease)
- [folderv/androidDataWithoutRootAPI33](https://github.com/folderv/androidDataWithoutRootAPI33)
Open source projects and their dependencies.
### LICENSE
```
Copyright [2020] molihuan
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```

+ 41
- 0
build.gradle View File

@@ -0,0 +1,41 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.6.21'//kotlin编译版本
repositories {
// 阿里云云效仓库:https://maven.aliyun.com/mvn/guide
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/google' }
// 华为开源镜像:https://mirrors.huaweicloud.com/
maven { url 'https://repo.huaweicloud.com/repository/maven/' }
// JitPack 远程仓库:https://jitpack.io
maven { url 'https://jitpack.io' }
mavenCentral()
google()
// noinspection JcenterRepositoryObsolete
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.2"
classpath 'com.github.kezong:fat-aar:1.3.8'//打包嵌套aar工具
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"//kotlin编译依赖
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://repo.huaweicloud.com/repository/maven/' }
maven { url 'https://jitpack.io' }
mavenCentral()
google()
// noinspection JcenterRepositoryObsolete
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

+ 172
- 0
gradlew View File

@@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

+ 84
- 0
gradlew.bat View File

@@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

+ 4
- 0
settings.gradle View File

@@ -0,0 +1,4 @@
include ':pathselector'
include ':app'
rootProject.name = "demo01"
include ':AndroidUtilCode'

Loading…
Cancel
Save