0

I'm trying to download file from server here when i download small .png files they get downloaded successfully without any problem but when it comes to downloading large files my app is crashing with illegal argument exception stating that set percentage is not between 0 and 100.

Here is the error log which i'm getting:

java.lang.IllegalArgumentException: setPercentage not between 0 and 100
        at is.arontibo.library.ProgressDownloadView.setPercentage(ProgressDownloadView.java:253)
        at is.arontibo.library.ElasticDownloadView.setProgress(ElasticDownloadView.java:86)
        at com.kitelytech.pmsapp.adapter.Filelistadapter$DownloadFile.onProgressUpdate(Filelistadapter.java:244)
        at com.kitelytech.pmsapp.adapter.Filelistadapter$DownloadFile.onProgressUpdate(Filelistadapter.java:150)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:715)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:171)
        at android.app.ActivityThread.main(ActivityThread.java:6651)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)

Here is my java class Note: To make it easy to understand i'm giving only the necessary portion as this is a adapter class which having a seperate download file class to support file download.

public class DownloadFile extends AsyncTask<String, String, String> {
        ElasticDownloadView mElasticDownloadView;
        private String fileName;
        public Activity fContext;
        private String folder;
        private boolean isDownloaded;


        public DownloadFile(Activity activity) {
            this.fContext = activity;
        }


        /**
         * Before starting background thread
         * Show Progress Bar Dialog
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mElasticDownloadView = fContext.findViewById(R.id.elastic_download_view);
            mElasticDownloadView.startIntro();
        }

        /**
         * Downloading file in background thread
         */
        @Override
        protected String doInBackground(String... f_url) {
            int count;
            try {
                URL url = new URL(f_url[0]);
                URLConnection connection = url.openConnection();
                connection.connect();
                // getting file length
                int lengthOfFile = connection.getContentLength();


                // input stream to read file - with 8k buffer
                InputStream input = new BufferedInputStream(url.openStream(), 8192);

                String timestamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());

                //Extract file name from URL
                fileName = f_url[0].substring(f_url[0].lastIndexOf('/') + 1, f_url[0].length());

                //Append timestamp to file name
                fileName = timestamp + "_" + fileName;

                //External directory path to save file
                folder = Environment.getExternalStorageDirectory() + File.separator + "pms/";
                //Create pms folder if it does not exist
                File directory = new File(folder);

                if (!directory.exists()) {
                    directory.mkdirs();
                }

                // Output stream to write file
                OutputStream output = new FileOutputStream(folder + 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) / lengthOfFile));


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

                // flushing output
                output.flush();

                // closing streams
                output.close();
                input.close();
            } catch (Exception e) {
                Log.e("Error: ", e.getMessage());
            }
            return "Something went wrong";
        }

        /**
         * Updating progress bar
         */
        protected void onProgressUpdate(String... progress) {
            // setting progress percentage
            mElasticDownloadView = fContext.findViewById(R.id.elastic_download_view);
            mElasticDownloadView.setProgress(Integer.parseInt(progress[0]));
        }


        @Override
        protected void onPostExecute(String message) {
            // dismiss the dialog after the file was downloaded
            mElasticDownloadView = fContext.findViewById(R.id.elastic_download_view);
            this.mElasticDownloadView.success();

          //New Approach using fileprovider use if android version is nougat or higher
            File toInstall = new File(folder, fileName );
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                Uri apkUri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".provider", toInstall);
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(apkUri);
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                mContext.startActivity(intent);
            } else {
                Uri apkUri = Uri.fromFile(toInstall);
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(apkUri, "*/*");
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                mContext.startActivity(intent);
            }
        }
    }

1 Answers1

0

From https://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#getContentLength()

public int getContentLength()
Returns the value of the content-length header field.
Note: getContentLengthLong() should be preferred over this method, since it returns a long instead and is therefore more portable.
Returns:
the content length of the resource that this connection's URL references, -1 if the content length is not known, or if the content length is greater than Integer.MAX_VALUE.

As you can see getContentLength() for large files could return -1 and maybe this is the source of your problem.
Maybe you should try: getContentLengthLong()
But there are cases that the length is not known.
In such case you can' show the exact progress of the process so use an infinite progress bar.

forpas
  • 160,666
  • 10
  • 38
  • 76