Android notification rebuilds instead of updating?

旧城冷巷雨未停 提交于 2019-12-24 07:28:10

问题


I'm downloading a file and i want to keep the user informed about the progress so i created a notification.The problem is that the notification keeps getting rebuild instead of updating. I searched for similar behaviours online and i did as they said but my problem persists.

Everybody is saying to use a notification builder so the first time it builds the whole notification and then only updates what i tell it to.Tried it,still not working.

Here i'm declaring the notification and the notificationManager.

private NotificationCompat.Builder notification;
private NotificationManager notificationManager;

This is the method that creates the notification.DOWNLOAD_NOTIFICATION_ID is a final int with value 2

private void createDownloadNotification(){

        notificationManager = (NotificationManager) getSystemService(GuideSelected.this.NOTIFICATION_SERVICE);

            notification = new NotificationCompat.Builder(GuideSelected.this,CHANNEL_DOWNLOAD)
                    .setSmallIcon(android.R.drawable.stat_sys_download)  // here is the animated icon
                    .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), android.R.drawable.stat_sys_download))
                    .setContentTitle("title")
                    .setContentText("Download starting...")
                    .setStyle(new NotificationCompat.BigTextStyle())

                    //.setContentIntent(pendingIntent)
                    //la notifica si cancella da sola dopo che clicco
                    .setOngoing(true)
                    .setPriority(NotificationCompat.PRIORITY_LOW)
                    .setProgress(100,0,false);
            notificationManager.notify(DOWNLOAD_NOTIFICATION_ID,notification.build());
        }
}

This is the asynctask where i'm updating the notification

private class DownloadFile extends AsyncTask<String, String, String> {
        final Handler handler = new Handler();

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected String doInBackground(String... f_url) {
            int count;
           // HERE I'M CREATING THE NOTIFICATION
                createDownloadNotification();

        //DOWNLOADING STUFF....

        }

        // Updating progress bar

        protected void onProgressUpdate(String... progress) {

            // UPDATING IT EVERY 5% SO I DON't MAKE TOO MANY CALLS

            currentPercentage=Integer.parseInt(progress[0]);

                if (previousPercentage != currentPercentage && currentPercentage%5==0) {// line : 6
                    notification.setProgress(100,previousPercentage, false).setContentText(previousPercentage+"%").setSubText("Downloading...");
                    notificationManager.notify(DOWNLOAD_NOTIFICATION_ID, notification.build());
                    previousPercentage=currentPercentage;
                }

        }


        @Override
        protected void onPostExecute(String message) {

            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    notification.setProgress(0,0,false).setOngoing(false).setContentText("Download complete").setSubText(null);
                    notificationManager.notify(DOWNLOAD_NOTIFICATION_ID, notification.build());
                }
            }, 2000);


        }
    }

I just want the notification to update without rebuilding everytime, i can see it rebuilds from the animated download icon because it keeps restarting.

EDIT: Added the declaration of notification and notification manager.


回答1:


In your Activity

private NotificationCompat.Builder notification;
    private NotificationManager notificationManager;

    int DOWNLOAD_NOTIFICATION_ID = 232;
 private void createDownloadNotification(){


        notificationManager = (NotificationManager) getSystemService(MainActivity.this.NOTIFICATION_SERVICE);

        notification = new NotificationCompat.Builder(MainActivity.this,"download")
                .setSmallIcon(android.R.drawable.stat_sys_download)  // here is the animated icon
                .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), android.R.drawable.stat_sys_download))
                .setContentTitle("title")
                .setContentText("Download starting...")
                .setStyle(new NotificationCompat.BigTextStyle())

                //.setContentIntent(pendingIntent)
                //la notifica si cancella da sola dopo che clicco
                .setOngoing(true)
                .setPriority(NotificationCompat.PRIORITY_LOW)
                .setProgress(100,0,false);
        notificationManager.notify(DOWNLOAD_NOTIFICATION_ID,notification.build());
    }

now in your AsyncTask use it like

  class DownloadFile extends AsyncTask<String, String, String>
{
    final Handler handler = new Handler();
    int currentPercentage;
    int previousPercentage;
    @Override
    protected void onPreExecute()
    {
        super.onPreExecute();
        createDownloadNotification();
    }
    @Override
    protected String doInBackground(String... f_url)
    {
        // Dummy code for notificaion progress you can change it with download file logic.
        for (int i = 0; i < 100; i++)
        {
            try
            {
                Thread.sleep(50);
                publishProgress(i + ""); //publish the progress to update the progress of Notification.
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
        return "";
    }
    protected void onProgressUpdate(String... progress)
    {
        // UPDATING IT EVERY 5% SO I DON't MAKE TOO MANY CALLS
        currentPercentage = Integer.parseInt(progress[0]);

        if (previousPercentage != currentPercentage && currentPercentage % 5 == 0)
        {// line : 6
            notification.setProgress(100, previousPercentage, false).setContentText(previousPercentage + "%").setSubText("Downloading...");
            notificationManager.notify(DOWNLOAD_NOTIFICATION_ID, notification.build());
            previousPercentage = currentPercentage;
        }

    }
    @Override
    protected void onPostExecute(String message)
    {
        handler.postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                notification.setSmallIcon(android.R.drawable.stat_sys_download_done); //update the icon 
                notification.setProgress(0, 0, false).setOngoing(false).setContentText("Download complete").setSubText(null);
                notificationManager.notify(DOWNLOAD_NOTIFICATION_ID, notification.build());
            }
        }, 2000);
    }
}

Create you notification in PreExecute method, then in onBackGround Method just publish the progress.

Hope this will fix your issue




回答2:


In the end i solved it by using custom download intent service class which extends IntentService and when i'm updating the notification i'm controlling if the last % is different than the current one (since the updateProgress is called multiple times in a second) and i also added a timer so it only updates every 1.3 seconds (this is the time that the download icon aniamtion takes to complete) and in this way i finally achieved my goal and the notification doesn't continuously rebuild.

Here is how i'm updating the notification:



   while ((count = input.read(data)) != -1) {
                if (Constants.stopService) {
                    output.flush();
                    output.close();
                    input.close();
                    stopSelf();
                    return;
                }
                if (count != 0) {
                    total += count;

                    latestPercentDone = (int) Math.round(total / lengthOfFile * 100.0);
                    if (percentDone != latestPercentDone) {
                        percentDone = latestPercentDone;
                        if (SystemClock.elapsedRealtime() - mLastClickTime > 1300) { // 1000 = 1second
                            mLastClickTime = SystemClock.elapsedRealtime();
                            sendMessage(percentDone, idLesson);
                            notification.setProgress(100, percentDone, false);
                            notificationManager.notify(realNotificationID, notification.build());
                        }
                    }
                    output.write(data, 0, count);
                }
            }
            // flushing output
            output.flush();
            // closing streams
            output.close();
            input.close();




回答3:


https://developer.android.com/training/notify-user/build-notification#Updating

To update this notification after you've issued it, call NotificationManagerCompat.notify() again, passing it a notification with the same ID you used previously. If the previous notification has been dismissed, a new notification is created instead.

You can optionally call setOnlyAlertOnce() so your notification interupts the user (with sound, vibration, or visual clues) only the first time the notification appears and not for later updates.

        notification = new NotificationCompat.Builder(GuideSelected.this,CHANNEL_DOWNLOAD)
                .setSmallIcon(android.R.drawable.stat_sys_download)  // here is the animated icon
                .setContentTitle("title")
                .setContentText("Download starting...")
                .setPriority(NotificationCompat.PRIORITY_LOW);
        notificationManager.notify(DOWNLOAD_NOTIFICATION_ID, notification.build());

Should work to keep updating the same notification, once you have this working, I would then add back the other settings you had on the builder (such a bigIcon etc, too see if adding one of those is breaking it.)



来源:https://stackoverflow.com/questions/57169517/android-notification-rebuilds-instead-of-updating

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!