WebView-এ PDF দেখানোর উপায়সমূহ
Android WebView নেটিভভাবে PDF রেন্ডার করে না। এই টিউটোরিয়ালে তিনটি পদ্ধতি দেখানো হয়েছে: Google Docs Viewer, Mozilla PDF.js, এবং AndroidX PDF Viewer লাইব্রেরি।
পদ্ধতি ১: Google Docs Viewer (সरलতম, ইন্টারনেট দরকার)
Google Docs Embedded Viewer ব্যবহার করে যেকোনো পাবলিক्ली অ্যাক্সেসযোগ্য PDF URL দেখানো যায়।
MainActivity.java
package com.example.webviewpdf;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void loadPdf(View view) {
webView = new WebView(this);
setContentView(webView);
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setAllowFileAccess(true);
settings.setAllowContentAccess(true);
settings.setLoadWithOverviewMode(true);
settings.setUseWideViewPort(true);
settings.setBuiltInZoomControls(true);
settings.setDisplayZoomControls(false);
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
});
// Google Docs Viewer URL pattern
String pdfUrl = "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf";
String viewerUrl = "https://docs.google.com/gview?embedded=true&url=" + pdfUrl;
webView.loadUrl(viewerUrl);
}
@Override
public void onBackPressed() {
if (webView != null && webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
@Override
protected void onDestroy() {
if (webView != null) {
webView.destroy();
}
super.onDestroy();
}
}
পদ্ধতি ২: Mozilla PDF.js (অফলাইন, লোকাল ফাইল সাপোর্ট)
PDF.js একটি জাভাস্ক্রিপ্ট লাইব্রেরি যা ব্রাউজারে PDF রেন্ডার করে। এটি অফলাইন কাজ করে এবং লোকাল ফাইল (assets/raw/storage) পড়তে পারে।
সেটআপ
- PDF.js ডাউনলোড করুন: github.com/mozilla/pdf.js/releases
web/viewer.htmlএবংbuild/pdf.js,build/pdf.worker.jsকপি করুনassets/pdfjs/ফোল্ডারে
MainActivity.java (PDF.js)
package com.example.webviewpdf;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void loadPdf(View view) {
webView = new WebView(this);
setContentView(webView);
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setAllowFileAccess(true);
settings.setAllowFileAccessFromFileURLs(true); // লোকাল ফাইল এক্সেস
settings.setAllowUniversalAccessFromFileURLs(true);
settings.setBuiltInZoomControls(true);
settings.setDisplayZoomControls(false);
webView.setWebViewClient(new WebViewClient());
// Assets-এ থাকা PDF ফাইল (assets/sample.pdf)
String pdfPath = "file:///android_asset/sample.pdf";
String viewerUrl = "file:///android_asset/pdfjs/web/viewer.html?file=" + Uri.encode(pdfPath);
webView.loadUrl(viewerUrl);
}
@Override
public void onBackPressed() {
if (webView != null && webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
}
পদ্ধতি ৩: AndroidX PDF Viewer (নেটিভ, সেরা পারফরম্যান্স)
Google-এর অফিসিয়াল androidx.pdf:pdf-viewer লাইব্রেরি (কotlin) ব্যবহার করে নেটিভ PDF রেন্ডারিং। এটি WebView-এর চেয়ে অনেক দ্রুত এবং ফিচার-রিচ।
build.gradle (app)
dependencies {
implementation "androidx.pdf:pdf-viewer:1.0.0-beta01"
// বা পুরনো ভার্সন:
// implementation "com.github.barteksc:android-pdf-viewer:3.2.0-beta.1"
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.barteksc.pdfviewer.PDFView
android:id="@+id/pdfView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java (AndroidX PDF Viewer)
package com.example.webviewpdf;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
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;
public class MainActivity extends AppCompatActivity {
private PDFView pdfView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pdfView = findViewById(R.id.pdfView);
}
public void loadPdf(View view) {
pdfView.fromAsset("sample.pdf") // assets/sample.pdf
.defaultPage(0)
.enableSwipe(true)
.swipeHorizontal(false)
.enableDoubletap(true)
.onLoad(new OnLoadCompleteListener() {
@Override
public void loadComplete(int nbPages) {
// লোড হয়েছে
}
})
.onPageChange(new OnPageChangeListener() {
@Override
public void onPageChanged(int page, int pageCount) {
// পেজ পরিবর্তন
}
})
.scrollHandle(new DefaultScrollHandle(this))
.load();
}
}
তুলনামূলক সারসংক্ষেপ
| পদ্ধতি | অফলাইন | পারফরম্যান্স | ফিচার | সেটআপ জটিলতা |
|---|---|---|---|---|
| Google Docs Viewer | ❌ | মধ্যম | বেসিক জুম, স্ক্রোল | নিম্ন |
| Mozilla PDF.js | ✅ | মধ্যম | জুম, সার্চ, থাম্বনেইল, আউटलাইন | মধ্যম |
| AndroidX PDF Viewer | ✅ | উৎকৃষ্ট (নেটিভ) | সব ফিচার + অ্যানোটেশন, ফর্ম ফিল | নিম্ন |
AndroidManifest.xml (সব পদ্ধতির জন্য)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.webviewpdf">
<uses-permission android:name="android.permission.INTERNET" />
<!-- লোকাল স্টোরেজ থেকে পড়ার জন্য (ঐচ্ছিক) -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.WebViewPdf">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml (সিম্পল বাটন লেআউট)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">
<Button
android:id="@+id/btnLoadPdf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:onClick="loadPdf"
android:text="PDF লোড করুন" />
</RelativeLayout>
সেরা অনুশীলন (Best Practices)
- বড় PDF- এর জন্য: AndroidX PDF Viewer বা PDF.js ব্যবহার করুন (WebView মেমরি ক্র্যাশ করতে পারে)
- ইন্টারনেট ছাড়া: PDF.js (assets-এ বান্ডেল) বা AndroidX PDF Viewer
- সিকিউরিটি: Google Docs Viewer-এ প্রাইভেট/সেনসিটিভ PDF লোড করবেন না
- মেমরি ম্যানেজমেন্ট: onDestroy-এ WebView.destroy() বা PDFView রিলিজ করুন
- রানটাইম পারমিশন: Android 10+ (API 29+) এ Scoped Storage — ফাইল পিকারের মাধ্যমে URI নিন
পরীক্ষা চেকলিস্ট
- assets/sample.pdf রাখুন (যেকোনো PDF)
- অ্যাপ চালু → "PDF লোড করুন" চাপুন
- PDF রেন্ডার হচ্ছে কিনা, জুম/স্ক্রোল কাজ করছে কিনা চেক করুন
- রোটেশন (পোর্ট্রেট/ল্যান্ডস্কেপ) এ ক্যাশ হয় না কিনা
- বড় PDF (৫০MB+) টেস্ট করুন মেমরি যাচাই করতে