Android — Отказано в разрешении на создание нового файла

#android

#Android

Вопрос:

Я пытаюсь создать файл в Android, и даже после выполнения всех других ответов мне все еще отказывают в разрешении. В методе SaveImage() возникает ошибка.

  // STATICS
 private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };
  

  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState)
        verifyStoragePermissions(this);
    }
  

   //HERE IS THE METHOD THAT ASKS FOR PERMISSIONS
    public static void verifyStoragePermissions(Activity activity) {
        // Check if we have write permission
        int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

        if (permission != PackageManager.PERMISSION_GRANTED) {
            // We don't have permission so prompt the user
            ActivityCompat.requestPermissions(
                    activity,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }
    }
  

   @Override //ON REQUEST PERMISSION RESULT, 
//I ACCEPTED THE PERMISSION, THE CODE HERE WAS EXECUTED AS IT SHOULD
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {

            case 1: {
                Log.d(TAG,"THIS IS FOR THE WRITE/READ PERMISSIONS");
                Log.d(TAG,grantResults.toString());
                if (grantResults.length > 0
                        amp;amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG,"[Persmission accepted for writing/reading]");


                    // permission was granted, yay! Do the
                    // camera related task you need to do.
                } else {
                    Log.d(TAG,"[Permission denied]");
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }

            }

            // other 'case' lines to check for other
            // permissions this app might request.
        }
    }
  

  //THE METHOD WHERE THE ERROR HAPPENS
 public String saveImage(Bitmap myBitmap) {

        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);

        File wallpaperDirectory = new File(
                Environment.getExternalStorageDirectory()   "TEST_APP_PHOTO_FOLDER");

        // have the object build the directory structure, if needed.
        if (!wallpaperDirectory.exists()) {

            wallpaperDirectory.mkdirs();
        }

        try {

            File f = new File(wallpaperDirectory   "testfile.jpg");

            f.mkdirs();
          f.createNewFile(); // <--- STACK TRACE POINTS HERE

            FileOutputStream fo = new FileOutputStream(f);
..
..
..
  

Ошибка возникает в методе SaveImage(). У меня есть комментарии, объясняющие, где это происходит. Я пробовал метод с помощью f.mkdirs() и без него, не работает в любом случае. Оба раза отказано в разрешении.

ТРАССИРОВКА СТЕКА

 java.io.IOException: Permission denied
        at java.io.UnixFileSystem.createFileExclusively0(Native Method)
        at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:281)
        at java.io.File.createNewFile(File.java:1000)
        at car.andrej.tradingapp.ProfileActivity.ProfileActivity.saveImage(ProfileActivity.java:263)
        at car.andrej.tradingapp.ProfileActivity.ProfileActivity.onActivityResult(ProfileActivity.java:220)
        at android.app.Activity.dispatchActivityResult(Activity.java:7556)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4487)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4534)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1752)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
  

В манифесте :

  <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
  

Чего мне не хватает?…

Комментарии:

1. У вас отсутствует разделитель путей в ваших File файлах. Измените File создание экземпляра для wallpaperDirectory in saveImage() на new File(Environment.getExternalStorageDirectory(), "TEST_APP_PHOTO_FOLDER") ; обратите внимание на запятую вместо плюса. Вам также нужно будет сделать то же самое для File f . Как у вас есть сейчас, он пытается создать файлы в родительском каталоге внешнего хранилища, к которому у вас нет доступа.

Ответ №1:

Это не проблема с разрешениями Android. Скорее, Exception это связано с разрешениями Linux, хотя и непреднамеренно.

При создании экземпляра File файлов, используемых в saveImage() , вы объединяете имя нового файла / каталога с Environment.getExternalStorageDirectory() ; например, для wallpaperDirectory :

 new File(Environment.getExternalStorageDirectory()   "TEST_APP_PHOTO_FOLDER")
  

Это неявный вызов toString() on Environment.getExternalStorageDirectory() и прямое добавление к нему имени без необходимого разделителя путей между ними, так что в итоге вы получаете полное имя, которое выглядит примерно так /storage/emulated/0TEST_APP_PHOTO_FOLDER . Это относится к файлу в родительском каталоге внешнего хранилища, и у вас нет доступа на запись туда, поэтому Exception .

Просто измените свои File экземпляры, чтобы использовать конструктор, который принимает отдельные File и String аргументы; первый для родительского каталога, а второй для имени. В принципе, измените знак плюс на запятую. Например:

 new File(Environment.getExternalStorageDirectory(), "TEST_APP_PHOTO_FOLDER")