I try to read a pdf file store in the assets folder. I see this solution :
Read a pdf file from assets folder
But like comments say this it's not working anymore, the file cannot be found, is there another solution for read a pdf file directly, without copy pdf in external storage ?
And I don't want to use PdfRenderer my minimal API is 17
Maybe this can be helpful for somebody so I post my answer :
private void openPdf(String pdfName){
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(getFilesDir(), pdfName);
try
{
in = assetManager.open(pdfName);
out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag", e.getMessage());
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.parse("file://" + getFilesDir() + "/"+pdfName),
"application/pdf");
startActivity(intent);
}
The pdf file is store inside the assets folder
Related
I have list of PDF files need to Place in asstes folder,my requirement is to read files from asstes and display it inside a listview.
if we click on each list item need to read respective PDF file
I have followed this blog http://androidcodeexamples.blogspot.in/2013/03/how-to-read-pdf-files-in-android.html
But here they have given reading a PDF files from External Storage Directory
I want to implement the same reading files from Asstes Folder
Could any one help How to implement the same example reading files from asstes?
You cannot open the pdf file directly from the assets folder.You first have to write the file to sd card from assets folder and then read it from sd card.
Try out the below code to copy and read the file from assets folder:
//method to write the PDFs file to sd card
private void PDFFileCopyandReadAssets()
{
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(getFilesDir(), "test.pdf");
try
{
in = assetManager.open("test.pdf");
out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
readFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag", e.getMessage());
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.parse("file://" + getFilesDir() + "/test.pdf"),
"application/pdf");
startActivity(intent);
}
private void readFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
Open the file from sdcard as below:
File file = new File("/sdcard/test.pdf");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),"application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Also provide a permission to write into your external storage in your manifest.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I am using following code to download and read a PDF file from internal storage on device.
I am able to download the files successfully to the directory:
data/data/packagename/app_books/file.pdf
But I am unable to read the file using a PDF reader application like Adobe Reader.
Code to download file
//Creating an internal dir;
File mydir = getApplicationContext().getDir("books", Context.MODE_WORLD_READABLE);
try {
File file = new File(mydir, outputFileName);
URL downloadUrl = new URL(url);
URLConnection ucon = downloadUrl.openConnection();
ucon.connect();
InputStream is = ucon.getInputStream();
FileOutputStream fos = new FileOutputStream(file);
byte data[] = new byte[1024];
int current = 0;
while ((current = is.read(data)) != -1) {
fos.write(data, 0, current);
}
is.close();
fos.flush();
fos.close();
isFileDownloaded=true;
} catch (IOException e) {
e.printStackTrace();
isFileDownloaded = false;
System.out.println(outputFileName + " not downloaded");
}
if (isFileDownloaded)
System.out.println(outputFileName + " downloaded");
return isFileDownloaded;
Code to read the file
PackageManager packageManager = getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent,
PackageManager.MATCH_DEFAULT_ONLY);
try {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
File fileToRead = new File(
"/data/data/com.example.filedownloader/app_books/Book.pdf");
Uri uri = Uri.fromFile(fileToRead.getAbsoluteFile());
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
} catch (Exception ex) {
Log.i(getClass().toString(), ex.toString());
Toast.makeText(MainActivity.this,
"Cannot open your selected file, try again later",
Toast.LENGTH_SHORT).show();
}
All works fine but the reader app says "File Path is not valid".
Your path is only valid for your app. Place the file in a place where other apps can 'see' it. Use GetExternalFilesDir() or getExternalStorageDirectory().
Note about files which are created inside the directory created by Context.getDir(String name, int mode) that they will only be accessible by your own application; you can only set the mode of the entire directory, not of individual files.
So you can use Context.openFileOutput(String name, int mode). I'm re-using your code for an example:
try {
// Now we use Context.MODE_WORLD_READABLE for this file
FileOutputStream fos = openFileOutput(outputFileName,
Context.MODE_WORLD_READABLE);
// Download data and store it to `fos`
// ...
You might want to take a look at this guide: Using the Internal Storage.
If you would like to keep the file app specific, you can use PdfRenderer available for Lollipop and above builds. There are great tutorials on google and youtube that work well. The method you are using is a secure way to store a PDF file that is only readable from inside the app ONLY. No outside application like Adobe PDF Reader will be able to even see the file.It took me a lot of seaching but I found a solution to my specific usage by using this site and especially youtube.
How to download PDF file from asset folder to storage by making folder
make sure you have storage permission are given like marshmallow device support etc then follow these steps
private void CopyReadAssets()
{
AssetManager assetManager = getContext().getAssets();
FileInputStream in = null;
FileOutputStream out = null;
File sdcard = Environment.getExternalStorageDirectory();
File dir = new File(Environment.getExternalStorageDirectory()+File.separator+ "A_level");
File dir2;
if (dir.exists() && dir.isDirectory()){
Log.e("tag out", ""+ dir);
}else {
dir.mkdir();
Log.e("tag out", "not exist");
}
File file = new File(dir, mTitle+".pdf");
try
{
Log.e("tag out", ""+ file);
out = new FileOutputStream(file);
in = new FileInputStream (new File(mPath));
Log.e("tag In", ""+ in);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag out", ""+ out);
Log.e("tag In", ""+ in);
Log.e("tag", e.getMessage());
Log.e("tag", ""+file);
Log.i("tag",""+sdcard.getAbsolutePath() + "A_level");
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
I have a PDF file stored in my assets. I want to load the PDF from my assets and read it in the app itself without using any 3rd party app to view.
I got the solution in this link. It works fine when selecting files from sdcard.
Following snippet might help you accessing files from asset folder and then open it:
private void ReadFromAssets()
{
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(getFilesDir(), "file.pdf");
try
{
in = assetManager.open("file.pdf");
out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag", e.getMessage());
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(
Uri.parse("file://" + getFilesDir() + "/file.pdf"),
"application/pdf");
startActivity(intent);
}
and copyFile method is as follows:
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
EDIT
For that purpose you'll have to use an ecternal library. It's explained quite well in the link below:
Render a PDF file using Java on Android
Hope this will help you.
Its better if you can open it using a webview
WebView web = (WebView) findViewById(R.id.webView1);
web.loadUrl("file:///android_asset/yourpdf.pdf");
Hope it works.
Ooops just now I checked, the pdf cannot be loaded in the web view
Sorry
File file = new File("android.resource://com.baltech.PdfReader/assets/raw/"+filename);
if (file.exists()) {
Uri targetUri = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(targetUri, "application/pdf");
try {
startActivity(intent);
}
catch (ActivityNotFoundException e) {
Toast.makeText(PdfReaderActivity.this, "No Application Available to View PDF", Toast.LENGTH_SHORT).show();
}
i want to read .pdf file which is in assets folder. what path i hav to give in filename. plz help. Thanks
I'm not sure if you got an answer to this already, seems pretty old, but this worked for me.
//you need to copy the input stream to a new file, so store it elsewhere
//this stores it to the sdcard in a new folder "MyApp"
String filename = Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyApp/solicitation_form.pdf";
AssetManager assetManager = getAssets();
try {
InputStream pdfFileStream = assetManager.open("solicitation_form.pdf");
CreateFileFromInputStream(pdfFileStream, filename);
} catch (IOException e1) {
e1.printStackTrace();
}
File pdfFile = new File(filename);
The CreateFileFromInputStream function is as follows
public void CreateFileFromInputStream(InputStream inStream, String path) throws IOException {
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(new File(path));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
inStream.close();
out.flush();
out.close();
}
Really hope this helps anyone else who reads this.
File file = new File("file:///android_asset/raw/"+filename);
replace the above line with below and try..
File file = new File("android.resource://com.com.com/raw/"+filename);
and place your PDF file raw folder instead of asset. Also change com.com.com with your package name.
Since assets files are stored inside apk file, there is no absolute path of the assets folder.
You might use a workaround creating a new file used as a buffer.
You should use AssetManager:
AssetManager mngr = getAssets();
InputStream ip = mngr.open(<filename in the assets folder>);
File assetFile = createFileFromInputStream(ip);
private File createFileFromInputStream(InputStream ip);
try{
File f=new File(<filename>);
OutputStream out=new FileOutputStream(f);
byte buf[]=new byte[1024];
int len;
while((len=inputStream.read(buf))>0)
out.write(buf,0,len);
out.close();
inputStream.close();
}catch (IOException e){}
}
}
Official facebook App has a bug, when you try to share an image with share intent, the image gets deleted from the sdcard. This is the way you have to pass the image to facebook app using the uri of the image:
File myFile= new File(Environment.getExternalStorageDirectory(), "car.jpg");
Uri uri = Uri.fromFile(myFile);
i.putExtra(Intent.EXTRA_STREAM, uri);
Then, suppose that if i create a copy from the original myFile object, and i pass the uri of the copy to facebook app, then, my original image will not be deleted.
I tried with this code, but it doesn't work, the original image file is still getting deleted:
File myFile= new File(Environment.getExternalStorageDirectory(), "car.jpg");
File auxFile=myFile.getAbsoluteFile();
Uri uri = Uri.fromFile(auxFile);
Can someone tell me how to do a exact copy of a file that doesn't redirect to the original File?
Please check: Android file copy
The file is copied byte by byte so no reference to the old file is maintained.
Here, this should be able to create a copy of your file:
private void CopyFile() {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(<file path>);
out = new FileOutputStream(<output path>);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(Exception e) {
Log.e("tag", e.getMessage());
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}