Bhiefer
Bhiefer

Reputation: 1653

Android Marshmallow: Files written by SAF are not immediatelly written

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.

Upvotes: 4

Views: 917

Answers (1)

Bhiefer
Bhiefer

Reputation: 1653

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

Upvotes: 1

Related Questions