我有一个应用程序,它使用
ACTION_CREATE_DOCUMENT
意图获取要写入的Uri一段时间以来,这一切都很好,但最近当我去保存一个文件并选择Google驱动器时,我注意到生成的文件是空的(0字节)但是,如果我选择下载文件夹作为目标(本地存储),则会正确地创建和写入文件。
我将问题简化为一个简单的测试活动(如下),并验证代码的所有部分实际上都在执行(没有捕获到异常,
ParcelFileDescriptor
不为空等)。
我在Android 7和Android 8模拟器以及android8物理设备上进行了测试,结果都显示了相同的行为,但是一个旧的Android 5手机工作正常??).
应用程序的完整版本具有并正确请求读取和写入外部存储权限以处理某些
third party file managers
,但Google Drive不需要这样做,所以我在本例中省略了它(行为与授予的权限相同)。
我得到的uri看起来像一个有效的内容uri(
content://com.google.android.apps.docs.storage/document/acc%3...
)
还有人看到这个问题吗我在这里做错什么了吗我怎样才能让谷歌硬盘再次发挥作用?
public class MainActivity extends AppCompatActivity {
private static final int FILE_EXPORT_REQUEST_CODE = 12;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK)
return;
switch(requestCode) {
case FILE_EXPORT_REQUEST_CODE:
if( data != null ) {
Uri uri = data.getData();
if( uri != null ) {
new ExportCSV(this).execute(uri);
}
}
break;
}
}
// test Activity has a single button that calls this
public void saveFile(View v) {
Intent exportIntent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
exportIntent.addCategory(Intent.CATEGORY_OPENABLE);
exportIntent.setType("text/csv");
String filename = "test.csv";
exportIntent.putExtra(Intent.EXTRA_TITLE, filename);
startActivityForResult(exportIntent, FILE_EXPORT_REQUEST_CODE);
}
private static class ExportCSV extends AsyncTask<Uri, Void, Boolean> {
private final WeakReference<Context> context;
ExportCSV(Context c) {
context = new WeakReference<>(c);
}
@Override
protected Boolean doInBackground(Uri... uris) {
Uri uri = uris[0];
Context c = context.get();
if( c == null ) {
return false;
}
String data = "colA,colB\n1,2\n";
boolean success = false;
try {
ParcelFileDescriptor pfd = c.getContentResolver().openFileDescriptor(uri, "w");
if( pfd != null ) {
FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
fileOutputStream.write(data.getBytes());
fileOutputStream.close();
success = true;
}
}
catch(Exception e) {
e.printStackTrace();
}
return success;
}
}
}