Place holder (First Page) of PDF files in android - android

I want to show first page of multi page PDF file on imageview and open PDF file on imageView click.
I'm calling an api and getting PDF files urls as response. Users can upload PDF files and view uploaded files.
(Whatsapp also create placeholder of the pdf, just like that)
Thanks

If you are looking to support API > 21 then you can use PdfRenderer like this.
// create a new renderer
PdfRenderer renderer = new PdfRenderer(getSeekableFileDescriptor());
// let us just render all pages
final int pageCount = renderer.getPageCount();
for (int i = 0; i < pageCount; i++) {
Page page = renderer.openPage(i);
// say we render for showing on the screen
page.render(mBitmap, null, null, Page.RENDER_MODE_FOR_DISPLAY);
// do stuff with the bitmap
// close the page
page.close();
}
// close the renderer
renderer.close();
For more info have a look at this: https://developer.android.com/reference/android/graphics/pdf/PdfRenderer

Related

Adding Text/Annotations into existing PDF file and View/Rendering the output in android

I am working on a pdf editor.
I have made my changes on pdf files with OpenPDF core that is based on iText
And I am viewing the Pdf file with AndroidPdfViewer
My problems are:
Adding new annotations like text or tags or icons into an existing pdf file. ( SOLVED )
Show new changes right after annotations added into pdf file.( SOLVED )
Convert user click into Pdf file coordinates to add new annotation based on user clicked location.
Get click event on added annotations and read meta data that added into that annotation , for ex: read tag hash id that sets on icon annotation. ( SOLVED )
Remove added annotation from PDF File.
Any help appreciated
UPDATE
========================================================================
Solution 1: Adding annotations
Here is my code snippet for adding icon annotation into existing pdf file.
public static void addWatermark(Context context, String filePath) throws FileNotFoundException, IOException {
// get file and FileOutputStream
if (filePath == null || filePath.isEmpty())
throw new FileNotFoundException();
File file = new File(filePath);
if (!file.exists())
throw new FileNotFoundException();
try {
// inout stream from file
InputStream inputStream = new FileInputStream(file);
// we create a reader for a certain document
PdfReader reader = new PdfReader(inputStream);
// get page file number count
int pageNumbers = reader.getNumberOfPages();
// we create a stamper that will copy the document to a new file
PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(file));
// adding content to each page
int i = 0;
PdfContentByte under;
// get watermark icon
Image img = Image.getInstance(PublicFunction.getByteFromDrawable(context, R.drawable.ic_chat));
img.setAnnotation(new Annotation("tag", "gd871394bh2c3r", 0, 0, 0, 0));
img.setAbsolutePosition(230, 190);
img.scaleAbsolute(50, 50);
while (i < pageNumbers) {
i++;
// watermark under the existing page
under = stamp.getUnderContent(i);
under.addImage(img);
}
// closing PdfStamper will generate the new PDF file
stamp.close();
} catch (Exception de) {
de.printStackTrace();
}
}
}
Solution 2: Show new changes
Here is my code snippet for refreshing the view after adding annotation, I have added this into AndroidPdfViewer core classes.
public void refresh(int currPage) {
currentPage = currPage;
if (!hasSize) {
waitingDocumentConfigurator = this;
return;
}
PDFView.this.recycle();
PDFView.this.callbacks.setOnLoadComplete(onLoadCompleteListener);
PDFView.this.callbacks.setOnError(onErrorListener);
PDFView.this.callbacks.setOnDraw(onDrawListener);
PDFView.this.callbacks.setOnDrawAll(onDrawAllListener);
PDFView.this.callbacks.setOnPageChange(onPageChangeListener);
PDFView.this.callbacks.setOnPageScroll(onPageScrollListener);
PDFView.this.callbacks.setOnRender(onRenderListener);
PDFView.this.callbacks.setOnTap(onTapListener);
PDFView.this.callbacks.setOnLongPress(onLongPressListener);
PDFView.this.callbacks.setOnPageError(onPageErrorListener);
PDFView.this.callbacks.setLinkHandler(linkHandler);
if (pageNumbers != null) {
PDFView.this.load(documentSource, password, pageNumbers);
} else {
PDFView.this.load(documentSource, password);
}
}
Solution 4: Click on object in pdf
I have create annotations and set it to added image object, AndroidPdfViewer has an event handler, here is the example
#Override
public void handleLinkEvent(LinkTapEvent event) {
// do your stuff here
}
I will add other new solutions into my question, as update parts.
Here is my code snippet for adding text into pdf file,
Your code does not add text into an existing pdf file. It creates a new PDF, adds text to it, and appends this new PDF to the existing file presumably already containing a PDF. The result is one file containing two PDFs.
Concatenating two files of the same type only seldom results in a valid file of that type. This does works for some textual formats (plain text, csv, ...) but hardly ever for binary formats, in particular not for PDFs.
Thus, your viewer gets to show a file which is invalid as a PDF, so your viewer could simply have displayed an error and quit. But PDF viewers are notorious for trying to repair the files they are given, each viewer in its own way. Thus, depending on the viewer you could also see either only the original file, only the new file, a combination of both, an empty file, or some other repair result.
So your observation,
but this will replace with all of the Pdf file, not just inserting into it
is not surprising but may well differ from viewer to viewer.
To actually change an existing file with OpenPDF (or any iText version before 6 or other library forked from such a version) you should read the existing PDF using a PdfReader, manipulate that reader in a PdfStamper, and close that stamper.
For example:
PdfReader reader = new PdfReader("original.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("original-stamped.pdf"));
PdfContentByte cb = stamper.getOverContent(1);
cb.beginText();
cb.setTextMatrix(100, 400);
cb.showText("Text at position 100,400.");
cb.endText();
stamper.close();
reader.close();
In particular take care to use different file names here. After closing the stamper and the reader you can delete the original PDF and replace it with the stamped version.
If it is not desired to have a second file, you can alternatively initialize the PdfStamper with a ByteArrayOutputStream and after closing the stamper and the reader replace the contents of the original file with those of the ByteArrayOutputStream.

How to convert Pdf pages into bitmaps using PdfRender in every android api version's?

I have looked through several codes and imported many libraries, i tried using PdfRender which is quite easy to use but it doesn't work below api version 21 and android-pdfviewer library code it makes the apk size lot bigger when i imported and used it in my project. Can anyone suggest some library or code to convert pdf every pages into bitmaps and saving it in arraylist which should not make apk size bigger and should support every versions of android.
Below i have attched my code PdfRender
ParcelFileDescriptor pdfFile = ParcelFileDescriptor.open(pdf,
ParcelFileDescriptor.MODE_READ_ONLY);
PdfRenderer pdfRenderer = new PdfRenderer(pdfFile);
if (pdfRenderer != null) {
for (int i = 0; i < pdfRenderer .getPageCount(); i++) {
// Open page with specified index
try {
if (pdfPage != null) {
pdfPage .close();
}
} catch (Exception e) {
e.printStackTrace();
}
pdfPage = pdfRenderer.openPage(i);
Bitmap bitmap = Bitmap.createBitmap(olamPage.getWidth(),
pdfPage .getHeight(), Bitmap.Config.ARGB_8888);
//Pdf page is rendered on Bitmap
pdfPage .render(bitmap, null, null,
PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
// ArrayList Adding Bitmaps
pdfBitmaps.add(bitmap);
}

PDFRenderer - How can I render a multiple page pdf to a web view or imageview?

I am new to android development and have been looking for a way to render a pdf that I created. Basically I am trying to render multiple pages and then put them all in a webView where I can scroll down and see each page. As of now the code I have below basically displays the first page and it is in an imageView. Each time I have tried to do multiple pages the pages basically all end up on one view with one on top of another.
Please let me know if you have a way of doing this in a webView.
Example code would be extremely helpful.
Thanks in advance!
try {
File file = new File(getExternalFilesDir(null).getAbsolutePath(), "document.pdf");
mPdfDocument.writeTo(new FileOutputStream(file));
ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
// PdfRenderer renderer = new PdfRenderer(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY));
PdfRenderer renderer = new PdfRenderer(fd);
Bitmap bitmap = Bitmap.createBitmap(800, 1000, Bitmap.Config.ARGB_4444);
int pageCount = renderer.getPageCount();
if (pageCount== 7) {
Log.v("its right", "its right");
} else {
Log.v("its not right", "its right");
}
PdfRenderer.Page pages = renderer.openPage(0);
pages.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
pages.close();
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
Log.e("cannot generate pdf", "e");
}
// create a new renderer
PdfRenderer renderer = new PdfRenderer(getSeekableFileDescriptor());
// let us just render all pages
final int pageCount = renderer.getPageCount();
for (int i = 0; i < pageCount; i++) {
Page page = renderer.openPage(i);
// say we render for showing on the screen
page.render(mBitmap, null, null, Page.RENDER_MODE_FOR_DISPLAY);
// do stuff with the bitmap
// close the page
page.close();
}
// close the renderer
renderer.close();
the secret is in render.getPageCount();
We can not render the multiple pdf pages by PdfRenderer, PdfRendere create the bitmap of the current page. If you have that requirement then you should implement it by assigning pre and next button. When your current page will be rendered and you are going the next page first page render will be closed.

Read and load images from SDcard asynchronously - fail

I'd like to load image which is on SDCARD in folder to imageView of my cell in listView. I've tried different solutions but each of them fails. When I load images normally as it is in every base tutorial everything works. I've observed that, my application slows down when it has to load many images. Images are taken from photo camera of device. I'd like to load each of them asynchronously to avoid UI slow reaction. I've tried to use Thread, Asynctask but each of them throws error: "Only the oryginal thread that created a view hierarchy can touch its views". How to load images to avoid speed problems? SDImageLoader is a class which is possible to get from GITHUB. What I've tried is a standard code but is slows:
In a getView method in ListAdapter:
File imageFile = new File(Options.PATH_TO_FOLDER_PHOTOS_OF_APP + "test.png");
String imageFileString = Options.PATH_TO_FOLDER_PHOTOS_OF_APP + "test.png";
// "test.png" is a test file. Each cell will have different name of file to load.
if(imageFile.exists())
{
Bitmap myBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
image.setImageBitmap(myBitmap);
// final SDImageLoader loader = new SDImageLoader(context);
// new SDImageLoader().load(imageFileString, image);
//UrlImageViewHelper.setUrlDrawable(image, url);
}
else
{
final SDImageLoader loader = new SDImageLoader();
Resources resources = context.getResources();
int resurceId;
resurceId = resources.getIdentifier("bad", "drawable",context.getPackageName());
loader.load(imageFileString, image);
image.setImageResource(resurceId);
}
Have you tried to refresh your project after adding an external library to your project? It doesn't matter with the fragment. You send exact context to the List Adapter - which should be fragment.this.getActivity().

Passing a reference to a Raw video file through Intent and using it in another activity

In my current working code, I pass the reference of an image from a screen that shows some thumbnails. When the thumbnail is selected, the image id is stored and then used in a new activity. Now, when a thumbnail is selected, I want to store the image id and a reference to the associated video file.
When the thumbnail is selected, it opens a new activity that shows the full image with a play button. When the play button is selected, I want it to call a new activity that will play the video based on the reference saved on the thumbnail screen. I have everything working except getting the video to play using the reference. When I hard code the file name in, the video will play.
here's some snippets of my code.
From thumbnail class:
public void onClick(View v) {
Intent fullImage = new Intent(standard_main.this, full_image.class);
Intent playVideo = new Intent(standard_main.this, video.class);
switch(v.getId()){
case R.id.img_standard1:
fullImage.putExtra("Full", R.drawable.img_standard1);
playVideo.putExtra("VideoFile", R.raw.standard); // added to try to reference video for future use
startActivity(fullImage);
break;
From full_image class:
if (x >= leftPlayPoint && x < rightPlayPoint && y >= topPlayPoint && y < bottomPlayPoint){
startActivity(new Intent("com.example.PLAYVIDEO"));
From my video class:
VideoView vd = (VideoView) findViewById(R.id.VideoView);
int vidID = getIntent().getIntExtra("VideoFile",0);
Uri uri = Uri.parse("android.resource://com.example/"+ R.raw.standard);
I want to somehow use vidID to replace R.raw.standard.
If I'm understanding correctly, I cannot use vidID because it is an Int and Uri.parse wants a string. I tried converting the Int to a String using toString() but I suspect that only converted the actual number to a string and did bring in the actual file name. I also tried String.valueOf(vidID).
I'm thinking that Parcelabel might be used somewhere, but I'm not following how to use it. One other option I thought was to store all the video names in an array and somehow use this to dynamically create the file name on the video.java file.
I'll keep searching, but any help is much appreciated.
This is one way to do it. Perhaps there is an easier way, but none that I know of.
Some example code.
int myResourceId = getIntent().getIntExtra("AudioFile", 0);
StringBuilder sb = new StringBuilder();
// get full resource path, e.g. res/raw/audio.mp3
sb.append(getResources().getString(myResourceId));
// delete res folder
sb.delete(0, sb.indexOf("/"));
// delete file extension
sb.delete(sb.indexOf(".mp3"), sb.length());
// insert package at beginning
sb.insert(0, "android.resource://com.example");
Uri uri = Uri.parse(sb.toString());

Categories

Resources