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(); }
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.
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.
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.
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>
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With