I'm trying to create an option in my android app for the user to be able to export his data, without requiring extra permissions for writting to external storage. The steps are:
- Create a text file from the database (csv)
- Send the file via Intent so the user can send it via email or store it in the desired cloud space.
I tried these examples - How to open private files saved to the internal storage using Intent.ACTION_VIEW? - Create and Share a File from Internal Storage
But i get a FileNotFoundException message on the logcat.
I hope you can help me find out what am I doing wrong. Thanks
Edit: It's working now! Followed Commonsware suggetions, I wans't using getFilesDir to create the files, and did a sync to make sure the file was already written when sending.
Here's the manifest:
<provider
android:name=".FileExportProvider"
android:authorities="com.mypackage.myappfileexport"
android:exported="true"
/>
Here's the provider:
public class FileExportProvider extends ContentProvider {
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
File privateFile = new File(getContext().getFilesDir(), uri.getPath());
return ParcelFileDescriptor.open(privateFile, ParcelFileDescriptor.MODE_READ_ONLY);
}
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
return 0;
}
@Override
public String getType(Uri arg0) {
return null;
}
@Override
public Uri insert(Uri arg0, ContentValues arg1) {
return null;
}
@Override
public boolean onCreate() {
return false;
}
@Override
public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
String arg4) {
return null;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
return 0;
}
}
Here's the code for the export dialog:
String filename = exp.ExportToFile(filter1, filter2, filter3, filter4);
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("text/plain");
Uri uri = Uri.parse("content://com.mypackage.myappfilexport/" + filename);
emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(emailIntent, "Send..."));
Here's how I create the file:
public String ExportToFile(Cursor cursor) {
File directory = _context.getFilesDir();
String filename = "file_export.csv";
FileOutputStream outputStream;
File file = new File(directory, filename);
try {
//outputStream = _context.openFileOutput(filename, Context.MODE_PRIVATE);
//Edit: suggested by Commonsware, in order to use getFilesDir()
outputStream = new FileOutputStream(file);
String header = "";
for(int i=0; i < cursor.getColumnCount(); i = i+1){
header = header+cursor.getColumnName(i);
if (i < cursor.getColumnCount()-1)
header = header+",";
}
header = header + "\r\n";
outputStream.write(header.getBytes());
//loop cursor
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String line = "";
for(int i=0; i < cursor.getColumnCount(); i = i+1){
String value = cursor.getString(i);
if (value==null)
value = "";
line = line + value;
if (i < cursor.getColumnCount()-1)
line = line+",";
}
line = line + "\r\n";
outputStream.write(line.getBytes());
cursor.moveToNext();
}
//Edit: suggested by Commonsware, getFD().sync() before sending the file
outputStream.getFD().sync();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
return filename;
}