uniqueSolutions
uniqueSolutions

Reputation: 163

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

I am new to Android and i was trying to write a text file in the internal storage of the Android device. But i am getting this exception.

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

I try to narrow down the problem and i found that it's the problem of permissions so i use these permissions in the manifest file.

    <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" />

But the problem was not solved then i found out that from higher versions than API Level 23 we've to ask for permissions during runtime so i used this function in runtime to ask for permission to write file in internal storage.

 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();
        }
    }

I called this function in button click event before writing the file. And also used it in the

onCreate

method separately.

But i am still getting the "Access Denied" Error.

Please help me what should i do and how to solve this problem.

Here is the Code for writing the File in the internal storage.

I wanted to save it in any more obvious folder Like "Downloads or DCIM" to access it easily but could not found any method for that so I am writing this file in "data" folder.

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());
                }

I am using this code in the onClick Method of a button.

Upvotes: 1

Views: 4511

Answers (2)

ahasbini
ahasbini

Reputation: 6901

In almost all Operating Systems, each file/folder has ownership rights/permissions and based on the user trying to access it, it either allows or denies the user completely (shows as Permission Denied). The folder /data/ is private folder owned by the Android system itself. Any app trying to access it will be denied, even if the Storage permission has been granted. Certain locations are allowed by the app to read from and write to. Use Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS) instead of Environment.getDataDirectory(). Check internal and external file storage sections in the following link on how to do so: Data and file storage overview

Upvotes: 2

matio
matio

Reputation: 427

You need to access the folders and files in the result of the checkDiskPermission not after it. Just cut the codes after calling checkDiskPermission and move them in this method below:

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());
                        }
    }

Upvotes: 0

Related Questions