Show PDF file in App - android

I found this two possibilities to show a pdf file.
Open a webView with:
webView.loadUrl("https://docs.google.com/gview?embedded=true&url="+uri);
Open the pdf File with a extern App:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(outFile),"application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
Both of them work. But my problem is that the pdf is for internal use only and in both examples the user could download it or save it in another folder.
I know frameworks for this in iOS dev, I looking for a solution that works with Android.

Android provides PDF API now with which it is easy to present pdf content inside application.
you can find details here
Below is the sample snippet to render from a pdf file in assets folder.
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();
}
mFileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
// This is the PdfRenderer we use to render the PDF.
if (mFileDescriptor != null) {
mPdfRenderer = new PdfRenderer(mFileDescriptor);
}
}
update: This snippet is from google developers provided samples.

Many libraries are available for showing pdfs within your own app.
Android PDF Viewer
VuDroid
APDFViewer
droidreader
android-pdf
mupdf
android-pdfView
For a working example using android-pdfView, see this blog post.
It demonstrates the basic usage of the library to display pdf onto the view with vertical and horizontal swipe.
pdfView = (PDFView) findViewById(R.id.pdfView);
pdfView.fromFile(new File("/storage/sdcard0/Download/pdf.pdf")).defaultPage(1).enableSwipe(true).onPageChange(this).load();

You can show the PDF in your own viewer
Tier are few open source pdf viewers you should look at:
http://androiddeveloperspot.blogspot.com/2013/05/android-pdf-reader-open-source-code.html
You can encrypt the pdf and make sure that your viewer only will be able to decrypt it.

Related

Where to store static pdf or general files while building an android app?

I have a number of pdf files (but I might extend the functionality to other document types as well) that I want to show in my app. Static images go in drawable folder, static text goes in the strings file. But where do I put pdf files?
I know I can host it on a server and have a one-time-download kind of thing, but for my app's use case that's impossible. The app is being designed for a very specific use case in mind and I absolutely need to bundle the pdf files along with the app.
Create directory named assets in your app and put your pdf files in that directory. use this to read and display pdf files.
I think you can keep your PDF file (or any other file type) inside assets folder. So while downloading the APK form store, it will download those files too. Only problem is it will increase the APP size.
Check the below answer how you can access the PDF file from the Assets using assetManager
https://stackoverflow.com/a/17085759/7023751
I'm answering my own question because other answers didn't fully work for me.
Like the other answers, I read the file from assets folder and created a file in internal storage. I used muPDF which works perfectly with file URI.
items is an ArrayList of file names.
try
{
AssetManager assetManager = getAssets();
InputStream in = assetManager.open(items.get(position));
byte[] buffer = new byte[in.available()];
in.read(buffer);
File targetFile = new File(getFilesDir(), items.get(position));
OutputStream outStream = new FileOutputStream(targetFile);
outStream.write(buffer);
in.close();
outStream.flush();
outStream.close();
//Change below intent statements as per your code
Intent intent = new Intent(this, DocumentActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.fromFile(targetFile));
startActivity(intent);
}
catch (Exception e)
{
e.printStackTrace();
}

Read PDF file from Online in Android

I want to be able to read a file hosted online in my android application. The google docs pdf viewers are effective but do not provide a good experience. The PDFViewer jar for opening the file works well for files offline but does not seem to be working for online files. Any sample which shows this.
For reading from SD card, I have found this sample to be very effective [Example of code to implement a PDF reader
Thanks
There is a pdf viewer that's working well in this case, it's RadaeePDF
To open a pdf from remote url:
Global.Init( this );
PDFHttpStream m_stream = new PDFHttpStream();
Document m_doc = new Document();
ReaderController m_vPDF = new ReaderController(this);
m_doc.Close();
m_stream.open("http://server/filename.pdf");
int ret = m_doc.OpenStream(m_stream, null);
if( ret == 0 ) {
m_vPDF.open(m_doc);
setContentView( m_vPDF );
}

How to merge several single page PDF files in to one PDF document in Android

I have single page several PDF files in my SD card. Now I need to programmatically merge those single page PDF files in to one PDF document. I have used Android PDF Writer library to create those single PDF files. How can I do that?
The iText library can merge PDF files, and reputedly there is a version of iText that works on Android.
You can combine multiple PDF Files on Android with with the latest Apache PdfBox Release.
Just add this dependency to your build.gradle:
compile 'org.apache.pdfbox:pdfbox:2.0.2'
And in an async task do this:
private File downloadAndCombinePDFs(InputStream streamToPdf1, InputStream streamToPdf2, InputStream streamToPdf3 ) throws IOException {
PDFMergerUtility ut = new PDFMergerUtility();
ut.addSource(streamToPdf1);
ut.addSource(streamToPdf2);
ut.addSource(streamToPdf3);
final File file = new File(getContext().getExternalCacheDir(), System.currentTimeMillis() + ".pdf");
final FileOutputStream fileOutputStream = new FileOutputStream(file);
try {
ut.setDestinationStream(fileOutputStream);
ut.mergeDocuments(MemoryUsageSetting.setupTempFileOnly());
} finally {
fileOutputStream.close();
}
return file;
}

Android: Can't play video after its been unzipped or copied in a webview

My goal:
Download a zip file that contains a video and JS file. Create a webview that runs the JS file which (among other things) contains a video tag to play that video file.
Problem: when I try to play the video I get an error saying "Sorry this video cannot be played". In logcat I get: error( 1, -2147483648)
Here is the code to unzip the files:
String path = context.getFilesDir().getPath()+"/";
InputStream is;
ZipInputStream zis;
try {
is = new FileInputStream(zip file);
zis = new ZipInputStream( new BufferedInputStream(is));
ZipEntry ze = null;
while ((ze = zis.getNextEntry()) != null) {
String filename = ze.getName();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;
FileOutputStream fout =
_context.openFileOutput( path + filename, Context.MODE_WORLD_READABLE );
while ((count = zis.read(buffer)) != -1) {
baos.write(buffer, 0, count);
baos.toByteArray();
fout.write(baos.toByteArray());
baos.reset();
}
fout.close();
zis.closeEntry();
baos.close();
}
zis.close();
}
To show the video I override MraidWebChromeClient.onShowCustomView:
super.onShowCustomView(view, callback);
if (view instanceof FrameLayout) {
FrameLayout frame = (FrameLayout) view;
if (frame.getFocusedChild() instanceof VideoView) {
VideoView video = (VideoView) frame.getFocusedChild();
frame.removeView(video);
Activity a = (Activity)getContext();
a.setContentView(video);
video.setOnCompletionListener(this);
video.setOnErrorListener(this);
video.start();
}
}
I do not believe there is an error with the video file, pathing or JS because:
The video plays fine if included as a resource in res or streamed with an external http link.
when loading the js file I use loadDataWithBaseURL and all other image elements show up fine.
I have copied the file from res to the local app folder (using similar code to the unzipping code) and the same error occurs.
I am thinking either:
the file is being corrupted while its being unzipped/copied
there is a permissions issue for playing a local video from a webview (even after I've set the file to world_readable. (from this link WebView NOT opening android default video player?)
Any insights into this issue would be greatly appreciated!
K
Ps: does anyone know why in the normal web-browser it will download .mp4 links while in other cases it will try and stream them?
EDIT:
After researching these two post seem to suggest that Android has security to prevent this:
Android - Load video from private folder of app
Playing an app local video (.mp4) in a webview
Copying files to public external worked fine.
And with regards to the Ps: why some videos stream and some are downloaded, Android 3 doesn't support streaming from https and so will download the file.
Since you're unzipping/reading video to/from the SD card, make sure to add the following line to your manifest file: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Since you're using JS, make sure to enable it in your WebView as follows:
private WebView mWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
...
...
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
...
}
As for video playback, the most reliable solution I've found so far is to hand it off to the native media player app (cause I found the WebView really buggy). In order to achieve this, you need to Bind JavaScript code to Android code so that when the user taps on a video thumbnail, you create the corresponding intent and launch the media player app as follows:
Intent i = new Intent();
i.setAction(android.content.Intent.ACTION_VIEW);
File file = new File(PATH_TO_YOUR_VIDEO);
i.setDataAndType(Uri.fromFile(file), "video/*");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
mContext.startActivity(i);
[UPDATE] As per the official documentation (see under "Accessing files on external storage"),
"If you're using API Level 8 or greater, use getExternalFilesDir() to open a File that represents the external storage directory where you should save your files".
"If you're using API Level 7 or lower, use getExternalStorageDirectory(), to open a File representing the root of the external storage".
Your unzipping code contains the line String path = context.getFilesDir().getPath(), try to modify it as per the above.

Read or open a PDF file using iText in android

i am new to android application development.
using iText i had done the PDF creation n write on that created file
now i want to read that PDF file.
how to open or read a PDF file using iText.
Examples will be appreciable..
thenx in advance.....!!!
which is the best library to render the PDF file..????
JPedal / iText / gnujpdf or anyother.....?????
Actually, iText is only for PDF creation, it doesn't contains viewer part. So, you need to choose some another library. You can follow the link provided by Azharahmed to find some useful libraries.
You can create your own PDF Viewer using iText, you can fetch Images for the specific page and simply display that image in a Scroll View.
But for using this approach, you will have to implement an efficient cache and set the specific pages threshold that will be made on initial run and progressively.
Here is the link, that will facilitate you:
public void makeImageFromPDF throws DocumentException,
IOException {
String INPUTFILE = Environment.getExternalStorageDirectory()
.getAbsolutePath()+"/YOUR_DIRECTORY/inputFile.pdf";
String OUTPUTFILE = Environment.getExternalStorageDirectory()
.getAbsolutePath()+"/YOUR_DIRECTORY/outputFile.pdf";
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream(OUTPUTFILE));
document.open();
PdfReader reader = new PdfReader(INPUTFILE);
int n = reader.getNumberOfPages();
PdfImportedPage page;
// Traversing through all the pages
for (int i = 1; i <= n; i++) {
page = writer.getImportedPage(reader, i);
Image instance = Image.getInstance(page);
//Save a specific page threshold for displaying in a scroll view inside your App
}
document.close();
}
You can also use this link as a reference:
Reading a pdf file using iText library
I hope this helps.

Categories

Resources