Android 从相对 uri 打开 InputStream 到 ACTION_OPEN_DOCUMENT?
Android open InputStream from relative uri to ACTION_OPEN_DOCUMENT?
我正在尝试在 android 4.4(api 级别 19)中打开与 json 配置文件相关的多个文件,
我用了
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType({mime});
this.startActivityForResult(intent, {code});
让用户找到配置文件,并从那里打开我知道配置文件路径的多个文件。
但是我明白了
Caused by: java.lang.SecurityException:
Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider
uri content://com.android.providers.downloads.documents/document/raw:/storage/emulated/0/Download/{relative file}
requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
我不想使用用户界面打开其他文件,所以我尝试添加以下权限但没有得到任何结果
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS "/>
我宁愿将文件分开,而不是在 blob 或 zip 文件中
ACTION_OPEN_DOCUMENT
只允许您访问用户 selects.
的文件(或多个文件,如果您使用 EXTRA_ALLOW_MULTIPLE
)
您可以使用 ACTION_OPEN_DOCUMENT_TREE 允许用户 select 一个文件夹 - 然后您将可以访问该文件夹(及其子文件夹)中的所有文件。
如果您需要让用户从一个文件选择器中选择多个文件,您可以执行以下操作:
它是我应用程序的一部分,您可以根据需要进行调整。这从 API 18
开始有效
private void openFileChooser() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("*/*");
i.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
i.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(i, REQUEST_CODE_DOC_ALL_FILES);
}
那么这里是你如何获得选定的 Uris:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_DOC_ALL_FILES && resultCode == Activity.RESULT_OK) {
if (data == null || (data.getData() == null && data.getClipData() == null)) {
Toast.makeText(getContext(), R.string.invalid_source, Toast.LENGTH_SHORT).show();
return;
}
//get result after user action (selecting files) and transform it into array of Uris
Uri[] uriPaths;
if (data.getData() != null) { // only one uri was selected by user
uriPaths = new Uri[1];
uriPaths[0] = data.getData();
} else if (data.getClipData() != null) {
int selectedCount = data.getClipData().getItemCount();
uriPaths = new Uri[selectedCount];
for (int i = 0; i < selectedCount; i++) {
uriPaths[i] = data.getClipData().getItemAt(i).getUri();
}
}
}
我正在尝试在 android 4.4(api 级别 19)中打开与 json 配置文件相关的多个文件, 我用了
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType({mime});
this.startActivityForResult(intent, {code});
让用户找到配置文件,并从那里打开我知道配置文件路径的多个文件。
但是我明白了
Caused by: java.lang.SecurityException:
Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider
uri content://com.android.providers.downloads.documents/document/raw:/storage/emulated/0/Download/{relative file}
requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
我不想使用用户界面打开其他文件,所以我尝试添加以下权限但没有得到任何结果
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS "/>
我宁愿将文件分开,而不是在 blob 或 zip 文件中
ACTION_OPEN_DOCUMENT
只允许您访问用户 selects.
EXTRA_ALLOW_MULTIPLE
)
您可以使用 ACTION_OPEN_DOCUMENT_TREE 允许用户 select 一个文件夹 - 然后您将可以访问该文件夹(及其子文件夹)中的所有文件。
如果您需要让用户从一个文件选择器中选择多个文件,您可以执行以下操作:
它是我应用程序的一部分,您可以根据需要进行调整。这从 API 18
开始有效private void openFileChooser() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("*/*");
i.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
i.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(i, REQUEST_CODE_DOC_ALL_FILES);
}
那么这里是你如何获得选定的 Uris:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_DOC_ALL_FILES && resultCode == Activity.RESULT_OK) {
if (data == null || (data.getData() == null && data.getClipData() == null)) {
Toast.makeText(getContext(), R.string.invalid_source, Toast.LENGTH_SHORT).show();
return;
}
//get result after user action (selecting files) and transform it into array of Uris
Uri[] uriPaths;
if (data.getData() != null) { // only one uri was selected by user
uriPaths = new Uri[1];
uriPaths[0] = data.getData();
} else if (data.getClipData() != null) {
int selectedCount = data.getClipData().getItemCount();
uriPaths = new Uri[selectedCount];
for (int i = 0; i < selectedCount; i++) {
uriPaths[i] = data.getClipData().getItemAt(i).getUri();
}
}
}