3

I have a Google Drive Android app installed on my device with API level 21. I would like to allow for my app to read some files from Google Drive private folder on my device, make some changes and let Google Drive Android app to synchronize it. Clicking on some file starts a file download process and app chooser appears right after it. As was pointed here Google Drive Android app no longer sends dataUri as a file://... to other apps. It sends a content://... instead. Nevertheless, I can get

ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(dataUri, "r");

Having pfd I can read out some bytes at some position in the buffer by means of:

FileInputStream fis = new FileInputStream(pfd.getFileDescriptor());
FileChannel fileChannel = fis.getChannel();
fileChannel.position(position);
int bytesRead = fileChannel.read(buffer);

The problem arises when I try to write some bytes from the buffer to some position of the file in Google Drive private folder:

ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(dataUri, "w"/*"rw", "rwt"*/); //Exception here for "rw"
FileOutputStream fos = new FileOutputStream(pfd.getFileDescriptor()); 
FileChannel fileChannel = fos.getChannel();
fileChannel.position(position);   //Exception here for "w" and "rwt"
int bytesWrite = fileChannel.write(buffer);

that gives me IOException - lseek failed: ESPIPE (Illegal seek). The same exception is for "rwt" mode. Access mode "rw" gives other exception:

java.io.FileNotFoundException: Unsupported mode: rw: 

All necessary permissions are present in the manifest:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

From other side it is possible to rewrite a whole file in private Google Drive Android app from my app - if I do not make any positioning on write - just copy FileInputStream to FileOutputStream:

FileInputStream fis = new FileInputStream("/storage/sdcard0/aaa/www/flower.jpg");
ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(dataUri, "rwt");
FileOutputStream fos = new FileOutputStream(pfd.getFileDescriptor());
new StreamCopyThread(fis, fos).start(); 

The question is: Why Google gives us an opportunity to rewrite a whole file in private Google Drive folder and does not give us an opportunity to change just a couple bytes in this file?

P.S. All necessary try-catch blocks were omitted for brevity

Community
  • 1
  • 1
isabsent
  • 3,683
  • 3
  • 25
  • 46
  • Have you tried calling getContentResolver().openFileDescriptor with "w" mode? – Anatoli Mar 20 '16 at 22:58
  • Yes, I have. It was unclear from my question and I have changed it little bit now. – isabsent Mar 21 '16 at 03:39
  • My guess is Drive wouldn't let you change the content in place because it needs this content (e.g. to serve other clients). – Anatoli Mar 29 '16 at 21:21
  • @Anatoli: Are you from Google? – isabsent Mar 30 '16 at 09:26
  • My guess is that Google Drive stores the entire file in a binary large object in a database and transacting written bits of a file in a REST API would be a nightmare if multiple clients are trying to make changes. – Robin Davies Oct 25 '17 at 09:24
  • I don't think so. I have seen downloaded files in the private Google Drive app folder on the device memory a year or two ago. – isabsent Oct 25 '17 at 11:46

0 Answers0