Android - updating notification progress bar, properly
Asked Answered
C

3

12

I am still really new to Android and I am trying to improve my notification's progress bar to be smoother, not fire a million updates to my Pebble and do it the "right way". This code works "fine" as in when I am using it, the notification draws and the progress bar completes as expected.

It became an issue to me when I set my Pebble watch to accept my app's notifications. Which causes it to vibrate about 50 times per image that uploads depending on how fast the upload speed is.

Being a beginner I assume I am doing this all wrong and there is a much better way to do what I am trying to do.

My notification's progress bar is updated with the following code:

private int upload_progress;
private Long time_previous_progress = Calendar.getInstance().getTimeInMillis();

protected void onProgressUpdate(Integer... progress) {
    Long time_now = Calendar.getInstance().getTimeInMillis();
    if(
       ((time_now - time_previous_progress) < 55) // 55ms minimum delay
       || (progress[0] < 0 && progress[0] > 100)  // progress >0 && <100
       || progress[0].equals(upload_progress)     // progress changed
       || ! App.getStatus()                       // watcher is running
       )
    {
        return;
    }
    time_previous_progress = time_now;
    upload_progress = progress[0];
    int upload_counter = getUploadCounter();
    int upload_total = db.getReadyImagesCount();
    NotificationHandler.notify(context, upload_progress, upload_counter, (upload_total + upload_counter));
}

The notification is then generated with this code:

public static int notify(Context context, Integer progress, Integer upload_count, Integer upload_total)
{
    Bitmap bm = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
    String notif_title = context.getResources().getString(R.string.instant_upload_title);

    String notif_progress = context.getResources().getString(R.string.instant_upload_progress);
    String notif_ticker = String.format(notif_progress, upload_count, upload_total);
    String notif_msg = String.format(notif_progress, upload_count, upload_total);

    Intent intent_swipe = new Intent(context, NotifyReceiver.class);
    intent_swipe.setAction("notification_cancelled");
    PendingIntent pendingIntent_swipe = PendingIntent.getBroadcast(context, 0, intent_swipe, PendingIntent.FLAG_CANCEL_CURRENT);

    Intent intent_click = new Intent(context, Settings.class);
    intent_click.putExtra("notification_clicked", true);
    PendingIntent pendingIntent_click = PendingIntent.getActivity(context, 0, intent_click, PendingIntent.FLAG_CANCEL_CURRENT);

    int pro_max = 100;
    int pro_cur = 0;
    if(progress < 100)
    {
        pro_cur = progress;
    }else{
        pro_cur = pro_max = 0;
    }

    //new NotificationCompat.Builder(context)
    NotificationCompat.Builder builder = new NotificationCompat.Builder(context) //PixelRelayApplication.getNotificationBuilder()
        .setTicker(notif_ticker)
        .setContentTitle(notif_title)
        .setContentText(notif_msg)
        .setNumber(upload_count)
        .setSmallIcon(R.drawable.ic_launcher)
        .setLargeIcon(bm)
        .setContentIntent(pendingIntent_click)
        .setDeleteIntent(pendingIntent_swipe)
        .setAutoCancel(true)
        .setOngoing(true)
        .setWhen(Calendar.getInstance().getTimeInMillis())
        .setProgress(pro_max, pro_cur, false);

    Notification notification = builder.build();

    // Put the auto cancel notification flag
    notification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONLY_ALERT_ONCE;
    NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
    notificationManager.notify(NOTIFY_ME_ID, notification);
    return NOTIFY_ME_ID;
}
Coastwise answered 20/12, 2013 at 19:54 Comment(1)
I think the problem is that you re-create the builder for each time you wish to update the notification. try to use the same builder. I think it will help.Affixation
B
10

You can use the open source code that is working properly for the idea you have in mind accessing it through Github: Progress Watch - A progress bar watchface for pebble. In case you decide to reuse the code, my suggestions are:

  • give the appropriate credit
  • inform the author if you still find something could be improved
  • if you add some new feature, create a fork and submit a patch
Bengt answered 25/12, 2013 at 22:5 Comment(0)
I
6

I fixed this by setting the ongoing flag after the first notification.

So, reuse the builder, and after the first notification is sent, update the builder so it creates ongoing notifications instead:

builder.setOngoing(true);

Of course this also means that the updated notification will become ongoing, http://developer.android.com/reference/android/app/Notification.Builder.html#setOngoing(boolean)

Inhospitality answered 16/12, 2015 at 13:22 Comment(0)
C
0

The behavior of updating the progress is correct. It should update as soon as there is any change.

But you should only update the UI part (like progress bar update).

In case you are using Vibrate to notify than don't use Vibration.

Collyrium answered 25/12, 2013 at 19:30 Comment(1)
Thank you, how do I go about only updating the progress bar?Coastwise

© 2022 - 2024 — McMap. All rights reserved.