60

I have a list of files in my android app and I want to be able to get the selected items and send them via email or any other sharing app. Here is my code.

Intent sendIntent = new Intent();
                    sendIntent.setAction(Intent.ACTION_SEND);
                    sendIntent.putExtra(Intent.EXTRA_EMAIL, getListView().getCheckedItemIds());
                    sendIntent.setType("text/plain");
                    startActivity(sendIntent);
user2351234
  • 965
  • 2
  • 12
  • 20

10 Answers10

65

this is the code for sharing file in android

Intent intentShareFile = new Intent(Intent.ACTION_SEND);
File fileWithinMyDir = new File(myFilePath);

if(fileWithinMyDir.exists()) {
    intentShareFile.setType("application/pdf");
    intentShareFile.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+myFilePath));

    intentShareFile.putExtra(Intent.EXTRA_SUBJECT,
                        "Sharing File...");
    intentShareFile.putExtra(Intent.EXTRA_TEXT, "Sharing File...");

    startActivity(Intent.createChooser(intentShareFile, "Share File"));
}

Below is another method to share PDF file if you have put file provider in manifest

Uri pdfUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        pdfUri = FileProvider.getUriForFile(PDFViewerActivity.this, fileprovider, pdfFile);
} else {
        pdfUri = Uri.fromFile(pdfFile);
}
Intent share = new Intent();
share.setAction(Intent.ACTION_SEND);
share.setType("application/pdf");
share.putExtra(Intent.EXTRA_STREAM, pdfUri);
startActivity(Intent.createChooser(share, "Share file"));
Tushar Mate
  • 753
  • 6
  • 11
  • myFilePath is the path of PDF file in above example. u may find many solutions to select file from SD card in Android. above program just takes file path as input and shows apps on device to share file to. e.g. if u select gmail app, it attaches file and set body and subject text – Tushar Mate Feb 25 '15 at 14:02
  • 4
    In addition to that, I needed to set up a `FileProvider`, this may help: https://guides.codepath.com/android/Sharing-Content-with-Intents – Antônio Medeiros Mar 27 '18 at 04:32
  • 2
    I am still unable to share file. It shows me that error in toast in gmail when I try to attach it there. Kindly help. Thank you – Khushboo Gandhi Nov 20 '19 at 07:12
27
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(exportPath));

also you can make zip file of all file and attach zip file for send multiple file in android

Bishan
  • 15,211
  • 52
  • 164
  • 258
Digvesh Patel
  • 6,503
  • 1
  • 20
  • 34
  • Thank a man!You solved my problem.I used Uri.fromFile(exportPath)) instead of using Uri.parse("file://"+myFilePath) and now can share image. – Saeid Z Jun 24 '19 at 18:26
16

For those who trying in Kotlin here is the way:

Start the intent like below:

 fun startFileShareIntent(filePath: String) { // pass the file path where the actual file is located.
        val shareIntent = Intent(Intent.ACTION_SEND).apply {
            type = FILE_TYPE  // "*/*" will accepts all types of files, if you want specific then change it on your need.
            flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
            putExtra(
                Intent.EXTRA_SUBJECT,
                "Sharing file from the AppName"
            )
            putExtra(
                Intent.EXTRA_TEXT,
                "Sharing file from the AppName with some description"
            )
            val fileURI = FileProvider.getUriForFile(
                context!!, context!!.packageName + ".provider",
                File(filePath)
            )
            putExtra(Intent.EXTRA_STREAM, fileURI)
        }
        startActivity(shareIntent)
    }

In Manifest inside the application tag:

    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>

Under res-->xml--> provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="files" path="." />
    <external-path name="external_files" path="."/>
</paths>
Shailendra Madda
  • 20,649
  • 15
  • 100
  • 138
14

This is work for every single file!

private void shareFile(File file) {

    Intent intentShareFile = new Intent(Intent.ACTION_SEND);

    intentShareFile.setType(URLConnection.guessContentTypeFromName(file.getName()));
    intentShareFile.putExtra(Intent.EXTRA_STREAM,
        Uri.parse("file://"+file.getAbsolutePath()));

    //if you need
    //intentShareFile.putExtra(Intent.EXTRA_SUBJECT,"Sharing File Subject);
    //intentShareFile.putExtra(Intent.EXTRA_TEXT, "Sharing File Description");

    startActivity(Intent.createChooser(intentShareFile, "Share File"));

}

Thanks Tushar-Mate!

Javad
  • 361
  • 5
  • 9
4

First you should define File Provider, see https://medium.com/@ali.dev/open-a-file-in-another-app-with-android-fileprovider-for-android-7-42c9abb198c1.

The code checks that a device contains applications which can receive the file, see How to check if an intent can be handled from some activity?.

fun sharePdf(file: File, context: Context) {
    val uri = getUriFromFile(file, context)

    if (uri != null) {
        val intent = Intent().apply {
            action = Intent.ACTION_SEND
            type = "application/pdf" // For PDF files.
            putExtra(Intent.EXTRA_STREAM, uri)
            putExtra(Intent.EXTRA_SUBJECT, file.name)
            putExtra(Intent.EXTRA_TEXT, file.name)
            // Grant temporary read permission to the content URI.
            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        }
        // Validate that the device can open your File.
        val activityInfo = intent.resolveActivityInfo(context.packageManager, intent.flags)
        if (activityInfo?.exported == true) {
            context.startActivity(Intent.createChooser(intent,
                "Share PDF file")
        }
    }
}

fun getUriFromFile(file: File, context: Context): Uri? =
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        Uri.fromFile(file)
    } else {
        try {
            FileProvider.getUriForFile(context, context.packageName + ".provider", file)
        } catch (e: Exception) {
            throw if (e.message?.contains("ProviderInfo.loadXmlMetaData") == true) {
                Error("FileProvider is not set or doesn't have needed permissions")
            } else {
                e
            }
        }
    }
CoolMind
  • 26,736
  • 15
  • 188
  • 224
3

Use ACTION_SEND_MULTIPLE for delivering multiple data to someone

intent.setAction(Intent.ACTION_SEND_MULTIPLE);
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, arrayUri);
intent.setType("text/plain");
startActivity(intent);

The arrayUri is the Array List of Uri of files to Send.

Arun C
  • 9,035
  • 2
  • 28
  • 42
3

Here is an example to share or save a text file:

private void shareFile(String filePath) {

    File f = new File(filePath);

    Intent intentShareFile = new Intent(Intent.ACTION_SEND);
    File fileWithinMyDir = new File(filePath);

    if (fileWithinMyDir.exists()) {
        intentShareFile.setType("text/*");
        intentShareFile.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + filePath));
        intentShareFile.putExtra(Intent.EXTRA_SUBJECT, "MyApp File Share: " + f.getName());
        intentShareFile.putExtra(Intent.EXTRA_TEXT, "MyApp File Share: " + f.getName());

        this.startActivity(Intent.createChooser(intentShareFile, f.getName()));
    }
}
live-love
  • 48,840
  • 22
  • 240
  • 204
3
File directory = new File(Environment.getExternalStorageDirectory() + File.separator + BuildConfig.APPLICATION_ID + File.separator + DIRECTORY_VIDEO);
            String fileName = mediaModel.getContentPath().substring(mediaModel.getContentPath().lastIndexOf('/') + 1, mediaModel.getContentPath().length());
            File fileWithinMyDir = new File(directory, fileName);
            if (fileWithinMyDir.exists()) {
                Uri fileUri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", fileWithinMyDir);
                Intent intent = ShareCompat.IntentBuilder.from(this)
                        .setStream(fileUri) // uri from FileProvider
                        .setType("text/html")
                        .getIntent()
                        .setAction(Intent.ACTION_SEND) //Change if needed
                        .setDataAndType(fileUri, "video/*")
                        .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                startActivity(intent);
Alok Singh
  • 640
  • 4
  • 14
1
val uriArrayList: ArrayList<Uri> = ArrayList()
GlobalScope.launch(Dispatchers.IO) {
    runCatching {
        itemsList!!.forEach {
            uriArrayList.add(
                FileProvider.getUriForFile(
                    mContext,
                    APPLICATION_ID + ".provider",
                    File(it.path)
                )
            )
        }

    }.onSuccess {
        requireActivity().runOnUiThread {
            if (uriArrayList.size > 0) {
                val intent = Intent()
                intent.action = Intent.ACTION_SEND_MULTIPLE
                intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriArrayList)
                intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
                intent.type = "image/*|application/pdf/*"
                startActivity(Intent.createChooser(intent, resources.getString(R.string.share)))
            }
        }
    }
        .onFailure {
            Log.e("SHARING_FAILED", it)
        }
}

First of all you have to write provider code in app manifest file for sharing on android 7.0 and above

<provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>

here provider_paths are:

    <?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="/storage/emulated/0" path="."/>
    <root-path name="root" path="." />
    <files-path name="files" path="."/>
</paths>
Abdur Rehman
  • 1,247
  • 10
  • 13
-5

Read this article about Sending Content to Other Apps

Intent sendIntent = new Intent();

sendIntent.setAction(Intent.ACTION_SEND);

sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");

sendIntent.setType("text/plain");

startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
Bishan
  • 15,211
  • 52
  • 164
  • 258