10

My application stores data locally in the native SQLite db, and I want to allow users to export this data by emailing themself a .csv file. In order to do this I'm generating the .csv from the database and writing it to the SD card, then attaching it to an email:

StringBuilder csv = generateFile();
writeFile(csv.toString(),"file.csv");
Intent email = new Intent(android.content.Intent.ACTION_SEND);
email.setType("application/octet-stream");
email.putExtra(android.content.Intent.EXTRA_STREAM, Uri.parse("file://sdcard/file.csv"));

Which all works great. What I'm wondering, though, is if it is possible to skip the step of writing to SD first, and directly attach the data.

Bee
  • 14,277
  • 6
  • 35
  • 49
  • 1
    I'm not going to post this as an answer, but can't you just write the CSV file to a stream in memory and then pass that stream in the email intent? – MattC Dec 02 '09 at 18:39
  • 2
    @MattC: no, because there is no "extra" type that is a stream. – CommonsWare Dec 02 '09 at 18:52

1 Answers1

3

Even if it is possible, I recommend against it.

Intents used to launch activities will be held onto for (potentially) a fairly long time -- as long as the activity in question is "alive" and could conceivably be returned to (e.g., back on the stack, because the user took a phone call while composing the email, then chatted via SMS for a half-hour).

Moreover, Intents get copied between processes a fair bit as part of this. For example, the email client will be in a different process than your app.

For both of these reasons, you need to keep your Intents small. The only alternative to a Uri to the content would be to have the content directly in the extra itself...and that CSV file presumably could get kinda big.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • I wanted to accomplish this because it seemed that it would be really frustrating and seem unrelated from the user's pov to fail in the case there was no SD mounted. But this is sound advice, and I can work with it. – Bee Dec 02 '09 at 20:07
  • 3
    You could try putting it in your app-local file storage area (getFilesDir()) and making it world-readable. I usually don't mess with the access control flags, but you need the email client to be able to read the file. The SD card works for that, but as you point out, conceivably there is no SD card. – CommonsWare Dec 03 '09 at 05:37
  • FYI: TransactionTooLargeException if too much data passed to Intent. – kaay Dec 13 '17 at 10:32