Я пытаюсь создать приложение, которое загружает файл PDF из Интернета и сохраняет его в папке «Загрузки». После загрузки pdf вместо того, чтобы открывать стороннее pdf-приложение, я хочу, чтобы оно отображалось в самом приложении (я выполнил загрузку и сохранение в папке Downloads). Для этого я должен использовать PDFRendered. Но проблема, с которой я сталкиваюсь, заключается в том, что я новичок, и, посмотрев некоторые учебники, я могу правильно отобразить pdf, но только тогда, когда он присутствует в папке ресурсов. Загруженный PDF-файл присутствует в папке «Загрузки». Есть ли способ, с помощью которого я могу использовать PDF-файл из папки «Загрузки» и отобразить его в самом приложении вместо предварительного определения PDF-файла в папке активов?
Я попытался загрузить и сохранить файл в папке «Загрузка», и я успешно сделал это, но я не могу использовать файл для рендеринга, поскольку он не находится в папке активов.
//Code which is successfully rendering pdf from assets folder. How to
//use it to render pdf from Download folder?
public class PdfRender extends AppCompatActivity {
@BindView(R.id.pdf_image) ImageView imageViewPdf;
@BindView(R.id.button_pre_doc) FloatingActionButton prePageButton;
@BindView(R.id.button_next_doc) FloatingActionButton nextPageButton;
private static final String FILENAME = Environment.DIRECTORY_DOWNLOADS+"/a.pdf";
private int pageIndex;
private PdfRenderer pdfRenderer;
private PdfRenderer.Page currentPage;
private ParcelFileDescriptor parcelFileDescriptor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_render);
ButterKnife.bind(this);
pageIndex = 0;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onStart() {
super.onStart();
try {
openRenderer(getApplicationContext());
showPage(pageIndex);
} catch (IOException e) {
e.printStackTrace();
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onStop() {
try {
closeRenderer();
} catch (IOException e) {
e.printStackTrace();
}
super.onStop();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@OnClick(R.id.button_pre_doc)
public void onPreviousDocClick(){
showPage(currentPage.getIndex() - 1);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@OnClick(R.id.button_next_doc)
public void onNextDocClick(){
showPage(currentPage.getIndex() + 1);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void openRenderer(Context context) throws IOException {
// In this sample, we read a PDF from the assets directory.
File file = new File(context.getCacheDir(), FILENAME);
if (!file.exists()) {
// Since PdfRenderer cannot handle the compressed asset file directly, we copy it into
// the cache directory.
InputStream asset = context.getAssets().open(FILENAME);
FileOutputStream output = new FileOutputStream(file);
final byte[] buffer = new byte[1024];
int size;
while ((size = asset.read(buffer)) != -1) {
output.write(buffer, 0, size);
}
asset.close();
output.close();
}
parcelFileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
// This is the PdfRenderer we use to render the PDF.
if (parcelFileDescriptor != null) {
pdfRenderer = new PdfRenderer(parcelFileDescriptor);
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void closeRenderer() throws IOException {
if (null != currentPage) {
currentPage.close();
}
pdfRenderer.close();
parcelFileDescriptor.close();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
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();
}
// Use `openPage` to open a specific page in PDF.
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.
// To render a portion of the page, use the second and third parameter. Pass nulls to get
// the default result.
// Pass either RENDER_MODE_FOR_DISPLAY or RENDER_MODE_FOR_PRINT for the last parameter.
currentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
// We are ready to show the Bitmap to user.
imageViewPdf.setImageBitmap(bitmap);
updateUi();
}
/**
* Updates the state of 2 control buttons in response to the current page index.
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void updateUi() {
int index = currentPage.getIndex();
int pageCount = pdfRenderer.getPageCount();
prePageButton.setEnabled(0 != index);
nextPageButton.setEnabled(index + 1 < pageCount);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public int getPageCount() {
return pdfRenderer.getPageCount();
}
}
Обновление: я пытался внести изменения в рабочий код приложения Rendering и отредактировал openRenderer (), чтобы внести изменения и дать имя и местоположение моего файла, как показано ниже, но файл pdf не открывается даже при его обнаружении ( проверил в логах, используя file.exists ()). Есть ли способ найти решение этой проблемы?
`private void openRenderer(Context context) throws IOException {
File file = new File("storage/emulated/0/Download/" + FILENAME);
if (!file.exists()) {
Log.e("testit", "Not exists");
FileInputStream asset = new FileInputStream(file);
FileOutputStream output = new FileOutputStream(file);
final byte[] buffer = new byte[1024];
int size;
while ((size = asset.read(buffer)) != -1) {
output.write(buffer, 0, size);
}
asset.close();
output.close();
}
parcelFileDescriptor = ParcelFileDescriptor.open(file,ParcelFileDescriptor.MODE_READ_ONLY);
// This is the PdfRenderer we use to render the PDF.
if (parcelFileDescriptor != null) {
pdfRenderer = new PdfRenderer(parcelFileDescriptor);
}
}`
Я получаю следующую ошибку в логах
`java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.pdf.PdfRenderer.close()' on a null object reference`
Ожидаемые результаты можно получить и скачать PDF из Интернета. Нажмите на кнопку, которая загружает файл и сразу после загрузки отображает PDF в самом приложении, и пользователи могут просматривать PDF в самом приложении без использования какого-либо стороннего PDF-приложения или веб-просмотра (для пользователей после или на 5.0).