9

I create file on the internal storage as suggested by android docs. To be accurate the file is created under a specific directory in the internal storage. I do this using the mode world_readable mode. Then later on i try to attach the file using email program. I was able to get the file attached, however sending the email failed (does not seem to be to load the file) i am sure it is internal storage/permission thingy.

Anyone knows how to fix it or a working example? It will suck to have convert everything on external storage.

Thank you

Ps:I checked other threads and they don't seem to have solutions (old threads)

Snake
  • 14,228
  • 27
  • 117
  • 250

2 Answers2

14

It is possible to share a file from your apps local storage to another application (such as email attachment) by granting temporary permissions to read that file as part of the share intent.

Step 1: Add a file provider to your AndroidManifest.xml:

<applicaton>
     ....
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.your.package.name.fileprovider"
        android:grantUriPermissions="true"
        android:exported="false">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/filepaths" />
    </provider>
</application>

Step 2: Add a file res/xml/filepaths.xml with the path to the file in local app storage that you want to share:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="myFolder" path="Folder/"/>
</paths>

Step 3: In your java code create the file sharing intent:

    Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
    shareIntent.setType("text/plain");
    shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Your subject");
    shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Your message");

    ArrayList<Uri> uris = new ArrayList<Uri>();
    String shareName = new String(pathToFile + filename);
    File shareFile = new File(shareName);
    Uri contentUri = FileProvider.getUriForFile(context, "com.your.package.name.fileprovider", shareFile);
    uris.add(contentUri);
    shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);

    // Grant temporary read permission to the content URI
    shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    String msgStr = "Share...";
    startActivity(Intent.createChooser(shareIntent, msgStr));

If you have any problems with it see the docs here https://developer.android.com/training/secure-file-sharing/share-file.html for further details.

Deemoe
  • 931
  • 10
  • 12
  • how do you include files from project in "files" directory? in your example, what's "filePath"? – jackal Mar 20 '20 at 14:57
  • 1
    @jackal You have to mention the name of the file(to be shared)'s parent directory in path. ie. in place of `Folder/` – h8pathak Apr 08 '20 at 20:32
  • After this answer, I had to use the permissions code from the following answer: https://stackoverflow.com/a/18332000/3886821 – h8pathak Apr 09 '20 at 17:24
4

I'm assuming you are trying to send the file as an email attachment using intents.

The reason why the file is empty is that the email app does not have access to the file in /data/data/package_name/myfile_name, due to Androids security model (the /data/data/package_name directory is private to your app).

In order to add the file as an attachment, you need to write it to public storage (such as the SD card) so the email app can access it.

KOTIOS
  • 11,177
  • 3
  • 39
  • 66
  • So no way I can do it from internal storage even if I have set the mode to world readable – Snake Jul 20 '13 at 06:37
  • @Snake You can use internal storage too, by using Provider. Read the given answer here http://stackoverflow.com/questions/13482310/how-to-share-internal-storage-file-with-gmail-client – Pankaj Kumar Nov 25 '13 at 09:05