How can I share pdf file in android?
Asked Answered
G

2

5

I try to share a pdf file from android/data/mypackage/files/file.pdf I generate these pdfs also in this app, and when I try to share it, the pdf doesn't appear in on attached files from email, or google drive says something like: "No data to share". Here is my code for sharing pdf:

            val aName = intent.getStringExtra("iName")
            val file = File(this.getExternalFilesDir(null)?.absolutePath.toString(), "$aName")
            val shareIntent = Intent(Intent.ACTION_SEND)
            shareIntent.putExtra(Intent.EXTRA_STREAM,  file)
            shareIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
            shareIntent.type = "application/pdf"
            startActivity(Intent.createChooser(shareIntent, "share.."))
            Toast.makeText(this,"$file",Toast.LENGTH_SHORT).show()

The pdf path looks correct when I toast it: SS

Garlandgarlanda answered 13/11, 2020 at 11:21 Comment(4)
have you try this #17986146Ieyasu
You should be crashing with a FileUriExposedException, at least on Android 7.0 and higher. Use FileProvider, please.Bloodthirsty
if for android 7.0 and below how would it be ? @BloodthirstyVertebrate
@gumuruh: FileProvider should work back to Android 15 or so. But, you can use Uri.forFile() for files visible on external storage, and that may work as well.Bloodthirsty
G
8

The problem is that you are not using a URI, just sending a path, you need several things.

Provider paths

You have to create provider_paths.xml under xml folder in res :

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path
        name="files_root"
        path="/" />
</paths>

Set the provider in the Manifest under Aplication:

<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>

Get the URI

fun uriFromFile(context:Context, file:File):Uri {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
  {
    return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file)
  }
  else
  {
    return Uri.fromFile(file)
  }
}

Your final code:

val aName = intent.getStringExtra("iName")
            val shareIntent = Intent(Intent.ACTION_SEND)
            shareIntent.putExtra(Intent.EXTRA_STREAM,  uriFromFile(context,File(this.getExternalFilesDir(null)?.absolutePath.toString(), "$aName")))
            shareIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
            shareIntent.type = "application/pdf"
            startActivity(Intent.createChooser(shareIntent, "share.."))

I didn't test the code, write it from "memory", let me know if it works for you.

Garish answered 13/11, 2020 at 12:2 Comment(5)
I tried and app stops working with error: java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/md.merit.strangatorul/files/2020-11-13_12:47:45.pdf on line: FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file)Garlandgarlanda
Edited the Provider path file, check it now.Garish
I am been trying since Jan, read different answers but every time what I get is this error Activity com.android.internal.app.ChooserActivity has leaked IntentReceiver com.android.internal.app.ChooserActivity$1@4afad61 that was originally registered here. Are you missing a call to unregisterReceiver()?Write
is that acceptable answer?Vertebrate
@Vertebrate it is the working answerGarish
N
0

In Kotlin : res/xml folder add file provider_path.xml write code:

   <?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="."/>
</paths>

Then in manifest file add code: <application ..>

<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>

Than Activity File Add below Function:

private fun sharePDF(file:File ) {
      //  val file = File(pdfFilePath)
        val uri = Uri.fromFile(file)
        val URI = FileProvider.getUriForFile(
            this@MainActivity,
            BuildConfig.APPLICATION_ID + ".provider",
            file
        )
        val intent = Intent(Intent.ACTION_SEND)
        intent.type = "application/pdf"
        intent.putExtra(Intent.EXTRA_STREAM, URI)
        intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
        startActivity(Intent.createChooser(intent, "Share PDF"))
    }
Norris answered 15/6, 2023 at 9:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.