Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android download PDF from URL then open it with a PDF reader

I am trying to write an app to download PDFs from a URL, store them on SD, then open by Adobe PDF reader or other apps (which ever is able to open the PDF).

Until now, I had "successfully downloaded and stored it on SD card" (but every time when I try to open the PDF with a PDF reader, the reader crashes and says an unexpected error occurs), for example, http://maven.apache.org/maven-1.x/maven.pdf

Here is the code for my downloader:

//........code set ui stuff //........code set ui stuff      new DownloadFile().execute(fileUrl, fileName);    private class DownloadFile extends AsyncTask<String, Void, Void>{          @Override         protected Void doInBackground(String... strings) {             String fileUrl = strings[0];   // -> http://maven.apache.org/maven-1.x/maven.pdf             String fileName = strings[1];  // -> maven.pdf             String extStorageDirectory = Environment.getExternalStorageDirectory().toString();             File folder = new File(extStorageDirectory, "testthreepdf");             folder.mkdir();              File pdfFile = new File(folder, fileName);              try{                 pdfFile.createNewFile();             }catch (IOException e){                 e.printStackTrace();             }             FileDownloader.downloadFile(fileUrl, pdfFile);             return null;         }     }    public class FileDownloader {     private static final int  MEGABYTE = 1024 * 1024;      public static void downloadFile(String fileUrl, File directory){         try {              URL url = new URL(fileUrl);             HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();             urlConnection.setRequestMethod("GET");             urlConnection.setDoOutput(true);             urlConnection.connect();              InputStream inputStream = urlConnection.getInputStream();             FileOutputStream fileOutputStream = new FileOutputStream(directory);             int totalSize = urlConnection.getContentLength();              byte[] buffer = new byte[MEGABYTE];             int bufferLength = 0;             while((bufferLength = inputStream.read(buffer))>0 ){                 fileOutputStream.write(buffer, 0, bufferLength);             }             fileOutputStream.close();         } catch (FileNotFoundException e) {             e.printStackTrace();         } catch (MalformedURLException e) {             e.printStackTrace();         } catch (IOException e) {             e.printStackTrace();         }     } } 

In debug mode, I can see the app downloaded it and stored this PDF on /storage/sdcard/testpdf/maven.pdf. However, I guess the file may be corrupted somehow during downloading, so it doesn't open up properly...

Here is the code how I intend to open it with another reader app:

File pdfFile = new File(Environment.getExternalStorageDirectory() + "/testthreepdf/" + fileName);  // -> filename = maven.pdf                     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(documentActivity, "No Application available to view PDF", Toast.LENGTH_SHORT).show();                     } 
like image 638
sefirosu Avatar asked Jul 14 '14 15:07

sefirosu


People also ask

How do I make a PDF link open instead of downloading?

Click “Site Settings” on the right. Scroll down in Site Settings and click “Additional content settings” at the very bottom. In the expanded menu, select “PDF documents.” Toggle on the “Download PDF files instead of automatically opening them in Chrome” option.

Why can't I open downloaded PDF files on my Android phone?

To fix a PDF file not opening in Adobe reader, you will need to download the latest version of Adobe Reader. After which you will disable the protected mode that comes with it by default. Once this is changed, the issue of the PDF file not opening in Adobe reader will be resolved.


2 Answers

Hi the problem is in FileDownloader class

 urlConnection.setRequestMethod("GET");     urlConnection.setDoOutput(true); 

You need to remove the above two lines and everything will work fine. Please mark the question as answered if it is working as expected.

Latest solution for the same problem is updated Android PDF Write / Read using Android 9 (API level 28)

Attaching the working code with screenshots.

enter image description here

enter image description here

MainActivity.java

package com.example.downloadread;  import java.io.File; import java.io.IOException;  import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.view.Menu; import android.view.View; import android.widget.Toast;  public class MainActivity extends Activity {      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);     }      @Override     public boolean onCreateOptionsMenu(Menu menu) {         // Inflate the menu; this adds items to the action bar if it is present.         getMenuInflater().inflate(R.menu.main, menu);         return true;     }      public void download(View v)     {         new DownloadFile().execute("http://maven.apache.org/maven-1.x/maven.pdf", "maven.pdf");      }      public void view(View v)     {         File pdfFile = new File(Environment.getExternalStorageDirectory() + "/testthreepdf/" + "maven.pdf");  // -> filename = maven.pdf         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(MainActivity.this, "No Application available to view PDF", Toast.LENGTH_SHORT).show();         }     }      private class DownloadFile extends AsyncTask<String, Void, Void>{          @Override         protected Void doInBackground(String... strings) {             String fileUrl = strings[0];   // -> http://maven.apache.org/maven-1.x/maven.pdf             String fileName = strings[1];  // -> maven.pdf             String extStorageDirectory = Environment.getExternalStorageDirectory().toString();             File folder = new File(extStorageDirectory, "testthreepdf");             folder.mkdir();              File pdfFile = new File(folder, fileName);              try{                 pdfFile.createNewFile();             }catch (IOException e){                 e.printStackTrace();             }             FileDownloader.downloadFile(fileUrl, pdfFile);             return null;         }     }   } 

FileDownloader.java

package com.example.downloadread;  import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL;  public class FileDownloader {     private static final int  MEGABYTE = 1024 * 1024;      public static void downloadFile(String fileUrl, File directory){         try {              URL url = new URL(fileUrl);             HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();             //urlConnection.setRequestMethod("GET");             //urlConnection.setDoOutput(true);             urlConnection.connect();              InputStream inputStream = urlConnection.getInputStream();             FileOutputStream fileOutputStream = new FileOutputStream(directory);             int totalSize = urlConnection.getContentLength();              byte[] buffer = new byte[MEGABYTE];             int bufferLength = 0;             while((bufferLength = inputStream.read(buffer))>0 ){                 fileOutputStream.write(buffer, 0, bufferLength);             }             fileOutputStream.close();         } catch (FileNotFoundException e) {             e.printStackTrace();         } catch (MalformedURLException e) {             e.printStackTrace();         } catch (IOException e) {             e.printStackTrace();         }     } } 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"     package="com.example.downloadread"     android:versionCode="1"     android:versionName="1.0" >      <uses-sdk         android:minSdkVersion="14"         android:targetSdkVersion="18" />     <uses-permission android:name="android.permission.INTERNET"></uses-permission>     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>     <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>     <application         android:allowBackup="true"         android:icon="@drawable/ic_launcher"         android:label="@string/app_name"         android:theme="@style/AppTheme" >         <activity             android:name="com.example.downloadread.MainActivity"             android:label="@string/app_name" >             <intent-filter>                 <action android:name="android.intent.action.MAIN" />                  <category android:name="android.intent.category.LAUNCHER" />             </intent-filter>         </activity>     </application>  </manifest> 

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:paddingBottom="@dimen/activity_vertical_margin"     android:paddingLeft="@dimen/activity_horizontal_margin"     android:paddingRight="@dimen/activity_horizontal_margin"     android:paddingTop="@dimen/activity_vertical_margin"     tools:context=".MainActivity" >      <Button         android:id="@+id/button1"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_alignParentLeft="true"         android:layout_alignParentTop="true"         android:layout_marginTop="15dp"         android:text="download"         android:onClick="download" />      <Button         android:id="@+id/button2"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_alignParentLeft="true"         android:layout_alignParentRight="true"         android:layout_below="@+id/button1"         android:layout_marginTop="38dp"         android:text="view"         android:onClick="view" />  </RelativeLayout> 
like image 67
Zack Dawood Avatar answered Oct 16 '22 11:10

Zack Dawood


This is the best method to download and view PDF file.You can just call it from anywhere as like

PDFTools.showPDFUrl(context, url);

here below put the code. It will works fine

public class PDFTools { private static final String TAG = "PDFTools"; private static final String GOOGLE_DRIVE_PDF_READER_PREFIX = "http://drive.google.com/viewer?url="; private static final String PDF_MIME_TYPE = "application/pdf"; private static final String HTML_MIME_TYPE = "text/html";   public static void showPDFUrl(final Context context, final String pdfUrl ) {     if ( isPDFSupported( context ) ) {         downloadAndOpenPDF(context, pdfUrl);     } else {         askToOpenPDFThroughGoogleDrive( context, pdfUrl );     } }   @TargetApi(Build.VERSION_CODES.GINGERBREAD) public static void downloadAndOpenPDF(final Context context, final String pdfUrl) {     // Get filename     //final String filename = pdfUrl.substring( pdfUrl.lastIndexOf( "/" ) + 1 );     String filename = "";     try {         filename = new GetFileInfo().execute(pdfUrl).get();     } catch (InterruptedException e) {         e.printStackTrace();     } catch (ExecutionException e) {         e.printStackTrace();     }     // The place where the downloaded PDF file will be put     final File tempFile = new File( context.getExternalFilesDir( Environment.DIRECTORY_DOWNLOADS ), filename );     Log.e(TAG,"File Path:"+tempFile);     if ( tempFile.exists() ) {         // If we have downloaded the file before, just go ahead and show it.         openPDF( context, Uri.fromFile( tempFile ) );         return;     }      // Show progress dialog while downloading     final ProgressDialog progress = ProgressDialog.show( context, context.getString( R.string.pdf_show_local_progress_title ), context.getString( R.string.pdf_show_local_progress_content ), true );      // Create the download request     DownloadManager.Request r = new DownloadManager.Request( Uri.parse( pdfUrl ) );     r.setDestinationInExternalFilesDir( context, Environment.DIRECTORY_DOWNLOADS, filename );     final DownloadManager dm = (DownloadManager) context.getSystemService( Context.DOWNLOAD_SERVICE );     BroadcastReceiver onComplete = new BroadcastReceiver() {         @Override         public void onReceive(Context context, Intent intent) {             if ( !progress.isShowing() ) {                 return;             }             context.unregisterReceiver( this );              progress.dismiss();             long downloadId = intent.getLongExtra( DownloadManager.EXTRA_DOWNLOAD_ID, -1 );             Cursor c = dm.query( new DownloadManager.Query().setFilterById( downloadId ) );              if ( c.moveToFirst() ) {                 int status = c.getInt( c.getColumnIndex( DownloadManager.COLUMN_STATUS ) );                 if ( status == DownloadManager.STATUS_SUCCESSFUL ) {                     openPDF( context, Uri.fromFile( tempFile ) );                 }             }             c.close();         }     };     context.registerReceiver( onComplete, new IntentFilter( DownloadManager.ACTION_DOWNLOAD_COMPLETE ) );      // Enqueue the request     dm.enqueue( r ); }   public static void askToOpenPDFThroughGoogleDrive( final Context context, final String pdfUrl ) {     new AlertDialog.Builder( context )             .setTitle( R.string.pdf_show_online_dialog_title )             .setMessage( R.string.pdf_show_online_dialog_question )             .setNegativeButton( R.string.pdf_show_online_dialog_button_no, null )             .setPositiveButton( R.string.pdf_show_online_dialog_button_yes, new DialogInterface.OnClickListener() {                 @Override                 public void onClick(DialogInterface dialog, int which) {                     openPDFThroughGoogleDrive(context, pdfUrl);                 }             })             .show(); }  public static void openPDFThroughGoogleDrive(final Context context, final String pdfUrl) {     Intent i = new Intent( Intent.ACTION_VIEW );     i.setDataAndType(Uri.parse(GOOGLE_DRIVE_PDF_READER_PREFIX + pdfUrl ), HTML_MIME_TYPE );     context.startActivity( i ); }  public static final void openPDF(Context context, Uri localUri ) {     Intent i = new Intent( Intent.ACTION_VIEW );     i.setDataAndType( localUri, PDF_MIME_TYPE );     context.startActivity( i ); }  public static boolean isPDFSupported( Context context ) {     Intent i = new Intent( Intent.ACTION_VIEW );     final File tempFile = new File( context.getExternalFilesDir( Environment.DIRECTORY_DOWNLOADS ), "test.pdf" );     i.setDataAndType( Uri.fromFile( tempFile ), PDF_MIME_TYPE );     return context.getPackageManager().queryIntentActivities( i, PackageManager.MATCH_DEFAULT_ONLY ).size() > 0; }  // get File name from url static class GetFileInfo extends AsyncTask<String, Integer, String> {     protected String doInBackground(String... urls)     {         URL url;         String filename = null;         try {             url = new URL(urls[0]);             HttpURLConnection conn = (HttpURLConnection) url.openConnection();             conn.connect();             conn.setInstanceFollowRedirects(false);             if(conn.getHeaderField("Content-Disposition")!=null){                 String depo = conn.getHeaderField("Content-Disposition");                  String depoSplit[] = depo.split("filename=");                 filename = depoSplit[1].replace("filename=", "").replace("\"", "").trim();             }else{                 filename = "download.pdf";             }         } catch (MalformedURLException e1) {             e1.printStackTrace();         } catch (IOException e) {         }         return filename;     }      @Override     protected void onPreExecute() {         super.onPreExecute();     }     @Override     protected void onPostExecute(String result) {         super.onPostExecute(result);         // use result as file name     } } 

}

try it. it will works, enjoy

like image 25
Jijo Avatar answered Oct 16 '22 12:10

Jijo