ksh
ksh

Reputation: 141

Opening pdf file from server using android intent

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?

Upvotes: 8

Views: 36881

Answers (4)

Nimesh Patel
Nimesh Patel

Reputation: 1496

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

Upvotes: 0

Vaibhav Agarwal
Vaibhav Agarwal

Reputation: 4499

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

Upvotes: 0

Shailendra Madda
Shailendra Madda

Reputation: 21551

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

Upvotes: 8

GrIsHu
GrIsHu

Reputation: 23638

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"/>

Upvotes: 17

Related Questions