saf存储访问框架(android 4.4 引入)全称 Storage Access Framework
用户可轻松在其所有首选文档存储提供程序中浏览并打开文档、图像及其他文件。
用户可通过易用的标准界面,以统一方式在所有应用和提供程序中浏览文件,以及访问最近使用的文件。
我们可以通过ACTION_OPEN_DOCUMENT或ACTION_OPEN_DOCUMENT_TREE来选择文件或文件夹,获得对应的URI(在Android系统中的地址)
通过URI与DocumentFile工具类来进行添加、编辑、保存和删除的操作
使用方法:选择文件 (ACTION_CREATE_DOCUMENT 创建文件)
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);//必须
intent.setType("*/*");//必须
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri);
startActivityForResult(intent, WRITE_REQUEST_CODE);
其中 uri:
Uri uri = Uri.parse("content://com.android.externalstorage.documents/document/primary:test");
固定格式:content://com.android.externalstorage.documents/document/primary
:test 代表下面的test 文件夹,当然如果再想得到下一级文件夹还需要:既 :test:child
使用方法:选择文件夹
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
//intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri);
startActivityForResult(intent, WRITE_REQUEST_CODE);
其中uri 和第一种一样
借助 implementation "androidx.documentfile:documentfile:1.0.1"
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data == null || resultCode != Activity.RESULT_OK) return;
if (requestCode == WRITE_REQUEST_CODE) {
DocumentFile child = DocumentFile
.fromTreeUri(this, data.getData())
.createDirectory("child")
.createFile("text/plain", "text.txt");
Uri uri = child.getUri();
try {
getContentResolver().openOutputStream(uri).write("成功".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}