I'm trying to check if a file exists prior to creating it, using DocumentFile (due to the Storage Access Framework). But DocumentFile().fromTreeUri()
removes the non-existant portion of the would-be Uri, which then causes DocumentFile().exists()
to always return true, regardless of whether it exists or not.
I've created a simple example to demonstrate my point. First we ask the user to select a directory:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Ask the user for the source folder
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 100);
}
On response, we add /fictionalFile
to the path (thus making it a non-existent file), and then check if it exists:
public void onActivityResult(int requestCode, int resultCode, Intent resultData)
{
if (resultCode == RESULT_OK)
{
if(requestCode == 100)
{
Uri fictionalURI = Uri.parse(resultData.getData()+"/fictionalFile");
DocumentFile fictionalFile = DocumentFile.fromTreeUri(this, fictionalURI);
Log.i("STORAGE", "FICTIONAL URI: "+fictionalURI);
Log.i("STORAGE", "FICTIONAL DOCUMENTFILE URI: "+fictionalFile.getUri());
if(fictionalFile.exists())
{
Log.i("STORAGE", "Fictional file exists");
}
}
}
}
However, when DocumentFile.fromTreeUri() is run on the fictional Uri, the fake "/fictionalfile" portion is lost, which then causes the DocumentFile.exists() function to return true, as shown by the below LogCat:
I/STORAGE: FICTIONAL URI: content://com.android.externalstorage.documents/tree/17FA-1C18%3AFileSync%2Ftarget/fictionalFile
I/STORAGE: FICTIONAL DOCUMENTFILE URI: content://com.android.externalstorage.documents/tree/17FA-1C18%3AFileSync%2Ftarget/document/17FA-1C18%3AFileSync%2Ftarget
I/STORAGE: Fictional file exists
(In the above example, I'm using the SD card, thus the long path names)
Is there another way to check if a not-yet created DocumentFile exists? The use case is that when copying a file from Directory A to Directory B, I want to check if said file already exists in Directory B prior to starting the transfer.
UPDATE: I've now realised that using DocumentFile.fromTreeUri()
is wrong, and that I should be using DocumentFile.fromSingleUri()
. This helps, but upon running .exists()
on the new file I am getting W/DocumentFile: Failed query: java.lang.UnsupportedOperationException: Unsupported Uri content://com.android.externalstorage.documents/tree/17FA-1C18%3AFileSync%2Ftarget/fictionalFile
. Any thoughts?
public void onActivityResult(int requestCode, int resultCode, Intent resultData)
{
if (resultCode == RESULT_OK)
{
if(requestCode == 100)
{
Uri fictionalURI = Uri.parse(resultData.getData()+"/fictionalFile");
DocumentFile fictionalFile = DocumentFile.fromSingleUri(this, fictionalURI);
Log.i("STORAGE", "FICTIONAL URI: "+fictionalURI);
Log.i("STORAGE", "FICTIONAL DOCUMENTFILE URI: "+fictionalFile.getUri());
if(fictionalFile != null && fictionalFile.exists())
{
Log.i("STORAGE", "Fictional file exists");
}
}
}
}
File
class and is methodexists()
. docs.oracle.com/javase/7/docs/api/java/io/File.html#exists() – VerditerACTION_OPEN_DOCUMENT_TREE
byACTION_OPEN_DOCUMENT
– Verditer