英文:
Create new file in the directory returned by Intent.ACTION_OPEN_DOCUMENT_TREE
问题
在我的应用中,用户可以通过隐式意图ACTION_OPEN_DOCUMENT_TREE选择要在其中创建Excel文件的目录。然而,在onActivityResult()
中返回的Uri不能被FileOutputStream()
使用。它会抛出FileNotFoundException
:
java.io.FileNotFoundException: content:/com.android.externalstorage.documents/tree/home%3A:test.xlsx (没有这个文件或目录)
在onActivityResult()
中,我通过File.exists()
检查路径是否存在,如果不存在,我想要创建一个新的Excel文件。
onActivityResult():
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
Log.d(TAG, "onActivityResult: called");
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == 2) {
Log.d(TAG, "onActivityResult: path = " + data.getData().getPath());
Uri treePath = data.getData();
File path = new File(treePath + File.pathSeparator + "test.xlsx");
if (path.exists()) {
updateExistingExcelFile(path);
} else {
createNewExcelFile(path);
}
}
}
createNewExcelFile():
private void createNewExcelFile(File path) {
Log.d(TAG, "createNewExcelFile: called");
Workbook workbook = new HSSFWorkbook();
Cell cell;
Sheet sheet;
sheet = workbook.createSheet("表格名称");
Row row = sheet.createRow(0);
cell = row.createCell(0);
cell.setCellValue("名称");
cell = row.createCell(1);
cell.setCellValue("编号");
sheet.setColumnWidth(0, (10 * 200));
sheet.setColumnWidth(1, (10 * 200));
FileOutputStream fileOutputStream;
try {
fileOutputStream = new FileOutputStream(path);
workbook.write(fileOutputStream);
Toast.makeText(this, "已创建", Toast.LENGTH_LONG).show();
fileOutputStream.close();
} catch (IOException e) {
Log.e(TAG, "createNewExcelFile: ", e);
}
}
如果我在隐式意图路径中使用Activity.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)
或类似的内容,代码完全可以正常工作。
英文:
In my App the user can choose a directory where to create an Excel file using the implicit intent ACTION_OPEN_DOCUMENT_TREE.
However, the Uri returned in onActivityResult()
cannot be used by FileOutputStream()
. It throws a FileNotFoundException
:
java.io.FileNotFoundException: content:/com.android.externalstorage.documents/tree/home%3A:test.xlsx (No such file or directory)
In onActivityResult()
I check if the path exists via File.exists()
and if not, I want to create a new Excel file.
onActivityResult():
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
Log.d(TAG, "onActivityResult: called");
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == 2) {
Log.d(TAG, "onActivityResult: path = " + data.getData()
.getPath());
Uri treePath = data.getData();
File path = new File(treePath + File.pathSeparator + "test.xlsx");
if (path.exists()) {
updateExistingExcelFile(path);
} else {
createNewExcelFile(path);
}
}
}
createNewExcelFile():
private void createNewExcelFile(File path) {
Log.d(TAG, "createNewExcelFile: called");
Workbook workbook = new HSSFWorkbook();
Cell cell;
Sheet sheet;
sheet = workbook.createSheet("Name of sheet");
Row row = sheet.createRow(0);
cell = row.createCell(0);
cell.setCellValue("Name");
cell = row.createCell(1);
cell.setCellValue("Number");
sheet.setColumnWidth(0, (10 * 200));
sheet.setColumnWidth(1, (10 * 200));
FileOutputStream fileOutputStream;
try {
fileOutputStream = new FileOutputStream(path);
workbook.write(fileOutputStream);
Toast.makeText(this, "Created", Toast.LENGTH_LONG)
.show();
fileOutputStream.close();
} catch (IOException e) {
Log.e(TAG, "createNewExcelFile: ", e);
}
}
The code works perfectly fine if I use Activity.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)
or something similar instead of the implicit intents path.
答案1
得分: 22
Step #1: 使用从ACTION_OPEN_DOCUMENT_TREE
获取的Uri
,并传递给DocumentFile.fromTreeUri()
。
Step #2: 调用DocumentFile
上的createFile()
方法,以获取表示子文档的DocumentFile
。
Step #3: 调用在Step #2中创建的DocumentFile
上的getUri()
方法。
Step #4: 调用ContentResolver
上的openOutputStream()
方法,传入Step #3中的Uri
,以获取可用于写入内容的OutputStream
。您可以通过在某些Context
上调用getContentResolver()
(例如Activity
)来获取ContentResolver
。
有关使用ACTION_OPEN_DOCUMENT_TREE
的更多信息,请参阅此博客文章。
英文:
Step #1: Take the Uri
that you get from ACTION_OPEN_DOCUMENT_TREE
and pass it to DocumentFile.fromTreeUri()
.
Step #2: Call createFile()
on that DocumentFile
to get a DocumentFile
representing the child document.
Step #3: Call getUri()
on the DocumentFile
that you created in Step #2.
Step #4: Call openOutputStream()
on a ContentResolver
, passing in the Uri
from Step #3, to get an OutputStream
that you can use to write content. You get a ContentResolver
by calling getContentResolver()
on some Context
, such as an Activity
.
See this blog post for more on using ACTION_OPEN_DOCUMENT_TREE
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论