Home | History | Annotate | Download | only in pdfrendererbasic
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.example.android.pdfrendererbasic;
     18 
     19 import android.app.Activity;
     20 import android.app.Fragment;
     21 import android.content.Context;
     22 import android.graphics.Bitmap;
     23 import android.graphics.pdf.PdfRenderer;
     24 import android.os.Bundle;
     25 import android.os.ParcelFileDescriptor;
     26 import android.view.LayoutInflater;
     27 import android.view.View;
     28 import android.view.ViewGroup;
     29 import android.widget.Button;
     30 import android.widget.ImageView;
     31 import android.widget.Toast;
     32 
     33 import java.io.IOException;
     34 
     35 /**
     36  * This fragment has a big {@ImageView} that shows PDF pages, and 2 {@link android.widget.Button}s to move between
     37  * pages. We use a {@link android.graphics.pdf.PdfRenderer} to render PDF pages as {@link android.graphics.Bitmap}s.
     38  */
     39 public class PdfRendererBasicFragment extends Fragment implements View.OnClickListener {
     40 
     41     /**
     42      * Key string for saving the state of current page index.
     43      */
     44     private static final String STATE_CURRENT_PAGE_INDEX = "current_page_index";
     45 
     46     /**
     47      * File descriptor of the PDF.
     48      */
     49     private ParcelFileDescriptor mFileDescriptor;
     50 
     51     /**
     52      * {@link android.graphics.pdf.PdfRenderer} to render the PDF.
     53      */
     54     private PdfRenderer mPdfRenderer;
     55 
     56     /**
     57      * Page that is currently shown on the screen.
     58      */
     59     private PdfRenderer.Page mCurrentPage;
     60 
     61     /**
     62      * {@link android.widget.ImageView} that shows a PDF page as a {@link android.graphics.Bitmap}
     63      */
     64     private ImageView mImageView;
     65 
     66     /**
     67      * {@link android.widget.Button} to move to the previous page.
     68      */
     69     private Button mButtonPrevious;
     70 
     71     /**
     72      * {@link android.widget.Button} to move to the next page.
     73      */
     74     private Button mButtonNext;
     75 
     76     public PdfRendererBasicFragment() {
     77     }
     78 
     79     @Override
     80     public View onCreateView(LayoutInflater inflater, ViewGroup container,
     81                              Bundle savedInstanceState) {
     82         return inflater.inflate(R.layout.fragment_pdf_renderer_basic, container, false);
     83     }
     84 
     85     @Override
     86     public void onViewCreated(View view, Bundle savedInstanceState) {
     87         super.onViewCreated(view, savedInstanceState);
     88         // Retain view references.
     89         mImageView = (ImageView) view.findViewById(R.id.image);
     90         mButtonPrevious = (Button) view.findViewById(R.id.previous);
     91         mButtonNext = (Button) view.findViewById(R.id.next);
     92         // Bind events.
     93         mButtonPrevious.setOnClickListener(this);
     94         mButtonNext.setOnClickListener(this);
     95         // Show the first page by default.
     96         int index = 0;
     97         // If there is a savedInstanceState (screen orientations, etc.), we restore the page index.
     98         if (null != savedInstanceState) {
     99             index = savedInstanceState.getInt(STATE_CURRENT_PAGE_INDEX, 0);
    100         }
    101         showPage(index);
    102     }
    103 
    104     @Override
    105     public void onAttach(Activity activity) {
    106         super.onAttach(activity);
    107         try {
    108             openRenderer(activity);
    109         } catch (IOException e) {
    110             e.printStackTrace();
    111             Toast.makeText(activity, "Error! " + e.getMessage(), Toast.LENGTH_SHORT).show();
    112             activity.finish();
    113         }
    114     }
    115 
    116     @Override
    117     public void onDetach() {
    118         try {
    119             closeRenderer();
    120         } catch (IOException e) {
    121             e.printStackTrace();
    122         }
    123         super.onDetach();
    124     }
    125 
    126     @Override
    127     public void onSaveInstanceState(Bundle outState) {
    128         super.onSaveInstanceState(outState);
    129         if (null != mCurrentPage) {
    130             outState.putInt(STATE_CURRENT_PAGE_INDEX, mCurrentPage.getIndex());
    131         }
    132     }
    133 
    134     /**
    135      * Sets up a {@link android.graphics.pdf.PdfRenderer} and related resources.
    136      */
    137     private void openRenderer(Context context) throws IOException {
    138         // In this sample, we read a PDF from the assets directory.
    139         mFileDescriptor = context.getAssets().openFd("sample.pdf").getParcelFileDescriptor();
    140         // This is the PdfRenderer we use to render the PDF.
    141         mPdfRenderer = new PdfRenderer(mFileDescriptor);
    142     }
    143 
    144     /**
    145      * Closes the {@link android.graphics.pdf.PdfRenderer} and related resources.
    146      *
    147      * @throws java.io.IOException When the PDF file cannot be closed.
    148      */
    149     private void closeRenderer() throws IOException {
    150         if (null != mCurrentPage) {
    151             mCurrentPage.close();
    152         }
    153         mPdfRenderer.close();
    154         mFileDescriptor.close();
    155     }
    156 
    157     /**
    158      * Shows the specified page of PDF to the screen.
    159      *
    160      * @param index The page index.
    161      */
    162     private void showPage(int index) {
    163         if (mPdfRenderer.getPageCount() <= index) {
    164             return;
    165         }
    166         // Make sure to close the current page before opening another one.
    167         if (null != mCurrentPage) {
    168             mCurrentPage.close();
    169         }
    170         // Use `openPage` to open a specific page in PDF.
    171         mCurrentPage = mPdfRenderer.openPage(index);
    172         // Important: the destination bitmap must be ARGB (not RGB).
    173         Bitmap bitmap = Bitmap.createBitmap(mCurrentPage.getWidth(), mCurrentPage.getHeight(),
    174                 Bitmap.Config.ARGB_8888);
    175         // Here, we render the page onto the Bitmap.
    176         // To render a portion of the page, use the second and third parameter. Pass nulls to get
    177         // the default result.
    178         // Pass either RENDER_MODE_FOR_DISPLAY or RENDER_MODE_FOR_PRINT for the last parameter.
    179         mCurrentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
    180         // We are ready to show the Bitmap to user.
    181         mImageView.setImageBitmap(bitmap);
    182         updateUi();
    183     }
    184 
    185     /**
    186      * Updates the state of 2 control buttons in response to the current page index.
    187      */
    188     private void updateUi() {
    189         int index = mCurrentPage.getIndex();
    190         int pageCount = mPdfRenderer.getPageCount();
    191         mButtonPrevious.setEnabled(0 != index);
    192         mButtonNext.setEnabled(index + 1 < pageCount);
    193         getActivity().setTitle(getString(R.string.app_name_with_index, index + 1, pageCount));
    194     }
    195 
    196     /**
    197      * Gets the number of pages in the PDF. This method is marked as public for testing.
    198      *
    199      * @return The number of pages.
    200      */
    201     public int getPageCount() {
    202         return mPdfRenderer.getPageCount();
    203     }
    204 
    205     @Override
    206     public void onClick(View view) {
    207         switch (view.getId()) {
    208             case R.id.previous: {
    209                 // Move to the previous page
    210                 showPage(mCurrentPage.getIndex() - 1);
    211                 break;
    212             }
    213             case R.id.next: {
    214                 // Move to the next page
    215                 showPage(mCurrentPage.getIndex() + 1);
    216                 break;
    217             }
    218         }
    219     }
    220 
    221 }
    222