Android open InputStream从相对uri到ACTION\u open\u文档?

Android open InputStream从相对uri到ACTION\u open\u文档?,android,relative-path,permission-denied,android-contentresolver,storage-access-framework,Android,Relative Path,Permission Denied,Android Contentresolver,Storage Access Framework,我正在尝试打开多个与android 4.4(api级别19)中的json配置文件相关的文件, 我曾经 让用户找到te配置文件,并从中打开多个文件,我知道配置文件的路径 但我明白了 Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider uri content://com.android.providers.

我正在尝试打开多个与android 4.4(api级别19)中的json配置文件相关的文件, 我曾经

让用户找到te配置文件,并从中打开多个文件,我知道配置文件的路径

但我明白了

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\u OPEN\u DOCUMENT
只允许您访问用户选择的文件(或文件,如果您使用)


您可以使用允许用户选择一个文件夹-然后您可以访问该文件夹中的所有文件(及其子文件夹)。

ACTION\u OPEN\u DOCUMENT
仅允许您访问用户选择的文件(或文件,如果使用)


您可以使用允许用户选择一个文件夹-然后您可以访问该文件夹中的所有文件(及其子文件夹)。

如果需要让用户从文件选择器中选择多个文件,您可以执行以下操作:

这是我的应用程序的一部分,你可以根据自己的需要进行调整。这从API 18开始工作

然后,以下是获取所选URI的方法:

@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();
            }
        } 
}
@覆盖
ActivityResult上的公共void(int请求代码、int结果代码、意图数据){
super.onActivityResult(请求代码、结果代码、数据);
if(requestCode==REQUEST\u CODE\u DOC\u ALL\u FILES&&resultCode==Activity.RESULT\u OK){
if(data==null | |(data.getData()==null&&data.getClipData()==null)){
Toast.makeText(getContext(),R.string.invalid_source,Toast.LENGTH_SHORT).show();
返回;
}
//在用户操作(选择文件)后获取结果,并将其转换为URI数组
Uri[]路径;
如果(data.getData()!=null){//用户只选择了一个uri
uriPaths=新Uri[1];
uriPaths[0]=data.getData();
}else if(data.getClipData()!=null){
int selectedCount=data.getClipData().getItemCount();
uriPaths=新Uri[selectedCount];
对于(int i=0;i
如果需要让用户从文件选择器中选择多个文件,可以执行以下操作:

这是我的应用程序的一部分,你可以根据自己的需要进行调整。这从API 18开始工作

然后,以下是获取所选URI的方法:

@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();
            }
        } 
}
@覆盖
ActivityResult上的公共void(int请求代码、int结果代码、意图数据){
super.onActivityResult(请求代码、结果代码、数据);
if(requestCode==REQUEST\u CODE\u DOC\u ALL\u FILES&&resultCode==Activity.RESULT\u OK){
if(data==null | |(data.getData()==null&&data.getClipData()==null)){
Toast.makeText(getContext(),R.string.invalid_source,Toast.LENGTH_SHORT).show();
返回;
}
//在用户操作(选择文件)后获取结果,并将其转换为URI数组
Uri[]路径;
如果(data.getData()!=null){//用户只选择了一个uri
uriPaths=新Uri[1];
uriPaths[0]=data.getData();
}else if(data.getClipData()!=null){
int selectedCount=data.getClipData().getItemCount();
uriPaths=新Uri[selectedCount];
对于(int i=0;i
您是否设置了读取外部存储和管理文档的运行时权限?我刚刚尝试过,我可以获取读取外部存储,但无法管理文档,并且仍然会被拒绝权限。我使用的是minSdkVersion 19,因此尝试了ActivityCompat。requestPermissions“我正在尝试打开多个文件”--您的代码实际上与打开文件无关。如果您需要将用户限制为您的应用程序可以直接访问的文件系统上的文件,请不要使用系统
Intent
,如
ACTION\u OPEN\u DOCUMENT
。您是否为读取外部存储和管理文档设置了运行时权限?我刚刚尝试过,我可以无法读取外部存储,但无法管理文档,仍然会被拒绝权限。我正在使用minSdkVersion 19,因此尝试使用ActivityCompat。requestPermissions“我正在尝试打开多个文件”--您的代码实际上与打开文件无关。如果您需要将用户限制为文件系统中您的应用程序可以直接访问的文件,请不要使用系统
Intent
,如
ACTION\u OPEN\u DOCUMENT
。ACTION\u OPEN\u DOCUMENT\u TREE是在API级别21中添加的,忘记了指定,但我使用的是minSdkVersion 19,所以我会ant使用它,我想我将只使用zip文件:'(正确,没有等效的pre API 21.ACTION_OPEN_DOCUMENT_树添加到API level 21中,忘记了指定,但我使用的是minSdkVersion 19,所以我不能使用它,我想我将只使用zip文件:'(正确,没有等效的pre API 21)。
@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();
            }
        } 
}