【问题标题】:How to resolve "Access Denied" Error even after asking for permissions in run time即使在运行时请求权限后如何解决“访问被拒绝”错误
【发布时间】:2023-03-21 18:03:01
【问题描述】:

我是 Android 新手,我试图在 Android 设备的内部存储中写入一个文本文件。 但我得到了这个例外。

java.io.FileNotFoundException: /data/Afile.txt (权限 拒绝)

我尝试缩小问题范围,发现是权限问题,所以我在清单文件中使用了这些权限。

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

但是问题没有解决,然后我发现从高于 API 级别 23 的版本中,我们必须在运行时请求权限,所以我在运行时使用此函数来请求在内部存储中写入文件的权限。

 private void checkDiskPermission ()
    {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "No Permissions" , Toast.LENGTH_LONG).show();
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 0);
        }
        else
        {
            Toast.makeText(this, "Has Permissions" , Toast.LENGTH_LONG).show();
        }
    }

在写入文件之前,我在按钮单击事件中调用了此函数。 并且还用在了

onCreate

单独的方法。

但我仍然收到“拒绝访问”错误。

请帮助我该怎么做以及如何解决这个问题。

这是在内部存储中写入文件的代码。

我想将它保存在任何更明显的文件夹中,例如“下载或 DCIM”以轻松访问它,但找不到任何方法,因此我将此文件写入“数据”文件夹。

try {
checkDiskPermission();
                    File path = Environment.getDataDirectory();
                    if(!path.exists())
                    {
                        path.mkdirs();
                    }
                    File myfile = new File(path, "Afile.txt");

                    FileWriter writer = new FileWriter(myfile);

                    writer.append("Hello This is sample test!");
                    writer.flush();
                    writer.close();

                    toast = Toast.makeText(getApplicationContext(), "Successful", Toast.LENGTH_SHORT);
                    query.setText(path.toString());
                } catch (Exception ex) {
                    toast = Toast.makeText(getApplicationContext(), "Failed", Toast.LENGTH_SHORT);
                    query.setText("Catch " + ex.toString());
                }

我在按钮的 onClick 方法中使用此代码。

【问题讨论】:

    标签: java android text-files filewriter access-denied


    【解决方案1】:

    在几乎所有操作系统中,每个文件/文件夹都具有所有权/权限,并且根据尝试访问它的用户,它可以完全允许或拒绝用户(显示为Permission Denied)。 /data/文件夹是Android系统本身拥有的私有文件夹。即使已授予存储权限,任何尝试访问它的应用程序都将被拒绝。应用程序允许读取和写入某些位置。使用Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS) 而不是Environment.getDataDirectory()。检查以下链接中的内部和外部文件存储部分,了解如何操作:Data and file storage overview

    【讨论】:

    • 谢谢。你能指导我如何使用内部存储中的下载文件夹吗?
    • 刚刚更新了使用下载文件夹的答案。如果您还需要帮助,请告诉我。
    • @ahasbini 在 android LOLLIPOP 之后你可能需要使用 FileProvider,查看我的answer 了解更多信息。
    • @KhaledLela FileProvider 用于访问存储在私人位置并由其他应用程序拥有的文件。由于目标是访问公共场所,因此不需要FileProvider
    • @ahasbini 你能支持我的问题吗?我不知道为什么有人反对它。
    【解决方案2】:

    您需要访问checkDiskPermission 结果中的文件夹和文件 不是在它之后。只需在调用checkDiskPermission 后将代码剪切并在下面这个方法中移动它们:

    private void checkDiskPermission ()
        {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                    && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "No Permissions" , Toast.LENGTH_LONG).show();
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 0);
            }
            else
            {
               accessFilesAndFolders();
            }
        }
    
    
         @Override
            public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {
    
                //move the accessing files and creating folders all here.
                  accessFilesAndFolders();
    
                }
    
        void accessFilesAndFolders(){
         try {
                                File path = Environment.getDataDirectory();
                                if(!path.exists())
                                {
                                    path.mkdirs();
                                }
                                File myfile = new File(path, "Afile.txt");
                enter code here
                                FileWriter writer = new FileWriter(myfile);
    
                                writer.append("Hello This is sample test!");
                                writer.flush();
                                writer.close();
    
                                toast = Toast.makeText(getApplicationContext(), "Successful", Toast.LENGTH_SHORT);
                                query.setText(path.toString());
                            } catch (Exception ex) {
                                toast = Toast.makeText(getApplicationContext(), "Failed", Toast.LENGTH_SHORT);
                                query.setText("Catch " + ex.toString());
                            }
        }
    

    【讨论】:

    • 谢谢。让我试试这个。
    • 在哪里调用这个方法? onRequestPermissionsResult
    • 你不需要调用它。它会在你调用checkDiskPermission(); 方法后被调用
    • 但它没有。我试过了,但它不工作。只有else { Toast.makeText(this, "Has Permissions" , Toast.LENGTH_LONG).show(); }这部分checkDiskPermission();正在执行
    • 检查我编辑的答案。因为您允许了一次权限,它将被保存在应用程序存储中,并且永远不会被请求权限,但是您卸载应用程序并再次安装它会再次询问。
    猜你喜欢
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-20
    • 2021-09-14
    • 2022-01-15
    • 1970-01-01
    相关资源
    最近更新 更多