permission denied при createNewFile на SD карту api 23

409
23 января 2018, 11:55

Здравствуйте.

package com.elf_m.android.testsdcard;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import android.support.design.widget.Snackbar;
public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
    Button mButton;
    private View mLayout;
    private static final int PERMISSION_STORAGE = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mLayout = findViewById(R.id.main_layout);

        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SaveFile();
            }
        });
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                           int[] grantResults) {
        // BEGIN_INCLUDE(onRequestPermissionsResult)
        if (requestCode == PERMISSION_STORAGE) {
            // Request for camera permission.
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission has been granted. Start camera preview Activity.
                Toast.makeText(this, "WRITE_EXTERNAL_STORAGE. Starting SaveFile", Toast.LENGTH_SHORT).show();
                SaveFileToSD();
            } else {
                // Permission request was denied.
                Toast.makeText(this, "WRITE_EXTERNAL_STORAGE permission request was denied.", Toast.LENGTH_SHORT).show();
            }
        }
        // END_INCLUDE(onRequestPermissionsResult)
    }
    private void SaveFile() {
        // BEGIN_INCLUDE(startCamera)
        // Check if the Camera permission has been granted
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            // Permission is already available, start camera preview
            Toast.makeText(this,
                    "WRITE_EXTERNAL_STORAGE is available.", Toast.LENGTH_SHORT).show();
            SaveFileToSD();
        } else {
            // Permission is missing and must be requested.
            requestWRITEEXTERNALPermission();
        }
        // END_INCLUDE(startCamera)
    }
    private void requestWRITEEXTERNALPermission() {
        // Permission has not been granted and must be requested.
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            // Provide an additional rationale to the user if the permission was not granted
            // and the user would benefit from additional context for the use of the permission.
            // Display a SnackBar with a button to request the missing permission.
            Snackbar.make(mLayout, "WRITE_EXTERNAL_STORAGE access is required to display the camera preview.",
                    Snackbar.LENGTH_INDEFINITE).setAction("OK", new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Request the permission
                    ActivityCompat.requestPermissions(MainActivity.this,
                            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                            PERMISSION_STORAGE);
                }
            }).show();
        } else {
            Snackbar.make(mLayout,
                    "Permission is not available. Requesting WRITE_EXTERNAL_STORAGE permission.",
                    Snackbar.LENGTH_SHORT).show();
            // Request the permission. The result will be received in onRequestPermissionResult().
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    PERMISSION_STORAGE);
        }
    }
    public void SaveFileToSD() {
        try
        {
            File fhandle = new File(getSDcardPath().toString() + "/myfolder111/test.txt");
            //Если нет директорий в пути, то они будут созданы:
            if (!fhandle.exists())
                if(!fhandle.mkdirs())
                    Log.d("test", "Ошибка создания папки!");
            //Если файл существует, то он будет перезаписан:
            if(!fhandle.createNewFile())
                Log.d("test", "Ошибка создания документа");
            FileOutputStream fOut = new FileOutputStream(fhandle);
            OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
            myOutWriter.write("TEST");
            myOutWriter.close();
            fOut.close();
        }
        catch (IOException e)
        {
            Toast.makeText(this, e.getMessage().toString(), Toast.LENGTH_LONG).show();
        }
    }

    private String getSDcardPath()
    {
        String exts =  Environment.getExternalStorageDirectory().getPath();
        String sdCardPath = null;
        try
        {
            FileReader fr = new FileReader(new File("/proc/mounts"));
            BufferedReader br = new BufferedReader(fr);
            String line;
            while((line = br.readLine())!=null)
            {
                if(line.contains("secure") || line.contains("asec"))
                    continue;
                if(line.contains("fat"))
                {
                    String[] pars = line.split("\\s");
                    if(pars.length<2)
                        continue;
                    if(pars[1].equals(exts))
                        continue;
                    sdCardPath =pars[1];
                    break;
                }
            }
            fr.close();
            br.close();
            return sdCardPath;
        }
        catch (Exception e)
        {
        }
        return sdCardPath;
    }
}
Answer 1

Посмотрел код.

 if (pars[1].equals(exts))
       continue;
                sdCardPath = pars[1];
                Log.d("SaveFileToSD", "pars " + pars[1]);
                Log.d("SaveFileToSD", "pars " + pars[0]);
                break;

В месте, что я привел выше sdCardPath = pars[1]; не вызывается потому что, не выполняется его условие и возвращается null. Так же насчет proc/mounts, папки mounts нет не на одном моем девайсе, плюс вы пытаетесь записать файлы в корневой каталог (получаем permission denied, для этого нужен root) Ошибка создания папки! null/myfolder111/test.txt при этом как я и сказал getSDcardPath ничего не возвращает. Не знаю насколько я помог, но код как и обещал посмотрел.

READ ALSO
Отображение данных из JSON в ListView(курс валют) - Android

Отображение данных из JSON в ListView(курс валют) - Android

Почему-то не отображаются актуальные данные из JSON файла которые тяну с сайта RBCСоздал класс в MainActivity:

389
Вопрос про валидность данных

Вопрос про валидность данных

Странный вопрос, но в голову больше ничего не лезетЧто ещё можно сделать если id меньше 0 или имя фамилия пустые?

378
Перебрать элементы Deque/Queue

Перебрать элементы Deque/Queue

Привет всем! Как можно перебрать все элементы Deque и Queue как в массиве?

275
AsynkTask. Как завершить преждевременно. Break?

AsynkTask. Как завершить преждевременно. Break?

ЭкспериментируюЗапустил Активити, а через него перехожу на второе активити, в нем запускаю AsyncTask

316