0

I'm doing an asynctask to handle the download of a pdf generated by a ASPX web page, in-order to be opened by the pdf viewer of google or driver for example. Is the only way, If I pass the url directly to the pdf viewer, it can't handle it and it gives an error. So, I will show you my code.

public static class OpenPdfFromAspxUrl extends AsyncTask<Void, Integer, Boolean> {

        private Activity mActivity;
        private String fileUrl;
        private String FILENAME = "bmed_document.pdf";


        public OpenPdfFromAspxUrl(Activity activity, String fileURL) {
            this.mActivity = activity;
            this.fileUrl = fileURL;
        }

        /**
         * Before starting background thread
         * Show Progress Bar Dialog
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showProgressDialog(mActivity, mActivity.getResources().getString(R.string.common_getting_document), false);
        }

        /**
         * Downloading file in background thread
         */
        @Override
        protected Boolean doInBackground(Void... voids) {
            int count;

            try {
                URL u = new URL(fileUrl);
                HttpURLConnection c = (HttpURLConnection) u.openConnection();
                c.setRequestMethod("GET");
                c.setDoOutput(true);
                c.connect();

                // this will be useful so that you can show a tipical 0-100% progress bar
                int lenghtOfFile = c.getContentLength();

                // download the file
                InputStream input = new BufferedInputStream(u.openStream(), 8192);

                // Output stream
                OutputStream output = new FileOutputStream(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator + FILENAME);

                byte data[] = new byte[1024];

                long total = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....
                    // After this onProgressUpdate will be called
                    publishProgress((int) ((total * 100) / lenghtOfFile));

                    // writing data to file
                    output.write(data, 0, count);
                }

                // flushing output
                output.flush();

                // closing streams
                output.close();
                input.close();

                return true;

            } catch (Exception e) {
                e.printStackTrace();
            }

            return false;
        }

        /**
         * Updating progress bar
         */
        protected void onProgressUpdate(Integer... progress) {
            mActivity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // setting progress percentage
                    if (getDialog() != null && getDialog().isShowing()) {
                        progressBarReference.setProgress(progress[0]);
                        tvProgressReference.setText(new StringBuilder().append("").append(progress[0]).append(" %").toString());
                    }
                }
            });

        }

        /**
         * After completing background task
         * Dismiss the progress dialog
         **/
        @Override
        protected void onPostExecute(Boolean stored) {
            // dismiss the dialog after the file was downloaded
            getDialog().dismiss();

            if(stored){
                // Displaying downloaded pdf
                File newFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator + FILENAME);

                Intent target = new Intent(Intent.ACTION_VIEW);
                target.setDataAndType(Uri.fromFile(newFile), "application/pdf");
                target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION);
                mActivity.startActivity(Intent.createChooser(target, mActivity.getResources().getString(R.string.common_open_with)));
            }else{
                showAlert(
                        mActivity,
                        mActivity.getResources().getString(R.string.common_error_inform),
                        mActivity.getResources().getString(R.string.common_error_getting_document),
                        false,
                        mActivity.getResources().getString(R.string.common_accept),
                        new OnSingleClickListener() {
                            @Override
                            public void onSingleClick(View v) {
                                getDialog().dismiss();
                            }
                        },
                        null,
                        null);
            }
        }

    }

It's failed in the next lines, when trying to update the progress:

progressBarReference.setProgress(progress[0]);
tvProgressReference.setText(new StringBuilder().append("").append(progress[0]).append(" %").toString());

The error is the next.

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

What is the problem?

Amir Dora.
  • 2,831
  • 4
  • 40
  • 61
Víctor Martín
  • 3,352
  • 7
  • 48
  • 94
  • I have this in my code mActivity.runOnUiThread(new Runnable() { ... it is not a duplicate. – Víctor Martín Aug 02 '18 at 07:07
  • 1
    `onProgressUpdate` is executed on main thread, so you don't need `mActivity.runOnUiThread` try to remove that is check if it helps – Lino Aug 02 '18 at 07:08

0 Answers0