如何在Android 10上直接从外部下载目录读取文件(Q)

如何在Android 10上直接从外部下载目录读取文件(Q),android,storage,Android,Storage,我正在尝试通过以下操作从Android Q上的下载文件夹读取文件: File downloadDir=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY\u下载); 文件f=新文件(downloadDir,“某些现有文件”); 如果(!f.exists()){ 抛出新的非法状态异常(); } urifuri=Uri.fromFile(f); 试一试{ ParcelFileDescriptor des=getCon

我正在尝试通过以下操作从Android Q上的下载文件夹读取文件:

File downloadDir=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY\u下载);
文件f=新文件(downloadDir,“某些现有文件”);
如果(!f.exists()){
抛出新的非法状态异常();
}
urifuri=Uri.fromFile(f);
试一试{
ParcelFileDescriptor des=getContentResolver().openFileDescriptor(
furi,“r”,空);
}catch(filenotfounde异常){
e、 printStackTrace();
}
我还在清单中设置了
android:requestLegacyExternalStorage=“true”
,并请求了
WRITE\u EXTERNAL\u STORAGE
READ\u EXTERNAL\u STORAGE
运行时权限

文件存在,但尝试打开文件描述符时,出现异常:
java.io.FileNotFoundException:open失败:EACCES(权限被拒绝)

我在安卓Q存储中读取了文件,但不知道如何在没有用户交互的情况下读取文件

谢谢

从Android 6(棉花糖)开始,用户应在运行时授予一些关键权限,以便他/她知道您的应用程序可以访问哪些内容。
这就是你所需要的

编辑
将这些添加到清单中


这将向用户弹出一个对话框以同意权限。如果用户同意调用
onRequestPermissionsResult
方法,那么像这样覆盖
onRequestPermissionsResult

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && requestCode == 2000) {
        //do what you want with files
    }
}


请注意,我将请求代码设置为2000。它是可选的。

此方法在API级别29中被弃用。为了提高用户隐私,不推荐直接访问共享/外部存储设备。当应用程序以Build.VERSION\u CODES.Q为目标时,此方法返回的路径将不再可供应用程序直接访问。应用程序可以通过迁移到上下文#getExternalFilesDir(String)媒体商店、或意图#操作(OPEN)文档等备选方案继续访问存储在共享/外部存储上的内容


复制自Android文档。

在花了太多时间试图弄清楚到底发生了什么之后,我终于找到了解决方案

我在舱单上补充说:

android:requestLegacyExternalStorage=“true” 当直接从Android Studio重建和重新安装时,构建系统或Android运行时不会在清单中注册更改,对
requestLegacyExternalStorage
的请求也不会注册


我通过完全卸载应用程序来修复它:
adb uninstall com.example.app
并从android studio再次安装它。

为什么不直接打开
文件
(例如,使用
FileInputStream
)呢?为什么要使用
Uri
ContentResolver
?请记住,即使使用android:requestLegacyExternalStorage=“true”,您仍然需要请求运行时权限。另外,您从哪里获得下载目录?
FileInputStream
我收到了相同的结果。我没有提到,但我要求获得所需的运行时权限。其他位置是否正常工作?换句话说,您的问题仅限于这一个目录,还是无法访问外部存储上的所有文件?请尝试使用
Environment.directory\u DOCUMENTS
Environment.DCIM
,收到了相同的结果。那么,您在何处以及如何应用android:requestLegacyExternalStorage=“true”可能存在问题。你能发布你的清单吗?嗨,请注意,我说我要求运行时权限。@v0idbar有趣的是,我今天遇到了像你这样的问题。下面的链接帮助了我。试试看。请注意,添加
android:requestLegacyExternalStorage=“true”
是不安全的,因为它是一个临时标志,很快就会被删除。今年年底之前,play store还将强制推出针对新老应用程序的SDK 29。因此,请不要建议将此作为解决方案,而使用此作为解决方案。
if (android.os.Build.VERSION.SDK_INT >= 23 && (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
                PackageManager.PERMISSION_GRANTED)) {
            ActivityCompat.requestPermissions(
                    this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    2000);
        }
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && requestCode == 2000) {
        //do what you want with files
    }
}