Android- download file + status bar notification slowing down phone

后端 未结 4 1575
难免孤独
难免孤独 2021-02-10 06:22

I currently have an asynctask which downloads a mp3 from a server. When the user starts to download it, a status bar notification is created. This displays the prog

4条回答
  •  再見小時候
    2021-02-10 06:54

    I had similar issue once, I solved it using CountDownTimer.

    Similar to how @superfell suggested, you can call progress update of AsyncTask regularly while downloading file. And call the Notification Manager only at specific interval.

    After calling start() of CountDownTimer, it will call onTick() function after every fixed interval of time, and will call onFinish() either when timer is timed out or when called explicitly. cancel() function will only cancel the timer and will not call onFinish() method.

    class DownloadMaterial extends AsyncTask {
    
        CountDownTimer cdt;
        int id = i;
        NotificationManager mNotifyManager;
        NotificationCompat.Builder mBuilder;
    
        @Override
        protected void onPreExecute() {
            /**
             * Create custom Count Down Timer
             */
            cdt = new CountDownTimer(100 * 60 * 1000, 500) {
                public void onTick(long millisUntilFinished) {
                    mNotifyManager.notify(id, mBuilder.build());
                }
    
                public void onFinish() {
                    mNotifyManager.notify(id, mBuilder.build());
                }
            };
        }
    
        @Override
        protected String doInBackground(String... strings) {
            /**
             * Start timer to update Notification
             * Set Progress to 20 after connection
             * Build Notification
             * Increment Progress
             * Download and Save file
             */
            try {
                mNotifyManager =
                        (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                mBuilder = new NotificationCompat.Builder(context);
                mBuilder.setContentTitle("Downloading File")
                        .setContentText(file_name)
                        .setProgress(0, 100, false)
                        .setOngoing(true)
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setPriority(Notification.PRIORITY_LOW);
    
                // Initialize Objects here
                publishProgress("5");
                mNotifyManager.notify(id, mBuilder.build());
                cdt.start();
    
                // Create connection here
                publishProgress("20");
    
                // Download file here
                while ((count = input.read(data)) != -1) {
                    total += count;
                    publishProgress("" + (int) (20 + (total * 80 / fileLength)));
                    output.write(data, 0, count);
                }
            } catch (Exception e) {
                return "Failed";
            }
            return "Success";
        }
    
        @Override
        protected void onProgressUpdate(String... values) {
            /**
             * Update Download Progress
             */
            mBuilder.setContentInfo(values[0] + "%")
                    .setProgress(100, Integer.parseInt(values[0]), false);
        }
    
        @Override
        protected void onPostExecute(String s) {
    
            String title;
            if (s.equals("Success")) {
                title = "Downloaded";
            } else {
                title = "Error Occurred";
            }
            mBuilder.setContentTitle(title)
                    .setContentInfo("")
                    .setOngoing(false)
                    .setProgress(0, 0, false);
            cdt.onFinish();
            cdt.cancel();
        }
    }
    

    It is a good practice to call onFinish() first and then call cancel().

提交回复
热议问题