I just started helping with an established android project, and am at a loss as to how to wrangle the system into doing what I want. Please keep in mind I am very new to android still, so apologies if part of this question doesn't make sense, or I say things wrong.
The project uses a ContentResolver
to traverse the DCIM folder of a usb OTG stick or internal storage. What I am given is the Uri of each video file found. I need to open and get a raw file descriptor number of that file, then make a new file next to it for writing (with a name like originalvideo.mp4.trim.mp4, doesn't have to be pretty), and get a raw file descriptor number for that as well.
The project makes ffmpeg calls on these files, and to avoid permissions errors with the OTG stick (since Google updated OTG permissions to be incredibly restrictive), we can only use file descriptors obtained from Java. This is a royal pain in the neck, but after weeks of poking around it is the only way we have found to make this work, so we're sticking with it.
This is what currently happens inside the traversal loops:
final Uri documentUri = DocumentsContract.buildDocumentUriUsingTree(rootUri, docId);
ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(documentUri, "r");
if (fd != null) {
int ret = NativeLib.testFd( fd.getFd( ) );
}
The path names I get from the Uri look like this: /tree/primary:DCIM/document/primary:DCIM/V0480060.MP4
and I am at a loss as to how to make and open a new file next to that one like this: /tree/primary:DCIM/document/primary:DCIM/V0480060.MP4.trim.mp4
. I have tried converting the Uri to a file, I have tried editing the path before creating a file, but both throw IOExceptions, saying No such file or directory
. No duh, I'm trying to create it.
This is the closest I have come to getting it to work:
File f = new File( documentUri.getPath() + ".trim.mp4" );
if( !f.exists() )
f.createNewFile();
ParcelFileDescriptor fn = ParcelFileDescriptor.open( f, ParcelFileDescriptor.MODE_WRITE_ONLY );
But even that throws an IOExcept.
Thank you for any help you can offer.
The path names I get from the Uri look like this: /tree/primary:DCIM/document/primary:DCIM/V0480060.MP4
A Uri
is not a file. If the scheme of the Uri
happens to be file
, then the path of the Uri
will be a filesystem path. Otherwise, it is an opaque string.
I am at a loss as to how to make and open a new file next to that one like this
rootUri
is a Uri
pointing to a document tree. So, given that:
Step #1: Wrap that in a DocumentFile
, via fromTreeUri()
Step #2: Create another document in the same tree, using createFile()
Step #3: Use the Uri
that you get from createFile()
in the same fashion as you are using documentUri
Now, bear in mind that you do not have strict control over the filename. Probably the DocumentsProvider
handling USB OTG will use the "display name" that you pass into createFile()
as the filename. That is not a requirement. The point behind the Storage Access Framework (DocumentsContract
, etc.) is to get away from thinking in terms of files and filenames.