8

I'm searching on the web how to open pdf file from server with default pdf viewer on android. What I found is download the file first then start it in intent or load it with google docs. I don't want to do all these. I just want to load it directly from server in default pdf viewer from phone. I've tried opening video url with intent and it worked. But opening pdf url with intent is not working. Below is my code;

private void openFilePDF(){
        try{
            Toast.makeText(getBaseContext(), "Opening PDF... ", Toast.LENGTH_SHORT).show();
            Intent inte = new Intent(Intent.ACTION_VIEW);
            inte.setDataAndType(
                    Uri.parse("http://122.248.233.68/pvfiles/Guide-2.pdf"),
                    "application/pdf");

            startActivity(inte);
            }catch(ActivityNotFoundException e){
                Log.e("Viewer not installed on your device.", e.getMessage());
            }
    }

Is there any way that I can load pdf url in intent?

ksh
  • 141
  • 1
  • 3
  • 16

4 Answers4

17

First Create a downloader class

public class Downloader {

    public static void DownloadFile(String fileURL, File directory) {
        try {

            FileOutputStream f = new FileOutputStream(directory);
            URL u = new URL(fileURL);
            HttpURLConnection c = (HttpURLConnection) u.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();

            InputStream in = c.getInputStream();

            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = in.read(buffer)) > 0) {
                f.write(buffer, 0, len1);
            }
            f.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

After that create an activity which downloads the PDF file from internet,

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        String extStorageDirectory = Environment.getExternalStorageDirectory()
        .toString();
        File folder = new File(extStorageDirectory, "pdf");
        folder.mkdir();
        File file = new File(folder, "Read.pdf");
        try {
            file.createNewFile();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        Downloader.DownloadFile("http://122.248.233.68/pvfiles/Guide-2.pdf", file);

        showPdf();
    }
    public void showPdf()
        {
            File file = new File(Environment.getExternalStorageDirectory()+"/Mypdf/Read.pdf");
            PackageManager packageManager = getPackageManager();
            Intent testIntent = new Intent(Intent.ACTION_VIEW);
            testIntent.setType("application/pdf");
            List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            Uri uri = Uri.fromFile(file);
            intent.setDataAndType(uri, "application/pdf");
            startActivity(intent);
        }
}

Finally at last declare persmissions in AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
GrIsHu
  • 29,068
  • 10
  • 64
  • 102
  • @ksh Is your issue solved? Does any answer helped you or not ? – GrIsHu Feb 13 '14 at 06:16
  • Try out and then see. @AnandPrakash – GrIsHu Jul 05 '14 at 12:42
  • @ GrlsHu one more favor bro, can you suggest any api's for generating pdf from a set of data on Android(prior to 4.4) – Anand Prakash Jul 06 '14 at 16:18
  • @AnandPrakash Check out some articles to generate pdf in android 1) http://www.dynamicpdf.com/Blog/post/2012/06/15/Generating-PDFs-Dynamically-on-Android.aspx 2)http://www.aspose.com/android/pdf-component.aspx – GrIsHu Jul 07 '14 at 04:37
  • @GrlsHu What if there is no app installed for pdf. Is there any other way for that? thnx – Anand Prakash Jul 10 '14 at 06:03
  • 1
    @AnandPrakash If there won't be any pdf application then it will not work. As `Intent` will not find any application related to pdf file. Another way is you can directly show pdf in browser also. And if don't want to load in browser then you will have to go for 3rd party api for pdfviewer. – GrIsHu Jul 11 '14 at 16:35
  • this is giving me this error `No Activity found to handle Intent { act=android.intent.action.VIEW dat=file:///mnt/sdcard/Mypdf/Read.pdf typ=application/pdf }` – CIRCLE Mar 19 '15 at 16:21
8

You can try this using WebView:

public class MyPdfViewActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WebView mWebView=new WebView(MyPdfViewActivity.this);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.getSettings().setPluginsEnabled(true);
    mWebView.loadUrl("https://docs.google.com/gview?embedded=true&url="+LinkTo);
    setContentView(mWebView);
  }
}
Shailendra Madda
  • 20,649
  • 15
  • 100
  • 138
  • I know this is really old, but for completeness `setPluginsEnabled()` was deprecated in API level 9, and removed in API level 18. The newer version `setPluginState(WebSettings.PluginState.ON)` was added in API level 8 but deprecated in API level 18. Plugins are not supported beyond API level 18. – Lee Richardson Mar 09 '17 at 18:43
  • @LeeRichardson Thank you for your comment can you update the answer with the same.. – Shailendra Madda Mar 10 '17 at 07:26
  • This is most important to hit your downloadable PDF file URL bind with "https://docs.google.com/gview?embedded=true&url=" this.. – CrazyMind Jun 25 '17 at 07:19
0

According to me there is no way to directly open your PDF file on device. Because of browser properties of android devices when we try to open PDF file it download to device. There is only Two way to open the PDF file.

  1. You can use PDF application Intent to choose app to open file with.

  2. You can append your server url for file with Google docs url and can open it in browser so ur PDF file will open in browser

Vaibhav Agarwal
  • 4,499
  • 3
  • 19
  • 20
  • Thanks for your reply. But pdf app intent can only open local files. It cannot load the files from server. – ksh Dec 16 '13 at 05:21
  • yeah you have to download file to the device and after that you can use intent to open that particular file – Vaibhav Agarwal Dec 16 '13 at 05:22
0

Download Pdf file from server and once download completed you can open this pdf file using pending intent.

Before you go to code just see below image which show functionality of my attach code.

enter image description here enter image description here enter image description here enter image description here

Step - 1: You need to create on Asynchronous task to download file from server url. See below code :

public class DownloadFileFromURL extends AsyncTask<String, Integer, String> {

private NotificationManager mNotifyManager;
private NotificationCompat.Builder build;
private File fileurl;
int id = 123;
OutputStream output;
private Context context;
private String selectedDate;
private String ts = "";

public DownloadFileFromURL(Context context, String selectedDate) {
    this.context = context;
    this.selectedDate = selectedDate;

}

protected void onPreExecute() {
    super.onPreExecute();

    mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    build = new NotificationCompat.Builder(context);
    build.setContentTitle("Download")
            .setContentText("Download in progress")
            .setChannelId(id + "")
            .setAutoCancel(false)
            .setDefaults(0)
            .setSmallIcon(R.drawable.ic_menu_download);

    // Since android Oreo notification channel is needed.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(id + "",
                "Social Media Downloader",
                NotificationManager.IMPORTANCE_HIGH);
        channel.setDescription("no sound");
        channel.setSound(null, null);
        channel.enableLights(false);
        channel.setLightColor(Color.BLUE);
        channel.enableVibration(false);
        mNotifyManager.createNotificationChannel(channel);

    }
    build.setProgress(100, 0, false);
    mNotifyManager.notify(id, build.build());
    String msg = "Download started";
    //CustomToast.showToast(context,msg);
}

@Override
protected String doInBackground(String... f_url) {
    int count;
    ts = selectedDate.split("T")[0];
    try {
        URL url = new URL(f_url[0]);
        URLConnection conection = url.openConnection();
        conection.connect();
        int lenghtOfFile = conection.getContentLength();

        InputStream input = new BufferedInputStream(url.openStream(),
                8192);
        // Output stream
        output = new FileOutputStream(Environment
                .getExternalStorageDirectory().toString()
                + Const.DownloadPath + ts + ".pdf");
        fileurl = new File(Environment.getExternalStorageDirectory()
                + Const.DownloadPath + ts + ".pdf");
        byte[] data = new byte[1024];

        long total = 0;

        while ((count = input.read(data)) != -1) {
            total += count;
            int cur = (int) ((total * 100) / lenghtOfFile);

            publishProgress(Math.min(cur, 100));
            if (Math.min(cur, 100) > 98) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    Log.d("Failure", "sleeping failure");
                }
            }
            Log.i("currentProgress", "currentProgress: " + Math.min(cur, 100) + "\n " + cur);

            output.write(data, 0, count);
        }

        output.flush();

        output.close();
        input.close();

    } catch (Exception e) {
        Log.e("Error: ", e.getMessage());
    }

    return null;
}

protected void onProgressUpdate(Integer... progress) {
    build.setProgress(100, progress[0], false);
    mNotifyManager.notify(id, build.build());
    super.onProgressUpdate(progress);
}

@Override
protected void onPostExecute(String file_url) {
    build.setContentText("Download complete");
    Intent intent = new Intent(context, DownloadBroadcastReceiver.class);
    Uri finalurl = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", fileurl);
    intent.putExtra("currenturl", finalurl.toString());
    intent.putExtra("selectedfilename", ts);
    context.sendBroadcast(intent);
    build.setProgress(0, 0, false);
    mNotifyManager.notify(id, build.build());
} }

Here in Above code i create asynctask using DownloadFileFromURL.java class file. here in this class file write a code to displat notification in android O and older version.

Step -2: Once your download completed i send it to broadcast receiver. With the help of broadcast receiver you can open your PDF file in pending intent easily. You can see broadcast receiver code onPostExecute method of asynchronous task.

See the below code to handle pending intent in broadcast receiver.

public class DownloadBroadcastReceiver extends BroadcastReceiver {
private NotificationManager mNotifyManager;
private NotificationCompat.Builder build;
private int rId=123;
private String localuri="";
private String selectedfilename="";

@Override
public void onReceive(Context context, Intent intent) {
    localuri=intent.getStringExtra("currenturl");
    selectedfilename=intent.getStringExtra("selectedfilename");
    startNotification(context,intent);
}

private void startNotification(Context context, Intent intent) {
    Log.e("fat", "startNotification: "+localuri );

    File fileurl = new File(Environment.getExternalStorageDirectory()
            + Const.DownloadPath + selectedfilename+".pdf");
    Uri finalurl = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID+".provider", fileurl);
    Intent downloadintent = new Intent(Intent.ACTION_VIEW);
    downloadintent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    downloadintent.setDataAndType(finalurl, "application/pdf");
    grantAllUriPermissions(context, downloadintent, finalurl);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, downloadintent,
            PendingIntent.FLAG_UPDATE_CURRENT);

    mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    build = new NotificationCompat.Builder(context);
    build.setContentTitle("Download Completed")
            .setContentText("Open Downloaded FIle")
            .setChannelId(rId+"")
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)
            .setStyle(new NotificationCompat.DecoratedCustomViewStyle())
            .setSmallIcon(R.drawable.ic_menu_download);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(rId+"" ,
                "Call Reminder",
                NotificationManager.IMPORTANCE_HIGH);
        channel.setDescription("With sound");
        channel.setSound(null,null);
        channel.enableLights(false);
        channel.setLightColor(Color.BLUE);
        channel.enableVibration(true);
        mNotifyManager.createNotificationChannel(channel);

    }


    mNotifyManager.notify(rId, build.build());

}

private void grantAllUriPermissions(Context context, Intent downloadintent, Uri finalurl) {
    List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(downloadintent, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        context.grantUriPermission(packageName, finalurl, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
} }

In above code you see that i added pending intent inside notification compact builder.

NOTE: when you add pending intent you have to assign access permission using below code which i already added.

 downloadintent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
 grantAllUriPermissions(context, downloadintent, finalurl);

Here GrantAllpermission method is created by which support in all device.

 private void grantAllUriPermissions(Context context, Intent downloadintent, Uri finalurl) {
    List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(downloadintent, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        context.grantUriPermission(packageName, finalurl, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
}

Step -3 : Add your Broadcast receiver in android Manifest file using below code.

 <receiver android:name=".services.DownloadBroadcastReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

Step - 4 : Also Add File Provider in Android Manifest File. With the help of File provider you can open file from your device storage.

  <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider_path" />
    </provider>

Note: if you face issue in Andorid 10(O) device than add below code in your application of android manifest file.

android:requestLegacyExternalStorage="true"

With the help of requestLegacyExternalStorage you can get list of downloaded file easily.

Step - 5: Now Last Step is call your Asynchronous class file in your on click event. Here i write code on pdf image click. To call Asynchronous task use below code.

 new DownloadFileFromURL(fContext,selectedDate).execute(currentResponse.getData());

Your can Download Above code Whole File From below link:

DownloadFileFromURL.java class file

DownloadBroadcastReceiver.java class file

Nimesh Patel
  • 1,394
  • 13
  • 26