0

From application Java side, created a directory using file.mkdir and copy JPG files present inside a folder(jpg_3) from USB mass storage device using java API.

Then deleted the same files as well as the directory from internal memory using File.delete() method.

When tried to add those same files to the internal memory,the files didn't get copied, instead got the below exception:

02-20 16:11:56.727 17471 17964 E XXXXXX: java.io.FileNotFoundException: /storage/emulated/0/XXX/jpg_3/galaxy-wallpaper-4.jpg: open failed: ENOENT (No such file or directory)

Later we found that below mentioned processes are still accessing those deleted files.

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 (deleted)

android.p 3205 u0_a4 67 ??? ??? ??? ??? /storage/emulated/0/XXX/jpg_3/galaxy-wallpaper-4.jpg (deleted)

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

If we try to create directory with the same name using mkdir(in ADB Shell) we get got below error:

shell@ABC:/storage/emulated/legacy/XXX # mkdir jpg_3 mkdir failed for jpg_3, Device or resource busy

We suspect that the soft links for those .jpg files are still present even after deletion, which causes above errors.

We tried File.delete() as well as the below mentioned code Reference: android : deleting an image

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});
    }
}

}

How to resolve the softlink issue for .jpg files ?

N.B: We also tried to re-scan the device

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

But it didn't helped.

Thanks in Advance

Community
  • 1
  • 1
Debabrata
  • 1
  • 1
  • 2
  • see the [grant-uri-permission-element](https://developer.android.com/guide/topics/manifest/grant-uri-permission-element)...this can also be requested at run-time. – Martin Zeitler Mar 06 '19 at 13:59

1 Answers1

0

In Android Nougat Version, there is a file ExifInterface.java(/frameworks/base/media/java/android/media/) which has a function 'getJpegAttributes' which Loads EXIF attributes from a JPEG input stream. Below is the link of the file - http://androidxref.com/7.0.0_r1/xref/frameworks/base/media/java/android/media/ExifInterface.java

In this function, DataInputStream has been created by the following code -

DataInputStream dataInputStream = new DataInputStream(inputStream);

However at the end of the function, the same file stream has not been closed. So the file was unnecessary being accessed by Android Media Provider process even though scan of the copied file is complete by the MediaScannerService.java. So when we close the file stream by the following code at the end of the function-

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

the issue gets fixed.

Debabrata
  • 1
  • 1
  • 2