Without considering the use of webView:
Use intent to open an app that can use pdf
private void openPdfFile(String url) { Intent intent = new Intent("android.intent.action.VIEW"); intent.addCategory("android.intent.category.DEFAULT"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Uri uri = Uri.parse(url); intent.setDataAndType(uri, "application/pdf"); startActivity(Intent.createChooser(intent, "開啟PDF檔案")); }
google drive URL (if the file is too large, it cannot be previewed)
public void setDocumentPath(final String url) { WebView webView = (WebView) findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setPluginsEnabled(true); webView.loadUrl("https://docs.google.com/viewer?url="+url); }
third-party package
There are many similar projects on github, choose the one that is used by the most people
I choose this android pdf viewer
Step 1. Add two classes
- RetrivePDFfromUrl is AsyncTask.
- TaskCancel is responsible for deleting tasks after seconds to avoid excessive loading.
class RetrivePDFfromUrl extends AsyncTask<String, Void, InputStream> {
@Override
protected InputStream doInBackground(String... strings) {
InputStream inputStream = null;
try {
URL url = new URL(strings[0]);
HttpURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
if (urlConnection.getResponseCode() == 200) {
inputStream = new BufferedInputStream(urlConnection.getInputStream());
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
return inputStream;
}
@Override
protected void onPostExecute(InputStream inputStream) {
pdfView.fromStream(inputStream).onLoad(new OnLoadCompleteListener() {
@Override
public void loadComplete(int nbPages) {
mProgressBar.setVisibility(View.GONE);
}
}).load();
}
}
class TaskCanceler implements Runnable {
private AsyncTask task;
public TaskCanceler(AsyncTask task) {
this.task = task;
}
@Override
public void run() {
if (task.getStatus() == AsyncTask.Status.RUNNING) {
task.cancel(true);
pdfView.setVisibility(View.GONE);
mProgressBar.setVisibility(View.GONE);
Toast.makeText(getContext(), getResources().getText(R.string.error_message_timeout), Toast.LENGTH_LONG).show();
}
}
}
Step 2. This function is used in fragment onCreate().
private void fetchStoreFileUrl() {
mProgressBar.setVisibility(View.VISIBLE);
final PushMailAPI api = DataProvider.getInstance().getStoreFile();
if (api == null) {
return;
}
final String accessToken = AccountProvider.getInstance().getToken();
api.getStoreFileUrl(accessToken, new Callback<StoreFile>() {
@Override
public void success(StoreFile storeFile, Response response) {
String url = storeFile.getStoreUrl();
pdfView.setVisibility(View.VISIBLE);
handler = new Handler();
RetrivePDFfromUrl task = new RetrivePDFfromUrl();
taskCanceler = new TaskCanceler(task);
handler.postDelayed(taskCanceler, Constants.LOADING_TIME_LIMIT );
task.execute(url);
}
@Override
public void failure(RetrofitError error) {
mProgressBar.setVisibility(View.GONE);
new ErrorHandler(getActivity(), TAG) {
@Override
protected void onUnknownError(String code, String message, String description) {
super.onUnknownError(code, message, description);
}
}.handle(error);
}
});
}
Step 3.
Finally, add and delete taskCanceler in onDestroyView().
To prevent the task from continuing after the Fragment is destroyed.
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
if (taskCanceler != null && handler != null)
handler.removeCallbacks(taskCanceler);
}