3

我的设备上安装了一个 API 级别为 21 的Google Drive Android 应用程序。我想让我的应用程序从我设备上的 Google Drive 私人文件夹中读取一些文件,进行一些更改并让 Google Drive Android 应用程序同步它。单击某个文件会启动文件下载过程,然后会出现应用程序选择器正如这里所指出的, Google Drive Android 应用程序不再将dataUri作为file://...发送到其他应用程序。它发送一个content://...代替。不过,我可以得到

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

有了pfd,我可以通过以下方式在缓冲区中的某个位置出一些字节:

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

当我尝试将缓冲区中的一些字节写入Google Drive 私有文件夹中文件的某个位置时,就会出现问题:

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);

这给了我IOException - lseek failed: ESPIPE (Illegal seek)。同样的例外是“rwt”模式。访问模式“rw”给出了其他例外:

java.io.FileNotFoundException: Unsupported mode: rw: 

清单中存在所有必要的权限:

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

从另一面来看,可以从我的应用程序中重写私有 Google Drive Android 应用程序中的整个文件 - 如果我没有在写入时进行任何定位 - 只需将 FileInputStream 复制到 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(); 

问题是:为什么 Google 让我们有机会重写私有 Google Drive 文件夹中的整个文件,而不给我们机会只更改该文件中的几个字节?

PS 为简洁起见,省略了所有必要的 try-catch 块

4

0 回答 0