2016-12-13 4 views
0

Я новичок здесь, однако задаюсь вопросом, может ли кто-нибудь указать мне в правильном направлении. Это часть моего приложения, в котором я хочу читать PDF-файл из активов и отображать его в фрагменте. Android версия используется 23.4.0Android v23 PDFreader keep crashing

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) 
+0

getPageCount()»на нулевой ссылки на объект -> pdfRenderer равно нулю, инициализировать его –

+0

пытались ли вы с buildToolsVersion«25.0 .1 "?? –

ответ

1

Там выглядит по крайней мере, 2 различные вопросы, влияющие прямо сейчас PdfRenderer поведение.

Первый связан с ошибкой в ​​v2.2 плагина градиента (https://code.google.com/p/android/issues/detail?id=224273), который влияет на обработку следующей конфигурации градиента, которая необходима для обеспечения того, чтобы pdf не был сжат (как указано в https://github.com/googlesamples/android-PdfRendererBasic). Это необходимо, так как PdfRenderer нуждается в ParcelFileDescriptor, который доступен для поиска (поэтому файл не может быть сжат). Вы можете воспроизвести эту проблему с помощью примера PdfRendererBasic Google, используя 2.2 версию плагина gradle. Исправить это - вернуться к v2.1.2 плагина. не кажется

android { 
    aaptOptions { 
     noCompress "pdf" 
    } 
} 

Другой вопрос, происходит в PdfRendererBasic образце, но и в других приложениях (в том числе и мой!), и, как представляется, связаны с упаковкой APK (Android Studio - PDFRendererBasic - Unable to replace sample.pdf? содержит подробное обсуждение вопроса).

Одно предложение в последней связанной статье SO должно было читать из папки raw вместо этого .... однако это почему-то не сработало для меня. То, что я должен был сделать, в конце концов, была готова PDF с SD-карты, используя нечто вроде следующих

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);