Home » Android » android download pdf from url then open it with a pdf reader

android download pdf from url then open it with a pdf reader

Posted by: admin February 23, 2018 Leave a comment

Questions:

I am trying to write an app to download pdfs from url, store them on sd, then open by adobe pdf reader or other apps which ever able to open the pdf.

untill now, i had “successfully downloaded and stored it on Sd card” (but everytime when i try to open the pdf with a pdf reader, reader crash and say 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 store this pdf on /storage/sdcard/testpdf/maven.pdf, however, i guess the file may be corrupted somehow during downloading, so it doesnt open up properly…

here is the code how i intent to open it with other 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();
                    }
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.

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>

Questions:
Answers:

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

Questions:
Answers:

Download source code from here (Open Pdf from url in Android Programmatically)

MainActivity.java

package com.deepshikha.openpdf;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;

public class MainActivity extends AppCompatActivity {
    WebView webview;
    ProgressBar progressbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webview = (WebView)findViewById(R.id.webview);
        progressbar = (ProgressBar) findViewById(R.id.progressbar);
        webview.getSettings().setJavaScriptEnabled(true);
        String filename ="http://www3.nd.edu/~cpoellab/teaching/cse40816/android_tutorial.pdf";
        webview.loadUrl("http://docs.google.com/gview?embedded=true&url=" + filename);

        webview.setWebViewClient(new WebViewClient() {

            public void onPageFinished(WebView view, String url) {
                // do your stuff here
                progressbar.setVisibility(View.GONE);
            }
        });

    }
}

Thanks!