Android: копирование .jpg изображения после удаления того же дает ошибку - PullRequest
0 голосов
/ 06 марта 2019

Со стороны Java приложения создайте каталог, используя file.mkdir и скопируйте JPG файлы, присутствующие в папке (jpg_3) с запоминающего устройства USB с использованием API Java.

Затем удалил те же файлы и каталог из внутренней памяти, используя File.delete () метод.

При попытке добавить те же файлы во внутреннюю память файлы не копировались, вместо этого получалось следующее исключение:

02-20 16: 11: 56.727 17471 17964 E XXXXXX: java.io.FileNotFoundException: /storage/emulated/0/XXX/jpg_3/galaxy-wallpaper-4.jpg: открыть не удалось: ENOENT (такого файла нет или каталог)

Позже мы обнаружили, что нижеупомянутые процессы все еще обращаются к этим удаленным файлам.

shell @ ABC: / storage / emulated / legacy / XXX # lsof | grep jpg_3

sdcard 1819 media_rw 5 ??? ??? ??? ??? /data/media/0/XXX/jpg_3/galaxy-wallpaper-4.jpg (удалено)

android.p 3205 u0_a4 67 ??? ??? ??? ??? /storage/emulated/0/XXX/jpg_3/galaxy-wallpaper-4.jpg (удалено)

shell @ ABC: / storage / emulated / legacy / XXX # ps 3205

USER PID PPID VSIZE RSS WCHAN PC NAME

u0_a4 3168 1830 1022984 58080 ffffffff 76e7f868 S android.process.media

Если мы попытаемся создать каталог с тем же именем, используя mkdir (в ADB Shell), мы получим ошибку ниже:

shell @ ABC: / storage / emulated / legacy / XXX # mkdir jpg_3 Ошибка mkdir для jpg_3, устройство или ресурс заняты

Мы подозреваем, что программные ссылки на эти файлы .jpg по-прежнему присутствуют даже после удаления, что вызывает вышеуказанные ошибки.

Мы попробовали File.delete (), а также приведенный ниже код Ссылка: android: удаление изображения

public static void deleteFileFromMediaStore(final ContentResolver contentResolver, final File file) {
String canonicalPath;
try {
    canonicalPath = file.getCanonicalPath();
} catch (IOException e) {
    canonicalPath = file.getAbsolutePath();
}
final Uri uri = MediaStore.Files.getContentUri("external");
final int result = contentResolver.delete(uri,
        MediaStore.Files.FileColumns.DATA + "=?", new String[]{canonicalPath});
if (result == 0) {
    final String absolutePath = file.getAbsolutePath();
    if (!absolutePath.equals(canonicalPath)) {
        contentResolver.delete(uri,
                MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath});
    }
}

}

Как решить проблему с программными ссылками для файлов .jpg?

N.B. Мы также пытались повторно сканировать устройство

MediaScannerConnection.scanFile(mService.getApplicationContext(), new String[]{
            oDeleteFile.getAbsolutePath().toString()
    }, null, null);

Но это не помогло.

Заранее спасибо

1 Ответ

0 голосов
/ 27 марта 2019

В версии Android Nougat существует файл ExifInterface.java (/ frameworks / base / media / java / android / media /), в котором есть функция 'getJpegAttributes', которая загружает атрибуты EXIF ​​из входного потока JPEG.Ниже приведена ссылка на файл - http://androidxref.com/7.0.0_r1/xref/frameworks/base/media/java/android/media/ExifInterface.java

В этой функции DataInputStream был создан с помощью следующего кода -

DataInputStream dataInputStream = new DataInputStream(inputStream);

Однако в конце функции тот же файлпоток не был закрыт.Таким образом, к файлу не нужно было обращаться из-за процесса Android Media Provider, хотя сканирование скопированного файла завершено с помощью MediaScannerService.java.Поэтому, когда мы закрываем поток файлов с помощью следующего кода в конце функции -

if (null != dataInputStream) {
    Log.d(TAG, "dataInputStream.close()" );
    dataInputStream.close();
}

, проблема исправляется.

...