diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..c1f0d04 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index c1215b5..59f1539 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,10 @@ +## 语言(Language) + +#### **[中文](./README.md)** | [English](./README_EN.md) + ## 为什么选择我 自动申请存储权限,支持 Android4.4 ~ 13,再也不用为了适配各种版本而苦恼了,快速集成,一句代码搞定,完善的文档,支持无root权限访问和操作Android/data和Android/obb目录(适配Android 13),支持SD卡,高度自定义UI满足你的所有需求,使用非常灵活,支持国际化,对于Android文件选择你只需要关注你的业务代码即可其他的都交给它。 @@ -28,13 +32,9 @@ - [x] 高度自定义UI - [x] 国际化 - [ ] 搜索功能 -- [ ] 自定义图标 +- [x] 自定义图标 - [ ] 显示隐藏文件 -## 语言(Language) - -#### **[中文](./README.md)** | [English](./README_EN.md) - ## 前言 #### 在开始之前可以给项目一个Star吗?非常感谢,你的支持是我唯一的动力。欢迎Star和Issues! @@ -234,7 +234,7 @@ PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG) .setShowFileTypes("", "mp3", "mp4")//只显示(没有后缀)或(后缀为mp3)或(后缀为mp4)的文件 .setSelectFileTypes("", "mp3")//只能选择(没有后缀)或(后缀为mp3)的文件 .setMaxCount(3)//最多可以选择3个文件,默认是-1不限制 - .setRadio()//单选 + .setRadio()//单选(如果需要单选文件夹请使用setMaxCount(0)来替换) .setSortType(MConstants.SORT_NAME_ASC)//按名称排序 .setTitlebarMainTitle(new FontBean("My Selector"))//设置标题栏主标题,还可以设置字体大小,颜色等 .setTitlebarBG(Color.GREEN)//设置标题栏颜色 @@ -412,34 +412,73 @@ PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG) .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() | 设置单选 | 默认多选 | -| 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() | 开始构建 | 必须调用 | -| ...... | ...... | | +| 方法 | 作用 | 备注 | +| ------------------------------------------------------------ | ------------------------------------------------------ | ----------------------------------------------- | +| 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() | 开始构建 | 必须调用 | +| ...... | ...... | | ## 五、!!!特别注意 !!! diff --git a/README_EN.md b/README_EN.md index 068d819..95779e4 100644 --- a/README_EN.md +++ b/README_EN.md @@ -13,7 +13,9 @@

support custom UI,support SD card.

(The Keyword:file selector operator android/data android 11 android 13)

+## Language(语言) +#### **[Chinese](./README.md)** | [English](./README_EN.md) ## Why choose me? @@ -28,13 +30,9 @@ Automatically apply storage permission, support Android4.4 ~ 13, no longer need - [x] Highly customizable UI - [x] Internationalization - [ ] Search function -- [ ] Custom icon +- [x] Custom icon - [ ] Show hidden files -## Language(语言) - -#### **[Chinese](./README.md)** | [English](./README_EN.md) - ## 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! @@ -234,7 +232,7 @@ PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG) .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 + .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 @@ -412,6 +410,43 @@ PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG) .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 @@ -426,7 +461,7 @@ PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG) | 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 | Default Multiple Choice | +| 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 | diff --git a/app/build.gradle b/app/build.gradle index fa959ba..dcad6f0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -44,7 +44,7 @@ dependencies { // implementation fileTree(dir: "../pathselector/build/outputs/aar/", includes: ["*-release.aar", "*.jar"]) // implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.11' -// implementation 'com.github.getActivity:XXPermissions:16.2' + implementation 'com.github.getActivity:XXPermissions:16.5' //调试用 diff --git a/app/release/app-release.apk b/app/release/app-release.apk index ad1f9c7..43c3395 100644 Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ diff --git a/app/src/main/java/com/molihuan/pathselectdemo/activity/MainActivity.java b/app/src/main/java/com/molihuan/pathselectdemo/activity/MainActivity.java index 633072c..b15d74c 100644 --- a/app/src/main/java/com/molihuan/pathselectdemo/activity/MainActivity.java +++ b/app/src/main/java/com/molihuan/pathselectdemo/activity/MainActivity.java @@ -14,6 +14,7 @@ import com.molihuan.pathselectdemo.fragments.CustomTitlebarFragment; import com.molihuan.pathselector.PathSelector; import com.molihuan.pathselector.configs.PathSelectorConfig; +import com.molihuan.pathselector.controller.AbstractFileBeanController; import com.molihuan.pathselector.entity.FileBean; import com.molihuan.pathselector.entity.FontBean; import com.molihuan.pathselector.fragment.BasePathSelectFragment; @@ -40,6 +41,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe private Button btnDialogSelector; private Button btnCustomSelector; private Button btnTest; + private Button btnCustomImgSelector; private PathSelectFragment selector; private long firstBackTime; @@ -62,6 +64,7 @@ private void getComponents() { btnDialogSelector = findViewById(R.id.btn_dialog_selector); btnCustomSelector = findViewById(R.id.btn_custom_toolbar_selector); btnTest = findViewById(R.id.btn_test); + btnCustomImgSelector = findViewById(R.id.btn_custom_filebean_img_selector); } private void initData() { @@ -79,11 +82,11 @@ private void setListeners() { btnDialogSelector.setOnClickListener(this); btnCustomSelector.setOnClickListener(this); btnTest.setOnClickListener(this); + btnCustomImgSelector.setOnClickListener(this); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); } @@ -102,7 +105,6 @@ public void onClick(View v) { break; case R.id.btn_custom_toolbar_selector: customTitlebarSelectShow(); -// t1(); break; case R.id.btn_test: FragmentTools.fragmentReplace( @@ -111,6 +113,10 @@ public void onClick(View v) { new CustomTitlebarFragment(), "55" ); + + break; + case R.id.btn_custom_filebean_img_selector: + customFilebeanImgSelectShow(); break; } } @@ -122,6 +128,7 @@ public void onClick(View v) { private void dialogSelectShow() { //获取PathSelectFragment实例onBackPressed中处理返回按钮点击事件 selector = PathSelector.build(MainActivity.this, MConstants.BUILD_DIALOG) + .setRootPath("/storage/emulated/0/bilibili视频合并/") .setMorePopupItemListeners( new CommonItemListener("SelectAll") { @Override @@ -275,7 +282,7 @@ public boolean onClick(View v, TextView tv, List selectedFiles, String * 自定义Toolbar方式 */ private void customTitlebarSelectShow() { - PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG) + selector = PathSelector.build(this, MConstants.BUILD_DIALOG) .setTitlebarFragment(new CustomTitlebarFragment()) .show(); } @@ -285,7 +292,7 @@ private void customTitlebarSelectShow() { */ private void CompleteConfiguration() { - PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG) + selector = PathSelector.build(this, MConstants.BUILD_DIALOG) //.setBuildType(MConstants.BUILD_DIALOG)//已经在build中已经设置了 //.setContext(this)//已经在build中已经设置了 .setRootPath("/storage/emulated/0/")//初始路径 @@ -350,6 +357,46 @@ public boolean onClick(View v, TextView tv, List selectedFiles, String } + + /** + * 自定义Filebean Img + */ + private void customFilebeanImgSelectShow() { + 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_mlh; + break; + default: + if (isDir) { + //开发者自己的图片资源id + resourceId = R.drawable.ml192; + } else { + resourceId = R.drawable.ic_launcher_background; + } + break; + } + return resourceId; + } + }) + .show(); + + } + @Override public void onBackPressed() { diff --git a/app/src/main/java/com/molihuan/pathselectdemo/fragments/CustomTitlebarFragment.java b/app/src/main/java/com/molihuan/pathselectdemo/fragments/CustomTitlebarFragment.java index 4425d62..c982464 100644 --- a/app/src/main/java/com/molihuan/pathselectdemo/fragments/CustomTitlebarFragment.java +++ b/app/src/main/java/com/molihuan/pathselectdemo/fragments/CustomTitlebarFragment.java @@ -7,6 +7,11 @@ import com.molihuan.pathselector.fragment.AbstractTitlebarFragment; import com.molihuan.pathselector.utils.Mtools; +/** + * @ClassName CustomTitlebarFragment + * @Author molihuan + * @Date 2022/12/22 6:50 + */ public class CustomTitlebarFragment extends AbstractTitlebarFragment { private Button btn1; @@ -35,5 +40,5 @@ public void onClick(View v) { } }); } - + } \ No newline at end of file diff --git a/app/src/main/java/com/molihuan/pathselectdemo/utils/DocumentsUtils.java b/app/src/main/java/com/molihuan/pathselectdemo/utils/DocumentsUtils.java deleted file mode 100644 index f01f3c4..0000000 --- a/app/src/main/java/com/molihuan/pathselectdemo/utils/DocumentsUtils.java +++ /dev/null @@ -1,323 +0,0 @@ -package com.molihuan.pathselectdemo.utils; - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.SharedPreferences; -import android.net.Uri; -import android.os.Build; -import android.preference.PreferenceManager; -import android.provider.DocumentsContract; -import android.util.Log; - -import androidx.documentfile.provider.DocumentFile; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - - -public class DocumentsUtils { - - private static final String TAG = DocumentsUtils.class.getSimpleName(); - - public static final int OPEN_DOCUMENT_TREE_CODE = 8000; - - private static List sExtSdCardPaths = new ArrayList<>(); - - private DocumentsUtils() { - - } - - public static void cleanCache() { - sExtSdCardPaths.clear(); - } - - /** - * Get a list of external SD card paths. (Kitkat or higher.) - * - * @return A list of external SD card paths. - */ - @TargetApi(Build.VERSION_CODES.KITKAT) - private static String[] getExtSdCardPaths(Context context) { - if (sExtSdCardPaths.size() > 0) { - return sExtSdCardPaths.toArray(new String[0]); - } - for (File file : context.getExternalFilesDirs("external")) { - if (file != null && !file.equals(context.getExternalFilesDir("external"))) { - int index = file.getAbsolutePath().lastIndexOf("/Android/data"); - if (index < 0) { - Log.w(TAG, "Unexpected external file dir: " + file.getAbsolutePath()); - } else { - String path = file.getAbsolutePath().substring(0, index); - try { - path = new File(path).getCanonicalPath(); - } catch (IOException e) { - // Keep non-canonical path. - } - sExtSdCardPaths.add(path); - } - } - } - if (sExtSdCardPaths.isEmpty()) sExtSdCardPaths.add("/storage/sdcard1"); - return sExtSdCardPaths.toArray(new String[0]); - } - - /** - * Determine the main folder of the external SD card containing the given file. - * - * @param file the file. - * @return The main folder of the external SD card containing this file, if the file is on an SD - * card. Otherwise, - * null is returned. - */ - @TargetApi(Build.VERSION_CODES.KITKAT) - private static String getExtSdCardFolder(final File file, Context context) { - String[] extSdPaths = getExtSdCardPaths(context); - try { - for (int i = 0; i < extSdPaths.length; i++) { - if (file.getCanonicalPath().startsWith(extSdPaths[i])) { - return extSdPaths[i]; - } - } - } catch (IOException e) { - return null; - } - return null; - } - - /** - * Determine if a file is on external sd card. (Kitkat or higher.) - * - * @param file The file. - * @return true if on external sd card. - */ - @TargetApi(Build.VERSION_CODES.KITKAT) - public static boolean isOnExtSdCard(final File file, Context c) { - return getExtSdCardFolder(file, c) != null; - } - - /** - * Get a DocumentFile corresponding to the given file (for writing on ExtSdCard on Android 5). - * If the file is not - * existing, it is created. - * - * @param file The file. - * @param isDirectory flag indicating if the file should be a directory. - * @return The DocumentFile - */ - public static DocumentFile getDocumentFile(final File file, final boolean isDirectory, - Context context) { - - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { - return DocumentFile.fromFile(file); - } - - String baseFolder = getExtSdCardFolder(file, context); - Log.i(TAG, " baseFolder " + baseFolder); - boolean originalDirectory = false; - if (baseFolder == null) { - return null; - } - - String relativePath = null; - try { - String fullPath = file.getCanonicalPath(); - if (!baseFolder.equals(fullPath)) { - relativePath = fullPath.substring(baseFolder.length() + 1); - } else { - originalDirectory = true; - } - } catch (IOException e) { - return null; - } catch (Exception f) { - originalDirectory = true; - //continue - } - String as = PreferenceManager.getDefaultSharedPreferences(context).getString(baseFolder, - null); - - Uri treeUri = null; - if (as != null) treeUri = Uri.parse(as); - if (treeUri == null) { - return null; - } - - // start with root of SD card and then parse through document tree. - DocumentFile document = DocumentFile.fromTreeUri(context, treeUri); - if (originalDirectory) return document; - String[] parts = relativePath.split("/"); - for (int i = 0; i < parts.length; i++) { - DocumentFile nextDocument = document.findFile(parts[i]); - - if (nextDocument == null) { - if ((i < parts.length - 1) || isDirectory) { - nextDocument = document.createDirectory(parts[i]); - } else { - nextDocument = document.createFile("image", parts[i]); - } - } - document = nextDocument; - } - - return document; - } - - public static boolean mkdirs(Context context, File dir) { - boolean res = dir.mkdirs(); - if (!res) { - if (DocumentsUtils.isOnExtSdCard(dir, context)) { - DocumentFile documentFile = DocumentsUtils.getDocumentFile(dir, true, context); - res = documentFile != null && documentFile.canWrite(); - } - } - return res; - } - - public static boolean delete(Context context, File file) { - boolean ret = file.delete(); - if (!ret && DocumentsUtils.isOnExtSdCard(file, context)) { - DocumentFile f = DocumentsUtils.getDocumentFile(file, false, context); - if (f != null) { - ret = f.delete(); - } - } - return ret; - } - - public static boolean canWrite(File file) { - boolean res = file.exists() && file.canWrite(); - - if (!res && !file.exists()) { - try { - if (!file.isDirectory()) { - res = file.createNewFile() && file.delete(); - } else { - res = file.mkdirs() && file.delete(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - return res; - } - - public static boolean canWrite(Context context, File file) { - boolean res = canWrite(file); - - if (!res && DocumentsUtils.isOnExtSdCard(file, context)) { - DocumentFile documentFile = DocumentsUtils.getDocumentFile(file, true, context); - res = documentFile != null && documentFile.canWrite(); - } - return res; - } - - public static boolean renameTo(Context context, File src, File dest) { - boolean res = src.renameTo(dest); - - if (!res && isOnExtSdCard(dest, context)) { - DocumentFile srcDoc; - if (isOnExtSdCard(src, context)) { - srcDoc = getDocumentFile(src, false, context); - } else { - srcDoc = DocumentFile.fromFile(src); - } - DocumentFile destDoc = getDocumentFile(dest.getParentFile(), true, context); - if (srcDoc != null && destDoc != null) { - try { - if (src.getParent().equals(dest.getParent())) { - res = srcDoc.renameTo(dest.getName()); - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - res = DocumentsContract.moveDocument(context.getContentResolver(), - srcDoc.getUri(), - srcDoc.getParentFile().getUri(), - destDoc.getUri()) != null; - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - return res; - } - - public static InputStream getInputStream(Context context, File destFile) { - InputStream in = null; - try { - if (!canWrite(destFile) && isOnExtSdCard(destFile, context)) { - DocumentFile file = DocumentsUtils.getDocumentFile(destFile, false, context); - if (file != null && file.canWrite()) { - in = context.getContentResolver().openInputStream(file.getUri()); - } - } else { - in = new FileInputStream(destFile); - - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return in; - } - - public static OutputStream getOutputStream(Context context, File destFile) { - OutputStream out = null; - try { - if (!canWrite(destFile) && isOnExtSdCard(destFile, context)) { - DocumentFile file = DocumentsUtils.getDocumentFile(destFile, false, context); - if (file != null && file.canWrite()) { - out = context.getContentResolver().openOutputStream(file.getUri()); - } - } else { - out = new FileOutputStream(destFile); - - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return out; - } - - public static boolean saveTreeUri(Context context, String rootPath, Uri uri) { - DocumentFile file = DocumentFile.fromTreeUri(context, uri); - if (file != null && file.canWrite()) { - SharedPreferences perf = PreferenceManager.getDefaultSharedPreferences(context); - perf.edit().putString(rootPath, uri.toString()).apply(); - Log.e(TAG, "save uri" + rootPath); - return true; - } else { - Log.e(TAG, "no write permission: " + rootPath); - } - return false; - } - - public static boolean checkWritableRootPath(Context context, String rootPath) { - File root = new File(rootPath); - if (!root.canWrite()) { - - if (DocumentsUtils.isOnExtSdCard(root, context)) { - Log.i(TAG, "isOnExtSdCard"); - DocumentFile documentFile = DocumentsUtils.getDocumentFile(root, true, context); - return documentFile == null || !documentFile.canWrite(); - } else { - Log.i(TAG, " get perf"); - SharedPreferences perf = PreferenceManager.getDefaultSharedPreferences(context); - - String documentUri = perf.getString(rootPath, ""); - - if (documentUri == null || documentUri.isEmpty()) { - return true; - } else { - DocumentFile file = DocumentFile.fromTreeUri(context, Uri.parse(documentUri)); - return !(file != null && file.canWrite()); - } - } - } - return false; - } -} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 9531c9a..214b41c 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -40,6 +40,12 @@ android:layout_height="wrap_content" android:text="自定义toolbar选择器" /> +