如何在 运行 时间内请求权限后解决 "Access Denied" 错误

How to resolve "Access Denied" Error even after asking for permissions in run time

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

java.io.FileNotFoundException: /data/Afile.txt (Permission denied)

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

    <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 Level 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

方法分开。

但我仍然遇到 "Access Denied" 错误。

请帮我解决这个问题,我该怎么办。

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

我想将它保存在任何更明显的文件夹中,例如 "Downloads or DCIM" 以便轻松访问它,但找不到任何方法,所以我将此文件写在 "data" 文件夹中。

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 方法中使用此代码。

您需要访问 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());
                        }
    }

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