Sandbox project on how to display PDF File (from url) and share pdf file with Android Sharesheet
This library will auto download remote pdf, and display on custom viewpager
I'm using PdfViewPager by voghDev
Add implementation 'es.voghdev.pdfviewpager:library:1.1.0'
on app/build.gradle
Add permission needed by the library
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
If pdf source is from url, we need to use RemotePDFViewPager
and we're gonna need to add it to our layout programmatically
In this example we use LinearLayout as the container
<LinearLayout
android:id="@+id/linear_layout_pdf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_bar"/>
On activity (or fragment), we need 4 main component
- A valid PDF url
- A PDFPagerAdapter
- A RemotePDFViewPager
- The listener for RemotePDFViewPager's DownloadFile
// MainActivity.kt that implement DownloadFile.Listener
private var url = "https://www.btpn.com/pdf/investor/annual-report/in/btpnar2017_ind_r.pdf"
private var adapter : PDFPagerAdapter? = null
private lateinit var remotePDFViewPager: RemotePDFViewPager
override fun onCreate(savedInstanceState: Bundle?) [
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
remotePDFViewPager = RemotePDFViewPager(this, url, this) // <- This will start the download
}
override fun onDestroy() {
super.onDestroy()
adapter?.close() // Don't forget to cleanup the adapter
}
override fun onSuccess(url: String?, destinationPath: String?) {
adapter = PDFPAgerAdapter(this, FileUtil.extractFileNameFromURL(url)) // Setup adapter with the file
remotePDFViewPager.adapter = adapter // Attach adapter to remote pdf viewpager
// Add it to the container
linear_layout_pdf.removeAllViews()
linear_layou_pdf.addView(
remotePDFViewPager,
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
}
override fun onFailure(e: Exception?) {
// Handle pdf download failure
}
override fun onProgressUpdate(progress: Int, total: Int) {
// Update pdf download progress
}
To be able to share pdf (or file), we need to use / setup FileProvider on the app
Create provider_paths.xml
on res/xml
<!-- Provider Path (provider_paths.xml) -->
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="external-files"
path="."/>
<!-- Need to add line below, because lib downloads the pdf into cache -->
<cache-path
name="cache-files"
path="."/>
</paths>
Add provider tag on AndroidManifest
<!-- AndroidManifest.xml -->
<manifest>
<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>
...
</application>
</manifest>
And here's the code to share the file using Android Sharesheet. By default, the PdfViewPager library downloads the file into app's cache directory.
val file = File(cacheDir, FileUtil.extractFileNameFromURL(url))
if (file.exists()) {
// Generate file Uri
val fileUri = FileProvider.getUriForFile(
this,
this.applicationContext.packageName + ".provider",
file
)
// Create Share Intent with the file uri
val shareIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, fileUri)
type = "application/pdf"
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
startActivity(Intent.createChooser(shareIntent, "Kirim PDF ke..."))
}
This library doesn't handle downloading remote pdf, it only shows pdf file We have to implement our own file download logic
I'm using PdfView-android by Dmitry-Borodin
TODO