PDFView 是一個用于在 Android 應用中顯示 PDF 文檔的庫。它提供了豐富的功能和靈活的配置選項,使得開發者能夠輕松地在應用中嵌入 PDF 閱讀器。
一、 添加依賴
- 在模塊的 build.gradle 文件中添加以下依賴:
// pdfimplementation("com.github.barteksc:android-pdf-viewer:3.2.0-beta.1")
二、添加 阿里云 Maven 倉庫
- 此時編譯時會報錯,提示無法找到該庫:
* What went wrong:
Execution failed for task ':app:mergeDebugNativeLibs'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.> Could not find com.github.barteksc:android-pdf-viewer:3.2.0-beta.1.Searched in the following locations:- https://dl.google.com/dl/android/maven2/com/github/barteksc/android-pdf-viewer/3.2.0-beta.1/android-pdf-viewer-3.2.0-beta.1.pom- https://repo.maven.apache.org/maven2/com/github/barteksc/android-pdf-viewer/3.2.0-beta.1/android-pdf-viewer-3.2.0-beta.1.pomRequired by:project :app
- 在項目的 settings.gradle.kts 文件中增加 阿里云 Maven 倉庫 支持。
dependencyResolutionManagement {repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)repositories {google()mavenCentral()// 阿里云 Maven 倉庫maven { url = uri("https://maven.aliyun.com/repository/google") }maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") }maven { url = uri("https://maven.aliyun.com/repository/public") }maven { url = uri("https://maven.aliyun.com/repository/central") }}
}
三、解決庫沖突問題
- 下載 android-pdf-viewer 依賴庫后,編譯提示 “com.android.support” 庫沖突:
* What went wrong:
Execution failed for task ':app:checkDebugDuplicateClasses'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable> Duplicate class android.support.v4.app.AppLaunchChecker found in modules support-compat-28.0.0.aar -> support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0) and support-core-utils-26.1.0.aar -> support-core-utils-26.1.0-runtime (com.android.support:support-core-utils:26.1.0)Duplicate class android.support.v4.app.FrameMetricsAggregator found in modules support-compat-28.0.0.aar -> support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0) and support-core-utils-26.1.0.aar -> support-core-utils-26.1.0-runtime (com.android.support:support-core-utils:26.1.0)Duplicate class android.support.v4.app.FrameMetricsAggregator$FrameMetricsApi24Impl found in modules support-compat-28.0.0.aar -> support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0) and support-core-utils-26.1.0.aar -> support-core-utils-26.1.0-runtime (com.android.support:support-core-utils:26.1.0)Duplicate class android.support.v4.app.FrameMetricsAggregator$FrameMetricsApi24Impl$1 found in modules support-compat-28.0.0.aar -> support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0) and support-core-utils-26.1.0.aar -> support-core-utils-26.1.0-runtime (com.android.support:support-core-utils:26.1.0)Duplicate class android.support.v4.app.FrameMetricsAggregator$FrameMetricsBaseImpl found in modules support-compat-28.0.0.aar -> support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0) and support-core-utils-26.1.0.aar -> support-core-utils-26.1.0-runtime (com.android.support:support-core-utils:26.1.0)Duplicate class android.support.v4.app.FrameMetricsAggregator$MetricType found in modules support-compat-28.0.0.aar -> support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0) and support-core-utils-26.1.0.aar -> support-core-utils-26.1.0-runtime (com.android.support:support-core-utils:26.1.0)Duplicate class android.support.v4.app.INotificationSideChannel found in modules core-1.13.1.aar -> core-1.13.1-runtime (androidx.core:core:1.13.1) and support-compat-28.0.0.aar -> support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0)Duplicate class android.support.v4.app.INotificationSideChannel$Stub found in modules core-1.13.1.aar -> core-1.13.1-runtime (androidx.core:core:1.13.1) and support-compat-28.0.0.aar -> support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0)Duplicate class android.support.v4.app.INotificationSideChannel$Stub$Proxy found in modules core-1.13.1.aar -> core-1.13.1-runtime (androidx.core:core:1.13.1) and support-compat-28.0.0.aar -> support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0)Duplicate class android.support.v4.app.NavUtils found in modules support-compat-28.0.0.aar -> support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0) and support-core-utils-26.1.0.aar -> support-core-utils-26.1.0-runtime (com.android.support:support-core-utils:26.1.0)Duplicate class android.support.v4.app.TaskStackBuilder found in modules support-compat-28.0.0.aar -> support-compat-28.0.0-runtime (com.android.support:support-compat:28.0.0) and support-core-utils-26.1.0.aar -> support-core-utils-26.1.0-runtime (com.android.support:support-core-utils:26.1.0)......Duplicate class androidx.versionedparcelable.VersionedParcelParcel found in modules versionedparcelable-1.1.1.aar -> versionedparcelable-1.1.1-runtime (androidx.versionedparcelable:versionedparcelable:1.1.1) and versionedparcelable-28.0.0.aar -> versionedparcelable-28.0.0-runtime (com.android.support:versionedparcelable:28.0.0)Duplicate class androidx.versionedparcelable.VersionedParcelStream found in modules versionedparcelable-1.1.1.aar -> versionedparcelable-1.1.1-runtime (androidx.versionedparcelable:versionedparcelable:1.1.1) and versionedparcelable-28.0.0.aar -> versionedparcelable-28.0.0-runtime (com.android.support:versionedparcelable:28.0.0)Duplicate class androidx.versionedparcelable.VersionedParcelStream$FieldBuffer found in modules versionedparcelable-1.1.1.aar -> versionedparcelable-1.1.1-runtime (androidx.versionedparcelable:versionedparcelable:1.1.1) and versionedparcelable-28.0.0.aar -> versionedparcelable-28.0.0-runtime (com.android.support:versionedparcelable:28.0.0)Duplicate class androidx.versionedparcelable.VersionedParcelable found in modules versionedparcelable-1.1.1.aar -> versionedparcelable-1.1.1-runtime (androidx.versionedparcelable:versionedparcelable:1.1.1) and versionedparcelable-28.0.0.aar -> versionedparcelable-28.0.0-runtime (com.android.support:versionedparcelable:28.0.0)Duplicate class androidx.versionedparcelable.VersionedParcelize found in modules versionedparcelable-1.1.1.aar -> versionedparcelable-1.1.1-runtime (androidx.versionedparcelable:versionedparcelable:1.1.1) and versionedparcelable-28.0.0.aar -> versionedparcelable-28.0.0-runtime (com.android.support:versionedparcelable:28.0.0)
錯誤分析
- 這個錯誤是由于新增的依賴庫中包含了Android Support Library 的依賴,跟項目中使用的 AndroidX 發生了類沖突。從 Android 9.0(API 級別 28)開始,Android Support Library 已被廢棄,Google 推薦使用 AndroidX 來替代。
解決方法
- 在項目的 gradle.properties 文件中增加自動遷移配置,此時重新編譯,即可編譯通過:
android.useAndroidX=trueandroid.enableJetifier=true
- android.useAndroidX=true:啟用 AndroidX。
- android.enableJetifier=true:啟用 Jetifier 工具,自動遷移項目中的第三方庫依賴。
四、配置文件權限
1、確保應用有權限讀取 PDF 文件,在 AndroidManifest.xml 中添加以下權限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
2、如果文件存儲在外部存儲中,還需要動態申請權限:
// 運行時權限private val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->if (isGranted) {// 權限被授予Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show()} else {// 權限被拒絕Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show()}}/*** 動態申請權限*/private fun requestPermission1() {requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)}
3、手動申請 “所有文件訪問權限”
- 從 Android 10(API 級別 29)開始,引入了分區存儲(Scoped Storage),限制了應用對外部存儲的訪問權限。只有 READ_EXTERNAL_STORAGE 權限,無法打開 PDF 文件,還需要申請 MANAGE_EXTERNAL_STORAGE 權限,并且手動引導用戶手動開啟 “所有文件訪問權限”。
/*** 申請 所有文件訪問權限*/private fun requestManagerPermission() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {if (!Environment.isExternalStorageManager()) {val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)val applicationId = "com.example.helloworld"//BuildConfig.APPLICATION_IDintent.data = "package:$applicationId".toUri()startActivity(intent)}}}
五、PDFView 常用方法
- fromFile(File file):從文件路徑加載 PDF 文件。
val filePath = "$filesDir/example.pdf"pdfView.fromFile(new File(filePath )).load();
- fromAsset(String assetName):從 assets 目錄(res/main/assets/example.pdf)加載 PDF 文件。
pdfView.fromAsset("example.pdf").load();
-
fromUri(Uri uri):從 URI 加載 PDF 文件。
-
defaultPage(int page):設置默認顯示的頁面。
-
enableSwipe(boolean swipe):啟用或禁用滑動翻頁。
-
enableDoubletap(boolean doubletap):啟用或禁用雙擊放大。
-
zoom(float scale):設置 PDFView 的初始縮放比例。
-
rotate(int degrees):設置 PDFView 的初始旋轉角度。
-
onPageChange(OnPageChangeListener listener):設置頁面改變時的監聽器。
-
onError(OnErrorListener listener):設置錯誤監聽器。
-
enableAnnotationRendering(boolean enabled):啟用注釋渲染。
-
setOffscreenPageLimit(int limit):設置預加載頁數,避免 OOM 問題。