Нет такого файла или каталога в Android 10 (api 29) - PullRequest
2 голосов
/ 06 мая 2020

Я работаю над приложением для редактирования фотографий, в котором после редактирования изображения я сохраняю его в моем локальном хранилище. Он работает нормально до android 9, но не на android 10. Он показывает исключение «Такой файл или каталог не найден» в Android 10. После некоторых исследований я обнаружил, что getExternalFilesDir () устарел в android Q +. Но я не могу найти какой-либо правильный способ сделать это в android 10. Так что, пожалуйста, если кто-нибудь может предоставить руководство, это было бы действительно полезно.

Я добавил и предоставил разрешение на использование android: name = "android .permission.WRITE_EXTERNAL_STORAGE" /> в случае, если это была проблема, и она ничего не решила.

Это моя попытка (Используемый ParcelFileDescriptor):

private void fileAccessForAndroidQ(Uri fileUri){
    try {
        ParcelFileDescriptor parcelFileDescriptor = this.getContentResolver().openFileDescriptor(fileUri, "r", null);
        InputStream inputStream = new FileInputStream(parcelFileDescriptor.getFileDescriptor());
        Cursor returnCursor =
                getContentResolver().query(fileUri, null, null, null, null);
        int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
        returnCursor.moveToFirst();
        fileName = returnCursor.getString(nameIndex);

        file = new File(this.getFilesDir(), fileName);

        OutputStream outputStream = new FileOutputStream(file);
        IOUtils.copyStream(inputStream, outputStream);

    }catch (Exception e){
        Toast.makeText(this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
    }
}

Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

6 голосов
/ 06 мая 2020

Если вы настроили таргетинг Android 10 (уровень API 29) или выше, установите значение requestLegacyExternalStorage на true в файле манифеста вашего приложения:

Документация

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.appname"
    android:installLocation="auto">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:requestLegacyExternalStorage="true"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme.NoActionBar">

        <activity android:name=".activities.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


    </application>

</manifest>
1 голос
/ 06 мая 2020

Вот лучшее, что я смог найти: https://developer.android.com/training/data-storage/app-specific#external

По сути, теперь вы используете для своих файлов каталоги c, указанные в приложении. Например:

@Nullable
File getAppSpecificAlbumStorageDir(Context context, String albumName) {
    // Get the pictures directory that's inside the app-specific directory on
    // external storage.
    File file = new File(context.getExternalFilesDir(
            Environment.DIRECTORY_PICTURES), albumName);
    if (file == null || !file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}
0 голосов
/ 18 июля 2020

Я обнаружил, что это работает для меня. Я пытаюсь перечислить все файлы в ListView

if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);

    } else {


        File s = Environment.getExternalStorageDirectory();
        Log.d("Path ",Arrays.toString(s.listFiles()));
        File[] s1 = new File[s.listFiles().length];

        for(int i=0;i<s.listFiles().length;i++){
            s1[i]= new File(s.listFiles()[i].toString().replace("/storage/emulated/0/", ""));
        }



        ArrayAdapter<File> adapter = new ArrayAdapter<File>(this,R.layout.support_simple_spinner_dropdown_item,s1);
        l1.setAdapter(adapter);

     }
...