Reputation: 1275
I want to open local (SD card) PDF file in a WebView.
I already tried this:
webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setPluginsEnabled(true);
webview.getSettings().setAllowFileAccess(true);
File file = new File(Environment.getExternalStorageDirectory() + "/test.pdf");
final Uri uri = Uri.fromFile(file);
webview.loadUrl(uri.toString());
But it's still not opening it, so let me know how I can open a PDF in WebView?
Upvotes: 23
Views: 65467
Reputation: 11
WebView don't provide direct functionality to open PDF from local storage. You can open pdf in external PDFViewer applications.
Wait it will take user to different application.
Now without using any extra library to open a PDF we can use PdfRenderer class to render a PDF.
PdfRenderer can render pdf on bitmap. Bitmap can be drawn to Image View to show the PDF in your application.
// create a new renderer
PdfRenderer renderer = new PdfRenderer(getSeekableFileDescriptor());
// let us just render all pages
final int pageCount = renderer.getPageCount();
for (int i = 0; i < pageCount; i++) {
Page page = renderer.openPage(i);
// say we render for showing on the screen
page.render(mBitmap, null, null, Page.RENDER_MODE_FOR_DISPLAY);
// do stuff with the bitmap
// close the page
page.close();
}
// close the renderer
renderer.close();
Read more about it from the docs.
Upvotes: 1
Reputation: 1861
WebView can easily be used for displaying PDF file from a web url but if you have local PDF file, then it becomes a pain.
In my case i first stored a reference of my local file:-
File file = new File(getExternalFilesDir(null),"your_pdf_file.pdf");
Then i obtained file path URI of my local PDF file using FileProvider and started an intent for opening it using existing applications that can open PDF documents:-
try{
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(FileProvider.getUriForFile(BaseActivity.this,BuildConfig.APPLICATION_ID +".provider",file), "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(BaseActivity.this,"No Application Available to View PDF",Toast.LENGTH_SHORT).show();
}
Also to use FileProvider API, you need to declare it in manifest as:-
<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/file_paths" />
</provider>
And declare file_paths.xml under XML resource folder as:-
<paths>
<external-path name="external_files" path="."/>
</paths>
Upvotes: -1
Reputation: 1
you can use the SkewPdfView library for loading pdf from remote or local urls.
First of all, Add following in your root build.gradle:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
and add the SkewPdfView
Library as:
dependencies {
implementation 'com.github.naya-aastra:SkewPdfView:1.1'
}
Now Include SkewPdfView in your layout:
<com.nayaastra.skewpdfview.SkewPdfView
android:id="@+id/skewPdfView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Save all the local files in assets folder and then use SkewPdfView as follows. Load a PDF file programmatically as:
SkewPdfView skewPdfView;
skewPdfView = findViewById(R.id.skewPdfView);
String pdfLink = "LINK TO ASSET FILE";
skewPdfView.loadPdf(pdfLink);
P.S. link of SkewPdfView library
Upvotes: 0
Reputation: 6165
I know, this question is old.
But I really like the approach of Xamarin to make use of the pdf.js from Mozilla. It works on older Android versions, you don't need a special PDF Viewer app for this and you can easily display a PDF inside of your apps views hierarchy.
Git for this: https://mozilla.github.io/pdf.js/
Additional default options (like standard zoom): https://github.com/mozilla/pdf.js/wiki/Viewer-options
Just add the pdfjs files to your Assets directory:
And call it the following way:
// Assuming you got your pdf file:
File file = new File(Environment.getExternalStorageDirectory() + "/test.pdf");
webview = (WebView) findViewById(R.id.webview);
WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true);
settings.setAllowFileAccessFromFileURLs(true);
settings.setAllowUniversalAccessFromFileURLs(true);
settings.setBuiltInZoomControls(true);
webview.setWebChromeClient(new WebChromeClient());
webview.loadUrl("file:///android_asset/pdfjs/web/viewer.html?file=" + file.getAbsolutePath() + "#zoom=page-width");
Cool thing: If you want to reduce the amount of functionalities / controls. Go to the Assets/pdfjs/web/viewer.html file and mark certain controls as hidden. With
style="display: none;"
E.g. If you don't like the right toolbar:
<div id="toolbarViewerRight" style="display: none;">...</div>
Update
'URL scheme "file" is not supported'
Might occur for newer versions of pdfjs. With version 1.8.188
this error does not appear.
Upvotes: 30
Reputation: 7511
From android OS 5.0(lollipop) on-wards you can use PdfRenderer instead of webview/library.
You can use this class to show pdf's within the app.
If you want to support OS lower than that you can use a library/other approach mentioned in other answer as there is no native support.
Read more about it from the docs, you can also refer this example
Upvotes: 1
Reputation: 6769
After going through several posts I came across this simple answer on Quora which pretty much do the work. Following are steps:-
Add this dependency in your gradle file:
compile 'com.github.barteksc:android-pdf-viewer:2.0.3'
activity_main.xml
<com.github.barteksc.pdfviewer.PDFView
android:id="@+id/pdfView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
MainActivity.java
package pdfviewer.pdfviewer;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import com.github.barteksc.pdfviewer.PDFView;
import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener;
import com.github.barteksc.pdfviewer.listener.OnPageChangeListener;
import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle;
import com.shockwave.pdfium.PdfDocument;
import java.util.List;
public class MainActivity extends Activity implements OnPageChangeListener,OnLoadCompleteListener{
private static final String TAG = MainActivity.class.getSimpleName();
public static final String SAMPLE_FILE = "sample_pdf.pdf";
PDFView pdfView;
Integer pageNumber = 0;
String pdfFileName;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pdfView= (PDFView)findViewById(R.id.pdfView);
displayFromAsset(SAMPLE_FILE);
}
private void displayFromAsset(String assetFileName) {
pdfFileName = assetFileName;
pdfView.fromAsset(SAMPLE_FILE)
.defaultPage(pageNumber)
.enableSwipe(true)
.swipeHorizontal(false)
.onPageChange(this)
.enableAnnotationRendering(true)
.onLoad(this)
.scrollHandle(new DefaultScrollHandle(this))
.load();
}
@Override public void onPageChanged(int page, int pageCount) {
pageNumber = page;
setTitle(String.format("%s %s / %s", pdfFileName, page + 1, pageCount));
}
@Override public void loadComplete(int nbPages) {
PdfDocument.Meta meta = pdfView.getDocumentMeta();
printBookmarksTree(pdfView.getTableOfContents(), "-");
}
public void printBookmarksTree(List<PdfDocument.Bookmark> tree, String sep) {
for (PdfDocument.Bookmark b : tree) {
Log.e(TAG, String.format("%s %s, p %d", sep, b.getTitle(), b.getPageIdx()));
if (b.hasChildren()) {
printBookmarksTree(b.getChildren(), sep + "-");
}
}
}
}
You have to make sure that your asset folder contains sample_pdf.pdf (Library also support opening pdf from Uri and SDCard)
Happy coding :)
Upvotes: 3
Reputation: 119
WebView can not open a .pdf file. The most popular solution (google docs' url + your url in WebView) just shows you converted by google docs pictures. However there is still no simple way to open .pdf from url.
Upvotes: -2
Reputation: 4619
As @Sameer replied in your comment above, the only solution to view PDF in webview is through Google Docs' online viewer which will render and send back a readable version to your app.
Previously discussed here
Upvotes: 5
Reputation: 13458
You cannot. Using an Intent, you can open the PDF in an external viewer application like Acrobat Reader:
try
{
Intent intentUrl = new Intent(Intent.ACTION_VIEW);
intentUrl.setDataAndType(uri, "application/pdf");
intentUrl.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mActivity.startActivity(intentUrl);
}
catch (ActivityNotFoundException e)
{
Toast.makeText(mActivity, "No PDF Viewer Installed", Toast.LENGTH_LONG).show();
}
Upvotes: 2