Android Question Update Foreground Service Notification Message

Marcos Alves

Well-Known Member
Licensed User
Hello,

I have a foreground service that navigates in a sqlite table and downloads some images, and would like to put a counter in the notification to show the number of downloaded images. The service notification is created with this code:

B4X:
    n.Initialize
    n.Sound = False
    n.Vibrate = False
    n.SetInfo("goLunch","Baixando imagens",restaurantMenu)
    Service.StartForeground(2,n)
I know that I can't call n.setinfo ater the notification is done and I can't use NB6 class also (because foregroundservice requires the original notification object right?).
How can I update the notification message considering that to create a new notification object for each table record couldn't be a good solution?
 

Marcos Alves

Well-Known Member
Licensed User
Registering a new notification with the same id will replace the old content.
Hello,

I don't think that in this situation could be a good solution. Imagine that a table could have 1000 records... the code will be:

B4X:
Dim n(1000) as notification
And in the loop parsing the table:
B4X:
for i = 0 to cursor1.recordcount - 1
n(i).initialize
...
next
I see many problems in this approach:
1. Memory: to create 1000 notification objects (?)
2. Each register will be a new notification (with vibrate, sound , etc), besides it's in the same channel

Isn't there other solution?
 

DonManfred

Expert
Licensed User
Why 1000 notifications??????
USE one and show the number 1000 in it.

If i would run a application and it is showing 1000 notifications. Only one thing i would do instantly. UNINSTALL! ASAP!
 

Marcos Alves

Well-Known Member
Licensed User
Why 1000 notifications??????
USE one and show the number 1000 in it.
Hello @DonManfred ... I'll try to be clear showing the complete code:
B4X:
    n.Initialize
    n.Sound = False
    n.Vibrate = False
    n.SetInfo("goLunch","Baixando imagens",restaurantMenu)
    Service.StartForeground(2,n)
    Dim query As String
    Dim cursor1 As Cursor
    Dim baseAddress As String = "https://static-images.test.br/image/upload/pratos/"
    Dim targetImage As String
    
    query = "select logoUrl from cadProd where logoUrl is not null"
    cursor1 = sql1.ExecQuery(query)
    
    If cursor1.RowCount > 0 Then
        Dim job As HttpJob
        Dim retImage As Bitmap
        Dim out As OutputStream
        For i = 0 To cursor1.RowCount - 1
            cursor1.Position = i
            targetImage = cursor1.GetString("logoUrl")
            Log("downloading image " & (i + 1) & " de " & cursor1.RowCount)
            If targetImage.Trim.Length > 5 Then
                If File.Exists(File.DirInternal,targetImage.Replace("/","-") ) = False Then

                    job.Initialize("",Me)               
                    job.Download(baseAddress & targetImage)
                    
                    Wait For jobDone(job As HttpJob)
                    
                    If job.Success Then
                        retImage = job.GetBitmap
                        out = File.OpenOutput(File.DirInternal,targetImage.Replace("/","-") ,False)
                        retImage.WriteToStream(out,100,"JPEG")
                        out.Close
                    Else
                        Log("error downloading image " & job.ErrorMessage)
                    End If
                    job.Release
                Else
                    Log("image " & (i+1) & " de " & cursor1.RowCount & " já existe")
                End If
            End If
            
        Next
    End If
    
    Service.StopForeground(2)
    Service.StopAutomaticForeground
For each record I need to update the counter in the service notification. If I put inside the for... next dim n1 as notification, n1 will be the same object and will not allow to change the message content ... so, for each loop count I think that must to be created a new object correct? And the only way to do this is using a notifications object as array...
 

Marcos Alves

Well-Known Member
Licensed User
As already mentioned by @Brandsum ; USE the ID of the Notification. Use the same ID to replace an old Notification with this ID. This way you replace it/set a new text...
Yes, I understood ... but as it requires to change the text as many as there are records in the table, if there are 1000 records I'll need to define an array of notifications OR each new Dim n as notification in the for... next loop will be enough to "renew" the object?
 

LucaMs

Expert
Licensed User
I also don't think you need to "shows" 1.000 notifications "each" time, I suppose you will have few new records every N minutes/seconds.
Select those not already "shown" and create a single notification which shows the number of these new records.
 

Marcos Alves

Well-Known Member
Licensed User
I also don't think you need to "shows" 1.000 notifications "each" time, I suppose you will have few new records every N minutes/seconds.
Select those not already "shown" and create a single notification which shows the number of these new records.
No... Each image spends about 5-10 seconds to be downloaded.... then, we are talking about 6-12 notifications per minute which could be bad to the user experience. In the other hand, only notify that the service started and don't show the evolution of the process isn't good either.
A good solution could be to leave the service notification static and use other one based in NB6 class to implement a counter... I think that this last one could be the best choice - what do you think?
 

LucaMs

Expert
Licensed User
No... Each image spends about 5-10 seconds to be downloaded.... then, we are talking about 6-12 notifications per minute which could be bad to the user experience
But should the user receive thousands of images (and notifications) perpetually? I don't think so, right?

So I think it's enough to show the number of new arrivals every T time.
 

Marcos Alves

Well-Known Member
Licensed User
But should the user receive thousands of images (and notifications) perpetually? I don't think so, right?

So I think it's enough to show the number of new arrivals every T time.
Yes... after the first setup the download is differential. But at the first time I need to sync the app with the server and sometimes the are more than 1000 images in the server (small size images, of course - not more than 200 Kb...). Then, the user opens the screen with text data only and a service is started in background to download.
The images codes are unique and the service only downloads the ones those aren't still in the device. To avoid the service to be stopped by Android must to be started as foreground.
The first images download could spend 5 minutes or more...
 

Marcos Alves

Well-Known Member
Licensed User
It doesn't seem like a good idea to store all those image files on clients; it is much better to downloaded 10-100 only if/when necessary - see:
https://www.b4x.com/android/forum/threads/b4x-xui-customlistview-lazy-loading-virtualization.87930/
The app in this case is a professional app.. our customer knows that will spend some space (about ~500Mb at maximum) in his device to be able to use the app when there is no internet connection. By the way, I found some people with more than 15Gb of WhatsApp images stored in the mobile phone :D:p. When my customer says about the space used by the app, I question: do you use WhatsApp o_O?
 

LucaMs

Expert
Licensed User
do you use WhatsApp o_O?
WhatsApp just uses that kind of "strategy", the same of the lazy loading of that CustomListView.
If you scroll quickly a WA chat, you will see some "lagging", while WA downloads old messages.
Probably, it stores last N messages on device, but the oldest ones...!

Anyway... I often remove images and videos from my device, WA stuff too ;)
 
Top