Reputation: 3337
My Android app can save files on device disk by means of Storage Access Framework, cannot save on cloud locations instead.
I am using the following code to open the file picker to save a file:
Intent intentCreate = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intentCreate.addCategory(Intent.CATEGORY_OPENABLE);
intentCreate.setType("application/json");
intentCreate.putExtra(Intent.EXTRA_TITLE, fileNameGlobal + JSON_MY_FILE_EXT);
startActivityForResult(intentCreate, REQUEST_CODE);
(I checked on a Galaxy A10 with Android 11)
On my device I have GoogleDrive, NextCloud, Onedrive.
The picker shows the device disk, GoogleDrive, NextCloud, but does not show Onedrive.
I choose one and the actual uri of the newly created file is retrieved in onActivityResult() method, then used in
static public void writeNewTextDocumentInUri(final Activity activity, final Uri uri, final String mimetype, final String text) {
final ContentResolver resolver = activity.getContentResolver();
boolean result=true;
try {
ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "w");
FileOutputStream fos = new FileOutputStream(pfd.getFileDescriptor());
OutputStreamWriter writer = new OutputStreamWriter(fos);
writer.write(text);//the same using the append method
writer.flush();
writer.close();
result = true;
} catch (FileNotFoundException e) {
result = false;
} catch (IOException e) {
result = false;
}
if (!result) openDialog();
}
(mimetype is application/json)
This code works if I choose to save on the device storage, but fails with GoogleDrive and NextCloud.
I get an empty file saved (0 bytes).
I try to read it with the following code:
static public String readTextDocument(Activity activity, String fileUri) {
ContentResolver contentResolver;
contentResolver = activity.getContentResolver();
InputStream is;
try {
is = contentResolver.openInputStream(Uri.parse(fileUri));
} catch (FileNotFoundException e) {
return null;
}
if (is == null) return null;
InputStreamReader isr = new InputStreamReader(is);
String text = new String();
try {
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
text = text + line + "\n";
}
br.close();
} catch (IOException e) {
return null;
}
return text;
}
This only works from the device storage.
If instead I try to read the empty file created on GoogleDrive I get IOException, that is catched, while on NextCloud I get a more complex exception in logcat output:
android.os.NetworkOnMainThreadException
at android.os.Parcel.createExceptionOrNull(Parcel.java:2395)
at android.os.Parcel.createException(Parcel.java:2369)
at android.os.Parcel.readException(Parcel.java:2352)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:190)
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:153)
at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:781)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1993)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1808)
at android.content.ContentResolver.openInputStream(ContentResolver.java:1485)
Why the files are saved empty and cannot be read?
Upvotes: 1
Views: 54
Reputation: 3337
The working code is:
final ContentResolver resolver = activity.getContentResolver();
try {
OutputStream os = activity.getContentResolver().openOutputStream(uri);
os.write(text.getBytes());
os.flush();
os.close();
result = true;
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
Upvotes: 0