|
1 | 1 |
|
2 | | -# Change of ownership and looking for contributors! |
3 | | - |
4 | | -The ownership of the project was recently changed and we are actively looking for contributors to bring the project back to track. Please [visit](https://github.com/DImuthuUpe/AndroidPdfViewer/issues/1186) |
5 | | - |
6 | 2 | # Android PdfViewer |
7 | 3 |
|
8 | | -__AndroidPdfViewer 1.x is available on [AndroidPdfViewerV1](https://github.com/barteksc/AndroidPdfViewerV1) |
9 | | -repo, where can be developed independently. Version 1.x uses different engine for drawing document on canvas, |
10 | | -so if you don't like 2.x version, try 1.x.__ |
11 | | - |
12 | | -Library for displaying PDF documents on Android, with `animations`, `gestures`, `zoom` and `double tap` support. |
13 | | -It is based on [PdfiumAndroid](https://github.com/barteksc/PdfiumAndroid) for decoding PDF files. Works on API 11 (Android 3.0) and higher. |
14 | | -Licensed under Apache License 2.0. |
15 | | - |
16 | | -## What's new in 3.2.0-beta.1? |
17 | | -* Merge PR #714 with optimized page load |
18 | | -* Merge PR #776 with fix for max & min zoom level |
19 | | -* Merge PR #722 with fix for showing right position when view size changed |
20 | | -* Merge PR #703 with fix for too many threads |
21 | | -* Merge PR #702 with fix for memory leak |
22 | | -* Merge PR #689 with possibility to disable long click |
23 | | -* Merge PR #628 with fix for hiding scroll handle |
24 | | -* Merge PR #627 with `fitEachPage` option |
25 | | -* Merge PR #638 and #406 with fixed NPE |
26 | | -* Merge PR #780 with README fix |
27 | | -* Update compile SDK and support library to 28 |
28 | | -* Update Gradle and Gradle Plugin |
29 | | -* **16 KB Page Size Support**: Updated for Google Play compatibility requirement (November 1st, 2025) |
| 4 | +Supports 16 KB page size. |
30 | 5 |
|
31 | | -## Changes in 3.0 API |
32 | | -* Replaced `Contants.PRELOAD_COUNT` with `PRELOAD_OFFSET` |
33 | | -* Removed `PDFView#fitToWidth()` (variant without arguments) |
34 | | -* Removed `Configurator#invalidPageColor(int)` method as invalid pages are not rendered |
35 | | -* Removed page size parameters from `OnRenderListener#onInitiallyRendered(int)` method, as document may have different page sizes |
36 | | -* Removed `PDFView#setSwipeVertical()` method |
37 | 6 |
|
38 | 7 | ## Installation |
39 | 8 |
|
40 | 9 | Add to _build.gradle_: |
41 | 10 |
|
42 | | -`implementation 'com.github.barteksc:android-pdf-viewer:3.2.0-beta.1'` |
43 | | - |
44 | | -or if you want to use more stable version: |
45 | | - |
46 | | -`implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'` |
47 | | - |
48 | | -Library is available in jcenter repository, probably it'll be in Maven Central soon. |
49 | | - |
50 | | -## 16 KB Page Size Support ✅ FIXED |
51 | | - |
52 | | -**✅ RESOLVED**: This library has been updated and **successfully fixed** to support 16 KB page sizes for Google Play compatibility. Starting November 1st, 2025, all new apps and updates targeting Android 15+ must support 16 KB page sizes. |
53 | | - |
54 | | -### ✅ What Was Fixed: |
55 | | -- **Issue**: The `pdfium-android:1.9.0` dependency contained prebuilt native libraries that were not aligned for 16 KB page sizes |
56 | | -- **Solution**: Implemented compressed shared libraries configuration and post-build realignment scripts |
57 | | -- **Result**: APK now passes all 16 KB alignment checks and is Google Play compliant |
58 | | - |
59 | | -### Key Updates Made: |
60 | | -- **AGP Version**: Using 8.13.0 (above required 8.5.1) |
61 | | -- **NDK Version**: Updated to r28+ for 16 KB support |
62 | | -- **Packaging**: Configured for compressed shared libraries to avoid alignment issues |
63 | | -- **Native Libraries**: All native libraries are properly aligned for 16 KB page sizes |
64 | | -- **Realignment Scripts**: Added automated tools to fix alignment issues |
65 | | - |
66 | | -### ✅ Verification: |
67 | | -Use the provided scripts to verify 16 KB alignment: |
68 | | -- **Linux/macOS**: `./check_16kb_alignment.sh your-app.apk` |
69 | | -- **Windows**: `.\check_16kb_alignment.ps1 -ApkFile "your-app.apk"` |
70 | | -- **Fix Alignment**: `.\realign_apk.bat "your-app.apk"` |
71 | | - |
72 | | -### 🎉 Google Play Compliance: |
73 | | -Your app will now **pass Google Play's 16 KB compatibility checks** and work on devices with 16 KB page sizes. |
74 | | - |
75 | | -For more details, see [16KB_SUPPORT.md](16KB_SUPPORT.md). |
76 | | - |
77 | | -## ProGuard |
78 | | -If you are using ProGuard, add following rule to proguard config file: |
79 | | - |
80 | | -```proguard |
81 | | --keep class com.shockwave.** |
82 | | -``` |
83 | | - |
84 | | -## Include PDFView in your layout |
85 | | - |
86 | | -``` xml |
87 | | -<com.github.barteksc.pdfviewer.PDFView |
88 | | - android:id="@+id/pdfView" |
89 | | - android:layout_width="match_parent" |
90 | | - android:layout_height="match_parent"/> |
91 | | -``` |
92 | | - |
93 | | -## Load a PDF file |
94 | | - |
95 | | -All available options with default values: |
96 | | -``` java |
97 | | -pdfView.fromUri(Uri) |
98 | | -or |
99 | | -pdfView.fromFile(File) |
100 | | -or |
101 | | -pdfView.fromBytes(byte[]) |
102 | | -or |
103 | | -pdfView.fromStream(InputStream) // stream is written to bytearray - native code cannot use Java Streams |
104 | | -or |
105 | | -pdfView.fromSource(DocumentSource) |
106 | | -or |
107 | | -pdfView.fromAsset(String) |
108 | | - .pages(0, 2, 1, 3, 3, 3) // all pages are displayed by default |
109 | | - .enableSwipe(true) // allows to block changing pages using swipe |
110 | | - .swipeHorizontal(false) |
111 | | - .enableDoubletap(true) |
112 | | - .defaultPage(0) |
113 | | - // allows to draw something on the current page, usually visible in the middle of the screen |
114 | | - .onDraw(onDrawListener) |
115 | | - // allows to draw something on all pages, separately for every page. Called only for visible pages |
116 | | - .onDrawAll(onDrawListener) |
117 | | - .onLoad(onLoadCompleteListener) // called after document is loaded and starts to be rendered |
118 | | - .onPageChange(onPageChangeListener) |
119 | | - .onPageScroll(onPageScrollListener) |
120 | | - .onError(onErrorListener) |
121 | | - .onPageError(onPageErrorListener) |
122 | | - .onRender(onRenderListener) // called after document is rendered for the first time |
123 | | - // called on single tap, return true if handled, false to toggle scroll handle visibility |
124 | | - .onTap(onTapListener) |
125 | | - .onLongPress(onLongPressListener) |
126 | | - .enableAnnotationRendering(false) // render annotations (such as comments, colors or forms) |
127 | | - .password(null) |
128 | | - .scrollHandle(null) |
129 | | - .enableAntialiasing(true) // improve rendering a little bit on low-res screens |
130 | | - // spacing between pages in dp. To define spacing color, set view background |
131 | | - .spacing(0) |
132 | | - .autoSpacing(false) // add dynamic spacing to fit each page on its own on the screen |
133 | | - .linkHandler(DefaultLinkHandler) |
134 | | - .pageFitPolicy(FitPolicy.WIDTH) // mode to fit pages in the view |
135 | | - .fitEachPage(false) // fit each page to the view, else smaller pages are scaled relative to largest page. |
136 | | - .pageSnap(false) // snap pages to screen boundaries |
137 | | - .pageFling(false) // make a fling change only a single page like ViewPager |
138 | | - .nightMode(false) // toggle night mode |
139 | | - .load(); |
140 | | -``` |
141 | | - |
142 | | -* `pages` is optional, it allows you to filter and order the pages of the PDF as you need |
143 | | - |
144 | | -## Scroll handle |
145 | | - |
146 | | -Scroll handle is replacement for **ScrollBar** from 1.x branch. |
147 | | - |
148 | | -From version 2.1.0 putting **PDFView** in **RelativeLayout** to use **ScrollHandle** is not required, you can use any layout. |
| 11 | +1) Add JitPack to your repositories (Gradle 7+): |
149 | 12 |
|
150 | | -To use scroll handle just register it using method `Configurator#scrollHandle()`. |
151 | | -This method accepts implementations of **ScrollHandle** interface. |
152 | | - |
153 | | -There is default implementation shipped with AndroidPdfViewer, and you can use it with |
154 | | -`.scrollHandle(new DefaultScrollHandle(this))`. |
155 | | -**DefaultScrollHandle** is placed on the right (when scrolling vertically) or on the bottom (when scrolling horizontally). |
156 | | -By using constructor with second argument (`new DefaultScrollHandle(this, true)`), handle can be placed left or top. |
157 | | - |
158 | | -You can also create custom scroll handles, just implement **ScrollHandle** interface. |
159 | | -All methods are documented as Javadoc comments on interface [source](https://github.com/barteksc/AndroidPdfViewer/tree/master/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/scroll/ScrollHandle.java). |
160 | | - |
161 | | -## Document sources |
162 | | -Version 2.3.0 introduced _document sources_, which are just providers for PDF documents. |
163 | | -Every provider implements **DocumentSource** interface. |
164 | | -Predefined providers are available in **com.github.barteksc.pdfviewer.source** package and can be used as |
165 | | -samples for creating custom ones. |
166 | | - |
167 | | -Predefined providers can be used with shorthand methods: |
168 | | -``` |
169 | | -pdfView.fromUri(Uri) |
170 | | -pdfView.fromFile(File) |
171 | | -pdfView.fromBytes(byte[]) |
172 | | -pdfView.fromStream(InputStream) |
173 | | -pdfView.fromAsset(String) |
174 | | -``` |
175 | | -Custom providers may be used with `pdfView.fromSource(DocumentSource)` method. |
176 | | - |
177 | | -## Links |
178 | | -Version 3.0.0 introduced support for links in PDF documents. By default, **DefaultLinkHandler** |
179 | | -is used and clicking on link that references page in same document causes jump to destination page |
180 | | -and clicking on link that targets some URI causes opening it in default application. |
181 | | - |
182 | | -You can also create custom link handlers, just implement **LinkHandler** interface and set it using |
183 | | -`Configurator#linkHandler(LinkHandler)` method. Take a look at [DefaultLinkHandler](https://github.com/barteksc/AndroidPdfViewer/tree/master/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java) |
184 | | -source to implement custom behavior. |
185 | | - |
186 | | -## Pages fit policy |
187 | | -Since version 3.0.0, library supports fitting pages into the screen in 3 modes: |
188 | | -* WIDTH - width of widest page is equal to screen width |
189 | | -* HEIGHT - height of highest page is equal to screen height |
190 | | -* BOTH - based on widest and highest pages, every page is scaled to be fully visible on screen |
191 | | - |
192 | | -Apart from selected policy, every page is scaled to have size relative to other pages. |
193 | | - |
194 | | -Fit policy can be set using `Configurator#pageFitPolicy(FitPolicy)`. Default policy is **WIDTH**. |
195 | | - |
196 | | -## Additional options |
197 | | - |
198 | | -### Bitmap quality |
199 | | -By default, generated bitmaps are _compressed_ with `RGB_565` format to reduce memory consumption. |
200 | | -Rendering with `ARGB_8888` can be forced by using `pdfView.useBestQuality(true)` method. |
201 | | - |
202 | | -### Double tap zooming |
203 | | -There are three zoom levels: min (default 1), mid (default 1.75) and max (default 3). On first double tap, |
204 | | -view is zoomed to mid level, on second to max level, and on third returns to min level. |
205 | | -If you are between mid and max levels, double tapping causes zooming to max and so on. |
206 | | - |
207 | | -Zoom levels can be changed using following methods: |
208 | | - |
209 | | -``` java |
210 | | -void setMinZoom(float zoom); |
211 | | -void setMidZoom(float zoom); |
212 | | -void setMaxZoom(float zoom); |
213 | | -``` |
214 | | - |
215 | | -## Possible questions |
216 | | -### Why resulting apk is so big? |
217 | | -Android PdfViewer depends on PdfiumAndroid, which is set of native libraries (almost 16 MB) for many architectures. |
218 | | -Apk must contain all this libraries to run on every device available on market. |
219 | | -Fortunately, Google Play allows us to upload multiple apks, e.g. one per every architecture. |
220 | | -There is good article on automatically splitting your application into multiple apks, |
221 | | -available [here](http://ph0b.com/android-studio-gradle-and-ndk-integration/). |
222 | | -Most important section is _Improving multiple APKs creation and versionCode handling with APK Splits_, but whole article is worth reading. |
223 | | -You only need to do this in your application, no need for forking PdfiumAndroid or so. |
224 | | - |
225 | | -### Why I cannot open PDF from URL? |
226 | | -Downloading files is long running process which must be aware of Activity lifecycle, must support some configuration, |
227 | | -data cleanup and caching, so creating such module will probably end up as new library. |
228 | | - |
229 | | -### How can I show last opened page after configuration change? |
230 | | -You have to store current page number and then set it with `pdfView.defaultPage(page)`, refer to sample app |
231 | | - |
232 | | -### How can I fit document to screen width (eg. on orientation change)? |
233 | | -Use `FitPolicy.WIDTH` policy or add following snippet when you want to fit desired page in document with different page sizes: |
234 | | -``` java |
235 | | -Configurator.onRender(new OnRenderListener() { |
236 | | - @Override |
237 | | - public void onInitiallyRendered(int pages, float pageWidth, float pageHeight) { |
238 | | - pdfView.fitToWidth(pageIndex); |
| 13 | +```gradle |
| 14 | +// settings.gradle |
| 15 | +dependencyResolutionManagement { |
| 16 | + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) |
| 17 | + repositories { |
| 18 | + google() |
| 19 | + mavenCentral() |
| 20 | + maven { url 'https://jitpack.io' } |
239 | 21 | } |
240 | | -}); |
241 | | -``` |
242 | | - |
243 | | -### How can I scroll through single pages like a ViewPager? |
244 | | -You can use a combination of the following settings to get scroll and fling behaviour similar to a ViewPager: |
245 | | -``` java |
246 | | - .swipeHorizontal(true) |
247 | | - .pageSnap(true) |
248 | | - .autoSpacing(true) |
249 | | - .pageFling(true) |
| 22 | +} |
250 | 23 | ``` |
251 | 24 |
|
252 | | -## One more thing |
253 | | -If you have any suggestions on making this lib better, write me, create issue or write some code and send pull request. |
254 | | - |
255 | | -## License |
| 25 | +2) Add the dependency: |
256 | 26 |
|
257 | | -Created with the help of android-pdfview by [Joan Zapata](http://joanzapata.com/) |
| 27 | +```gradle |
| 28 | +implementation 'com.github.xposed73:AndroidPdfViewer:1.0.0' |
258 | 29 | ``` |
259 | | -Copyright 2017 Bartosz Schiller |
260 | 30 |
|
261 | | -Licensed under the Apache License, Version 2.0 (the "License"); |
262 | | -you may not use this file except in compliance with the License. |
263 | | -You may obtain a copy of the License at |
| 31 | +## Publish (quickest: JitPack) |
264 | 32 |
|
265 | | - http://www.apache.org/licenses/LICENSE-2.0 |
| 33 | +1) Push this project to a public GitHub repo under your account. |
| 34 | +2) Create a release tag (example: `v1.0.0`). |
| 35 | +3) Visit `https://jitpack.io/#xposed73/AndroidPdfViewer` and trigger a build for the tag. |
| 36 | +4) Consumers can then use the dependency shown above. |
266 | 37 |
|
267 | | -Unless required by applicable law or agreed to in writing, software |
268 | | -distributed under the License is distributed on an "AS IS" BASIS, |
269 | | -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
270 | | -See the License for the specific language governing permissions and |
271 | | -limitations under the License. |
272 | | -``` |
| 38 | +Notes: |
| 39 | +- If JitPack needs a specific JDK/Gradle, add a `jitpack.yml` with your settings. |
| 40 | +- Keep tags semantic (e.g., `v1.0.1`) to publish updates. |
0 commit comments