Как устранить ошибку «Отказано в доступе» даже после запроса разрешений во время выполнения - PullRequest
0 голосов
/ 05 сентября 2018

Я новичок в 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», чтобы получить к нему легкий доступ, но не смог найти для этого никакого способа, поэтому я записываю этот файл в папку «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 кнопки.

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Практически во всех операционных системах каждый файл / папка имеет права / разрешения на владение и, основываясь на том, что пользователь пытается получить к нему доступ, разрешает или запрещает пользователю полностью (отображается как Permission Denied). Папка /data/ является частной папкой, принадлежащей самой системе Android. Любому приложению, пытающемуся получить к нему доступ, будет отказано, даже если разрешение на хранение было предоставлено. Определенные местоположения разрешены приложением для чтения и записи. Используйте Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS) вместо Environment.getDataDirectory(). Чтобы узнать, как это сделать, проверьте разделы внутреннего и внешнего хранилища файлов в следующей ссылке: Обзор хранилища данных и файлов

0 голосов
/ 05 сентября 2018

Вам необходимо получить доступ к папкам и файлам в результате 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());
                        }
    }
...