Can't read PDF downloaded from server - android

I'm downloading a PDF from my server.
The server send me a HttpResponse with the InputStream of file's body.
I'm able to write it into a file but, when I try to read it with a PDF reader, it tells me that the file might be corrupted.
I've also noticed that the size of the PDF downloaded directly from web service is twice the size of the PDF downloaded via my application.
The code I use to download and write the PDF file is this:
String fileName = //FILENAME + ".pdf";
fileName = fileName.replaceAll("/", "_");
String extPath = Environment.getExternalStorageDirectory().toString();
String folderName = //FOLDERNAME;
try {
File folder = new File(extPath, folderName);
folder.mkdir();
File pdfFile = new File(folder, fileName);
pdfFile.createNewFile();
URL url = new URL(downloadURL);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(pdfFile);
byte[] buffer = new byte[MEGABYTE];
int bufferLength;
while((bufferLength = inputStream.read(buffer))>0 ){
fileOutputStream.write(buffer, 0, bufferLength);
}
fileOutputStream.close();
Uri path = Uri.fromFile(pdfFile);
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(pdfIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), "No Application available to view PDF", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
}
//otherStuff
Where I go wrong?
I've also noticed that inside the Headers of HttpResponse contains Content-type:text/html. It shoudld be something like text/pdf?

Your Downloading code seems correct. Based on that and on your comment:
I've also noticed that the size of the PDF downloaded directly from web service is twice the size of the PDF downloaded via my application."
I would suggest checking your URL. It appears that you might be downloading an html page instead of the pdf. To verify you are downloading correctly, change the download directory as follows:
//Default download directory
String extPath = Environment.DIRECTORY_DOWNLOADS;
And check the directory (via the file system, e.g. mount the phone to your computer or a file manager app) for the downloaded content to verify it is a pdf.

Related

How to read a pdf file from REST API using retrofit?

This is my json data coming from backend. How to read this Pdf file using Retofit library.
Thanks in Advance
{
"data": [
{
"Invoice": "Bhavdip-html-to-pdf (1).pdf"
}
]
}
You must first Download your pdf file with
Download Manager
after it, u can use this library for read it.
Library for read pdf in java
Notice :
you must take a url of your pdf in json
see
https://www.codexpedia.com/android/android-download-large-file-using-retrofit-streaming/
this is not a good scenario for large files .if your files are small you can use retrofit for downloading them but if your files are large you should use download manager for them.
above link help you for downloading file with retrofit.
URL url = new URL( f_url[0] );//pass you url here
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream( url.openStream(), 1024 );
// Output stream to write file
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File( extStorageDirectory );
String timeStamp = new SimpleDateFormat( "yyyyMMdd_HHmmss", Locale.getDefault() ).format( new Date() );
String fileName = "SMART_" + timeStamp + "_" + Brochure.substring( Brochure.lastIndexOf( '/' ) + 1 );
File file = new File( folder, fileName );
try {
file.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
OutputStream output = new FileOutputStream( file);
byte[] data = new byte[1024];
long total = 0;
while ((read( data )) != -1) {
// writing data to file
output.write( data, 0, count );
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e( "Error: ", e.getMessage() );
}
this is the way of download pdf file from the server

Android sharing image not working

I'm trying to share an image in an app I have made that downloads an Image and writes it to a file. But any time I try to share it, it says can't upload file or just does nothing. It's not coming up in the logcat so I'm kinda stuck for ideas on how to fix it.
The image that is downloaded is displayed in an image view like this
iView.setImageBitmap(im);
String path = ContentFromURL.Storage + "/temp.jpg";
File temp = new File(path);
uri = Uri.fromFile(temp);
iView.setImageURI(uri);
Asynch task to download file
HttpURLConnection connection;
try {
String url = params[0];
connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestProperty("Accept-Charset","UTF-8");
connection.connect();
InputStream input = connection.getInputStream();
image = BitmapFactory.decodeStream(input);
File temp = new File(Storage,"temp.jpg");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
FileOutputStream fo = new FileOutputStream(temp);
fo.write(bytes.toByteArray());
fo.close();
String path = temp.getAbsolutePath();
Log.d("Asynch", "image shuould exist");
SharePage.act.runOnUiThread(new Runnable()
{
public void run()
{
SharePage.setImage(image);
}
}
);
creating intent
twitterIntent = new Intent(Intent.ACTION_SEND);
twitterIntent.setClassName("com.twitter.android",packageName);
twitterIntent.setType("image/jpeg");
twitterIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(twitterIntent);
I know that I should use the built in android share thing but its not working either when I try to share the image
The problem was where I was trying to store the Image, I wanted to have it so that the user never saw the image and it was deleted when it wasn't needed anymore but the other apps didn't have access to the directory. So I have since moved it to the external storage directory.

how to open a pdf from specific URL in android

I am an iOS developer but have been tasked with updating our company's android apps also (so I have little android experience) The android app currently loads PDFs from raw and then displays them in another pdf reader application also installed on the android... however I would like to instead get the pdf's from the internet.
this is the code being using to show the pdf stored locally.
if (mExternalStorageAvailable==true && mExternalStorageWriteable==true)
{
// Create a path where we will place our private file on external
// storage.
Context context1 = getApplicationContext();
File file = new File(context1.getExternalFilesDir(null).toString() + "/pdf.pdf");
URL url = new URL("https://myurl/pdf.pdf");
URLConnection urlConnection = url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
OutputStream os = new FileOutputStream(file);
try {
byte[] data = new byte[in.available()];
in.read(data);
os.write(data);
Uri path = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(path, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
} catch (IOException e) {
// Unable to create file, likely because external storage is
// not currently mounted.
Log.w("ExternalStorage", "Error writing " + file, e);
Context context2 = getApplicationContext();
CharSequence text1 = "PDF File NOT Saved";
int duration1 = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context2, text1, duration1);
toast.show();
} finally {
in.close();
os.close();
}
}
Eventually the pdf's will come from a website and the website will require an HTML post request sent to it before the PDF can be downloaded. I think I will be able to figure out the HTML post, but for now how can I download a PDF from the internet and have it display. I tried changing the URI to point to the location but that didn't work, or I structured it incorrectly.
Also keep in mind for security reasons I do not want to display this using google viewer and a webview
You just need to read from a distant server. I'd try something like:
URL url = new URL("http://www.mydomain.com/slug");
URLConnection urlConnection = url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
try {
readStream(in); // Process your pdf
} finally {
in.close();
}
You may also want to checkout the AndroidHttpClient class to make http requests directly (GET or POST in your application).

How to download a file from a server and save it in specific folder in SD card in Android?

I have one requirement in my Android application. I need to download and save file in specific folder of SD card programmatically. I have developed source code, which is
String DownloadUrl = "http://myexample.com/android/";
String fileName = "myclock_db.db";
DownloadDatabase(DownloadUrl,fileName);
// and the method is
public void DownloadDatabase(String DownloadUrl, String fileName) {
try {
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File(root.getAbsolutePath() + "/myclock/databases");
if(dir.exists() == false){
dir.mkdirs();
}
URL url = new URL("http://myexample.com/android/");
File file = new File(dir,fileName);
long startTime = System.currentTimeMillis();
Log.d("DownloadManager" , "download url:" +url);
Log.d("DownloadManager" , "download file name:" + fileName);
URLConnection uconn = url.openConnection();
uconn.setReadTimeout(TIMEOUT_CONNECTION);
uconn.setConnectTimeout(TIMEOUT_SOCKET);
InputStream is = uconn.getInputStream();
BufferedInputStream bufferinstream = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(5000);
int current = 0;
while((current = bufferinstream.read()) != -1){
baf.append((byte) current);
}
FileOutputStream fos = new FileOutputStream( file);
fos.write(baf.toByteArray());
fos.flush();
fos.close();
Log.d("DownloadManager" , "download ready in" + ((System.currentTimeMillis() - startTime)/1000) + "sec");
int dotindex = fileName.lastIndexOf('.');
if(dotindex>=0){
fileName = fileName.substring(0,dotindex);
}
catch(IOException e) {
Log.d("DownloadManager" , "Error:" + e);
}
}
Now the issue is only empty file with filename myclock_db.db is saving in the path. but I need to download and save content of file in the specific folder. Tried several ways to get the file download, but I can't.
Your download URL is not a link to any file. It's a directory. Make sure its a file and exists. Also check your logcat window for error logs. One more suggestion, its always better to do a printStackTrace() in catch blocks instead of Logs. Its gives a more detailed view of the error.
Change this line:
URL url = new URL("http://myexample.com/android/");
to:
URL url = new URL("http://myexample.com/android/yourfilename.txt"); //some file url
Next, in catch block, add this line:
e.printStackTrace();
Also in the directory path, it should be something like this:
File dir = new File(root.getAbsolutePath() + "/mnt/sdcard/myclock/databases");
instead of
File dir = new File(root.getAbsolutePath() + "/myclock/databases");
Next, make sure you have acquired permission for writing to external storage in Android manifest.

How to read PDF file saved to internal storage of device?

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

Categories

Resources