I am using SAF (Storage access framework) to write files to SD card. On Marshmallow, the files are actually written and updated with a big delay (approximately 10 seconds).
When I use e.g.:
android.support.v4.provider.DocumentFile docFile = DocumentFile.fromTreeUri(context, getUri()) // tree uri that represents some existing file on sd card
File file = getFile(getUri()); // java.io.File that points to same file as docFile
docFile.length(); // length of current file is e.g. 150B
file.length(); // length of file is also 150B
try (OutputStream outStream = context.getContentResolver().getOutputStream(docFile.getUri()))
{
outStream.write(data, 0, 50); // overwrite with 50 B
outStream.flush(); // didn't help
}
docFile.length(); // it still returns 150B !!
file.length(); // it still returns 150B
Thread.sleep(12000); // sleep 12 seconds
docFile.length(); // now it returns correctly 50B
file.length(); // now it returns correctly 50B
Btw. when I check the length by File.length()
method, it returns the same values.
Is there a way how to write it immediately? Or can I set some listener? Otherwise I have to check the size regularly and I don't want to do it this way. And actually, I don't want to wait 10 seconds after file is written.
So I have found that the delays occurs when I use both java.io.File
and SAF api. Checking the file by methods File.isDirectory()
, File.exists()
, File.length()
causes that subsequent call of
context.getContentResolver().getOutputStream(someUri))
is delayed for 10 seconds. It delayes deletion too. I.e. when you try:
DocumentFile docFile = DocumentFile.fromTreeUri(context, someUri);
File file = new File("path to same file as someUri");
if(file.exists() && !file.isDirectory()) // this cause the delay
{
docFile.delete();
}
boolean exists = file.exists(); // exists is INCORRECTLY true
exists = docFile.exists(); // exists is INCORRECTLY true
Thread.sleep(12000);
exists = file.exists(); // exists is CORRECTLY false
exists = docFile.exists(); // exists is CORRECTLY false
I used File class for read only operations because it was faster. But I cannot use it together with SAF since Marshmallow. It has to use strictly SAF api:
DocumentFile docFile = DocumentFile.fromTreeUri(context, someUri);
if(docFile.exists() && !docFile.isDirectory()) // this cause the delay
{
docFile.delete();
}
boolean exists = docFile.exists(); // exists is CORRECTLY false