[英]Android v23 PDFreader keep crashing
I am new here however wondering if someone could point me in the right direction. 我在这里是新手,但是想知道是否有人可以指出我正确的方向。 This is part of my app in which I want to read PDF file from assets and display in the fragment.
这是我的应用程序的一部分,在该应用程序中,我想从资产中读取PDF文件并显示在片段中。 Android version used 23.4.0
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 error message 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)
There looks to be at least 2 different issues right now affecting PdfRenderer
behaviour. 现在看来至少有2个不同的问题会影响
PdfRenderer
行为。
First one is related to bug in v2.2 of gradle plugin ( https://code.google.com/p/android/issues/detail?id=224273 ) that affects treatment of following gradle config that's required to ensure pdf is not compressed (as mentioned in https://github.com/googlesamples/android-PdfRendererBasic ). 第一个与gradle插件v2.2( https://code.google.com/p/android/issues/detail?id=224273 )中的错误有关,该错误会影响以下确保Gradle不需要的gradle配置的处理压缩(如https://github.com/googlesamples/android-PdfRendererBasic中所述 )。 This is required as
PdfRenderer
needs a ParcelFileDescriptor
that is seekable (so file cannot be compressed). 这是必需的,因为
PdfRenderer
需要一个可ParcelFileDescriptor
(因此无法压缩文件)。 You can reproduce this issue with google's PdfRendererBasic
sample by using 2.2 version of gradle plugin. 您可以使用2.2版本的gradle插件,使用Google的
PdfRendererBasic
示例重现此问题。 A fix for this is to revert to v2.1.2 of plugin. 解决此问题的方法是还原到插件v2.1.2。
android {
aaptOptions {
noCompress "pdf"
}
}
The other issue doesn't seem to be occurring in PdfRendererBasic
sample but is in other apps (including mine!) and seems to be related to packaging of apk ( Android Studio - PDFRendererBasic - Unable to replace sample.pdf? contains detailed discussion on issue). 另一个问题似乎不在
PdfRendererBasic
示例中发生,而是在其他应用程序中(包括我的!),并且似乎与apk的打包有关( Android Studio-PDFRendererBasic-无法替换sample.pdf?包含有关该问题的详细讨论)。
One suggestion in last linked SO article was to read from raw
folder instead....however this didn't work for me for some reason. 上一篇链接的SO文章中的一个建议是改为从
raw
文件夹中读取...。但是由于某种原因,这对我不起作用。 What I had to do in the end was ready pdf from SD card using something like following 我最终要做的是使用以下类似的东西从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.