簡體   English   中英

Android v23 PDFreader不斷崩潰

[英]Android v23 PDFreader keep crashing

我在這里是新手,但是想知道是否有人可以指出我正確的方向。 這是我的應用程序的一部分,在該應用程序中,我想從資產中讀取PDF文件並顯示在片段中。 Android版本使用23.4.0

public class PDFFragment extends Fragment {

private ParcelFileDescriptor fileDescriptor;
private PdfRenderer pdfRenderer;
private PdfRenderer.Page currentPage;
private ImageView image;
private Button buttonPrevious;
private Button buttonNext;

public PDFFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_research_paper, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    // Retain view references.
    image = (ImageView) view.findViewById(R.id.image);
    buttonPrevious = (Button) view.findViewById(R.id.button_previous_research);
    buttonNext = (Button) view.findViewById(R.id.button_next_research);

    //set buttons event
    buttonPrevious.setOnClickListener(onActionListener(-1)); //previous button clicked
    buttonNext.setOnClickListener(onActionListener(1)); //next button clicked

    int index = 0;
    // If there is a savedInstanceState (screen orientations, etc.), we restore the page index.
    if (null != savedInstanceState) {
        index = savedInstanceState.getInt("current_page", 0);
    }
    showPage(index);
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        openRenderer(activity);
    } catch (IOException e) {
        e.printStackTrace();
        Log.i("Fragment", "Error occurred!");
        Log.e("Fragment", e.getMessage());
        activity.finish();
    }
}

@Override
public void onDestroy() {
    try {
        closeRenderer();
    } catch (IOException e) {
        e.printStackTrace();
    }
    super.onDestroy();
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if (null != currentPage) {
        outState.putInt("current_page", currentPage.getIndex());
    }
}

 //Create a PDF renderer
private void openRenderer(Activity activity) throws IOException {
    // Reading a PDF file from the assets directory.
    fileDescriptor = activity.getAssets().openFd("research_paper.pdf").getParcelFileDescriptor();

    // This is the PdfRenderer we use to render the PDF.
    pdfRenderer = new PdfRenderer(fileDescriptor);
}

 //Closes PdfRenderer and related resources.
private void closeRenderer() throws IOException {
    if (null != currentPage) {
        currentPage.close();
    }
    pdfRenderer.close();
    fileDescriptor.close();
}

 //Shows the specified page of PDF file to screen
private void showPage(int index) {
    if (pdfRenderer.getPageCount() <= index) {
        return;
    }
    // Make sure to close the current page before opening another one.
    if (null != currentPage) {
        currentPage.close();
    }
    //open a specific page in PDF file
    currentPage = pdfRenderer.openPage(index);
    // Important: the destination bitmap must be ARGB (not RGB).
    Bitmap bitmap = Bitmap.createBitmap(currentPage.getWidth(), currentPage.getHeight(),
            Bitmap.Config.ARGB_8888);
    // Here, we render the page onto the Bitmap.
    currentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
    // showing bitmap to an imageview
    image.setImageBitmap(bitmap);
    updateUIData();
}

 //Updates the state of 2 control buttons in response to the current page index.
private void updateUIData() {
    int index = currentPage.getIndex();
    int pageCount = pdfRenderer.getPageCount();
    buttonPrevious.setEnabled(0 != index);
    buttonNext.setEnabled(index + 1 < pageCount);
    getActivity().setTitle(getString(index + 1, pageCount));
}

private View.OnClickListener onActionListener(final int i) {
    return new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (i < 0) {//go to previous page
                showPage(currentPage.getIndex() - 1);
            } else {
                showPage(currentPage.getIndex() + 1);
            }
        }
    };
}

}

Logcat錯誤消息

              java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.pdf.PdfRenderer.getPageCount()' on a null object reference
                  at com.example.PDFFragment.showPage(PDFFragment.java:115)
                  at com.example.PDFFragment.onViewCreated(PDFFragment.java:61)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
                  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
                  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
                  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
                  at android.os.Handler.handleCallback(Handler.java:739)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:148)
                  at android.app.ActivityThread.main(ActivityThread.java:5417)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

現在看來至少有2個不同的問題會影響PdfRenderer行為。

第一個與gradle插件v2.2( https://code.google.com/p/android/issues/detail?id=224273 )中的錯誤有關,該錯誤會影響以下確保Gradle不需要的gradle配置的處理壓縮(如https://github.com/googlesamples/android-PdfRendererBasic中所述 )。 這是必需的,因為PdfRenderer需要一個可ParcelFileDescriptor (因此無法壓縮文件)。 您可以使用2.2版本的gradle插件,使用Google的PdfRendererBasic示例重現此問題。 解決此問題的方法是還原到插件v2.1.2。

android {
    aaptOptions {
        noCompress "pdf"
    }
}

另一個問題似乎不在PdfRendererBasic示例中發生,而是在其他應用程序中(包括我的!),並且似乎與apk的打包有關( Android Studio-PDFRendererBasic-無法替換sample.pdf?包含有關該問題的詳細討論)。

上一篇鏈接的SO文章中的一個建議是改為從raw文件夾中讀取...。但是由於某種原因,這對我不起作用。 我最終要做的是使用以下類似的東西從SD卡准備好pdf

    String pdfPath = Environment.getExternalStorageDirectory() + "/sample.pdf";
    mFileDescriptor = ParcelFileDescriptor.open(new File(pdfPath), ParcelFileDescriptor.MODE_READ_ONLY);

    // This is the PdfRenderer we use to render the PDF.
    mPdfRenderer = new PdfRenderer(mFileDescriptor);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM