Android - 下载并打开Pdf

时间:2014-09-22 19:46:39

标签: android http pdf

我有一个应用程序,可以从listview点击监听器下载并打开pdf。

文件下载并保存到我的手机但文件大小为0字节,因此无法打开。我使用了http://www.coderzheaven.com/2013/03/06/download-pdf-file-open-android-installed-pdf-reader/中的教程代码。这是我的代码。任何帮助将不胜感激。

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

    }

}

2 个答案:

答案 0 :(得分:1)

有几件事:

也许添加超时?

暂时不要检查内容长度。

使用BufferedOutputStream

这样的事情:

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

答案 1 :(得分:0)

(包括logcat可能有助于更好地了解正在发生的事情)

一个可能的问题是:

fileOutput.close();

不确保将所有字节都写入磁盘。如果您在关闭流后立即尝试读取文件,则可能该文件尚未完全写入(特别是因为您的缓冲区很大)。

解决方案是在close()之后请求同步:

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

类似问题here