简体   繁体   中英

Android - Download and Open Pdf

I have a application that downloads and opens a pdf from a listview click listener.

A file downloads and save to my phone but it has a file size of 0 bytes therefore It can not open. I Used tutorial code from http://www.coderzheaven.com/2013/03/06/download-pdf-file-open-android-installed-pdf-reader/ Here is my code. Any help will be greatly appreciated.

public class OpenPdfActivity extends Activity {

    TextView tv_loading;
    String dest_file_path = "pdf-test.pdf";
    int downloadedSize = 0, totalsize;
    String download_file_url = "http://www.education.gov.yk.ca/pdf/pdf-test.pdf";
    float per = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tv_loading = new TextView(this);
        setContentView(tv_loading);
        tv_loading.setGravity(Gravity.CENTER);
        tv_loading.setTypeface(null, Typeface.BOLD);
        downloadAndOpenPDF();
    }

    void downloadAndOpenPDF() {
        new Thread(new Runnable() {
            public void run() {
                Uri path = Uri.fromFile(downloadFile(download_file_url));
                try {
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setDataAndType(path, "application/pdf");
                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(intent);
                    finish();
                } catch (ActivityNotFoundException e) {
                    tv_loading
                            .setError("PDF Reader application is not installed in your device");
                }
            }
        }).start();

    }

    File downloadFile(String dwnload_file_path) {
        File file = null;
        try {

            URL url = new URL(dwnload_file_path);
            HttpURLConnection urlConnection = (HttpURLConnection) url
                    .openConnection();

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

            // connect
            urlConnection.connect();

            // set the path where we want to save the file
            File SDCardRoot = Environment.getExternalStorageDirectory();
            // create a new file, to save the downloaded file
            file = new File(SDCardRoot, dest_file_path);

            FileOutputStream fileOutput = new FileOutputStream(file);

            // Stream used for reading the data from the internet
            InputStream inputStream = urlConnection.getInputStream();

            // this is the total size of the file which we are
            // downloading
            totalsize = urlConnection.getContentLength();
            setText("Starting PDF download...");

            // create a buffer...
            byte[] buffer = new byte[1024 * 1024];  
            int bufferLength = 0;

            while ((bufferLength = inputStream.read(buffer)) > 0) {
                fileOutput.write(buffer, 0, bufferLength);
                downloadedSize += bufferLength;
                per = ((float) downloadedSize / totalsize) * 100;
                setText("Total PDF File size  : "
                        + (totalsize / 1024)
                        + " KB\n\nDownloading PDF " + (int) per
                        + "% complete");
            }
            // close the output stream when complete //
            fileOutput.close();
            setText("Download Complete. Open PDF Application installed in the device.");

        } catch (final MalformedURLException e) {
            setTextError("Some error occured. Press back and try again.",
                    Color.RED);
        } catch (final IOException e) {
            setTextError("Some error occured. Press back and try again.",
                    Color.RED);
        } catch (final Exception e) {
            setTextError(
                    "Failed to download image. Please check your internet connection.",
                    Color.RED);
        }
        return file;
    }

    void setTextError(final String message, final int color) {
        runOnUiThread(new Runnable() {
            public void run() {
                tv_loading.setTextColor(color);
                tv_loading.setText(message);
            }
        });

    }

    void setText(final String txt) {
        runOnUiThread(new Runnable() {
            public void run() {
                tv_loading.setText(txt);
            }
        });

    }

}

A couple of things:

Maybe add a timeout?

Try to NOT check the content length for now.

Use BufferedOutputStream

Something like this:

FileOutputStream fos = new FileOutputStream(file); 
BufferedOutputStream out = new BufferedOutputStream( fos);

try {
HttpURLConnection urlConnection = (HttpURLConnection) url
                    .openConnection();
 urlConnection.setRequestMethod("GET"); 
 urlConnection.setReadTimeout( 15000); 
 urlConnection.connect();

try { 
      InputStream in = urlConnection.getInputStream(); 
      byte[] buffer = new byte[1024 * 1024]; 
      int len = 0; 

      while (( len = in.read( buffer)) > 0) 
      { 
        out.write( buffer, 0, len); 
      } 
      out.flush(); 
    } finally { 
      fos.getFD(). sync(); 
      out.close(); 
    }





} catch (IOException eio) {
 Log.e("Download Tag", "Exception in download", eio);
}

(Including the logcat may help to have a better idea of what's going on)

One possible issue is this :

fileOutput.close();

don't ensure that all bytes are written to the disk. If you try to read the file immediately after closing the stream, it's possible that the file is not totally written yet (especially because your buffer is big).

The solution is to request a sync after the close():

 fileOutput.close();
 fileOutput.getFD().sync();

similar question here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM