Office Hours — Today, February 18

Tuesday, February 16

Feb 18
8:25 AM
Mark M.
has entered the room
Mark M.
turned on guest access
Kai H.
has entered the room
Mark M.
hello, Kai!
how can I help you today?
Kai H.
Hello Mark.
I thougth I had some questions, but I have none written down atm.
So I'll be lurking for the time being.
8:30 AM
Mark M.
ok
8:35 AM
Grigore C.
has entered the room
Mark M.
hello, Grigore! sorry, I didn't notice your arrival!
how can I help you today?
Grigore C.
Hello, Mark! No problem.
Well I'm facing some problems with FCM and notifications
Mark M.
I do not work with FCM much, but I can still try to help
Grigore C.
And I got some questions and I'd appreciate some direction on what to read or tips about notifications
Sooo first one :D
Notification channels are immutable? You cannot change them after they are created? An example, I set a default sound for a channel and the change to a custom sound. When I reinstall the app the channel still has a default sound. I guess this type of changes requires a notification channel "manager"? Like recreate the channel or so
Immutable as you cannot change all of the properties, only some of them
Mark M.
"You cannot change them after they are created?... Immutable as you cannot change all of the properties, only some of them" -- correct
8:40 AM
Grigore C.
So if I want to change the sound I have to delete and create the channel?
Mark M.
yes, or just let the user change the sound themselves via the Settings app
that's really part of the point here: you state what you would like, and from there, the user takes over
Grigore C.
but can I use the same channel properties? like delete channel 1 with no custom sound and create it again with a custom sound
Mark M.
I think there may be some restrictions around reusing channel names -- I haven't dealt with this in a few years so I forget that level of detail
Google would really prefer that you not try to manage the notification sound in-app
Grigore C.
hmm, that's interesting
Some of the phones work ok, but some of them don't "find" the custom sound
So it just might be better to guide the user
Mark M.
in modern Android, users can choose, per channel, whether notifications play a sound and what that sound is
(in addition to blocking a channel's notifications outright)
Grigore C.
Ok, back to FCM :D did you use any other tool for notifications?
8:45 AM
Grigore C.
I assume that FCM might be the best choice because is made by Google...
Mark M.
here, if by "notifications" you mean "push messages", then no -- if I needed those to occur all the time, I have only needed FCM
however, I have not had that requirement all that much
Grigore C.
push notifications, yes
It seems like my phone won't be triggered by high priority notifications
while it's in doze mode...
Mark M.
in newer versions of Android, there are throttles as to how frequently a high-priority message will wake up the device
Grigore C.
yes, the buckets, right?
Mark M.
right
Grigore C.
but active bucket I think it doesn't have restrictions
Mark M.
Grigore C.
but Huawei, Samsung, etc might override that...
Mark M.
yes, though in Huawei's case that would be limited to Play Store ecosystem devices -- their other ones lack FCM
Grigore C.
I don't really understand this one. Phones will not get notified...
Mark M.
for an active app, that is a case where I would be using something else (e.g., websocket) -- I have only used FCM for cases where we have no idea if the app is active or not
Grigore C.
Hmm, I think that's my case, "no idea if the app is active or not"
8:50 AM
Grigore C.
but the user should be notified as soon as possible
8:50 AM
Mark M.
however, in the "no idea if the app is active or not" case, you may not be in the active bucket
(BTW, Kai: if you come up with a question, let me know!)
Grigore C.
Any idea on how a chat app always pop-up notifications? I want to achieve chat-app like notification consistency
I've studied the Singal app source code and I think it forces a WakeLock
Mark M.
that would depend a bit on what app you are using as a basis for comparison
Grigore C.
using an Alarm
notify the user with a 1-5 minute error
Mark M.
Signal definitely has no abilities beyond what you or I could do -- WhatsApp, on the other hand, might use FCM but might also use $$$ to get manufacturers to not mess with their messages
if I had to implement something Signal-ish, I would look at having a durable websocket connection to the server with a foreground service, and use FCM only when that websocket is gone for X minutes
and even there, the objective of the FCM message is less "show something to the user" and more "get our process running again so we get the websocket up"
Grigore C.
so when the foreground service is kinda dead
That makes sense
8:55 AM
Grigore C.
I've read that FCM might deliver notifications using Google Play Services
Hopefully, I am not wrong
Mark M.
it definitely does -- FCM is part of the Play Services framework
which is why FCM can do things that you and I cannot
Grigore C.
But if the app is killed I don't think it will be able to show notifications
Mark M.
that will depend a fair bit on what happens when your app "is killed"
your UI process probably is terminated
separate processes (e.g., for a foreground service) may or may not survive
and, on some devices, "killing" the app has the same effect as does the "Force Stop" button in Settings, and that has fairly drastic effects
Grigore C.
but what if I don't have a foreground/background service
can I prevent the app from being killed?
Mark M.
not without custom firmware
basically, if you build your own Android OS version, you can do whatever you want
Grigore C.
uff :(
Mark M.
however, even in the "Force Stop" scenario, FCM messages should still get to your app, as FCM will use an explicit Intent to talk to your app, which will move your app out of the "stopped" state and allow processes to run again
Grigore C.
seems impossible to make it work most of the times
I'll try to force stop it and see what happens
do you think using a wakelock when a notification is consumed would improve anything?
9:00 AM
Grigore C.
or it will cause the app to be "blacklisted" even faster
Mark M.
I can't speak to manufacturer-specific blacklist sorts of behavior
Grigore C.
yes, of course, just your opinion
Mark M.
and I have not tried maintaining a long-lived websocket like this -- about an hour is all I have needed to deal with
Grigore C.
and how did you do it? like described before?
Mark M.
well, my current client uses websockets, but it is mostly while the app is in use
Grigore C.
I understand
Mark M.
the "about an hour" scenario is a case where the app is running and probably in the foreground, but the device is set aside and the screen turns off
we use a partial wakelock and a WifiLock to keep the websocket going (because we know that we are on WiFi)
as part of a foreground service, to help ensure Android doesn't terminate the process
Grigore C.
and when do you require that wakelock? using the foreground service I assume
Mark M.
yes -- there is a particular user action that triggers the foreground service
we keep that service going for the duration of a particular event (5-60 minutes)
Grigore C.
and the wakelock duration is set to 5-60 minutes?
Mark M.
and stop that service when the event ends (either automatically at the end of the time or if the user manually cancels it)
I forget the actual duration value that we use -- we mostly focus on manually releasing it when the service stops
Grigore C.
yes, I mean the wakelock is released after the service stops
like you said
9:05 AM
Mark M.
yes -- we hold the WakeLock and WifiLock for the duration of this "session", then release them
our results are not 100% reliable, though how much of that is tied to our app and how much is tied to other things is unclear
Grigore C.
I don't understand a thing
"we keep that service going for the duration of a particular event (5-60 minutes)"
how?
Mark M.
it's a foreground service
we start the service at the start of the "session"
we stop the service at the end of the "session"
we know when the session starts based on user interaction
Grigore C.
and you have a counter inside it or something that will stop it after x minutes?
Mark M.
effectively, yes -- the story is a bit more complicated and I cannot discuss it
Grigore C.
sure, no problem, I thought Foreground Service has an option
a timer like one
Mark M.
I do not recall there being one -- we know when the session ends either due to elapsed time or user interaction (basically, clicking a stop button)
Grigore C.
yes, I got it now, thank you :)
I've ran into this today https://dontkillmyapp.com/
looks like things are getting worse and worse
Mark M.
yes, the "War on Background Processing" is something I have been writing about since Android 6.0
writing a Signal-style messaging app is not going to be fun
9:10 AM
sudokai
has entered the room
Grigore C.
where did you write about it? in your books?
Mark M.
I have used that phrase in blog posts and Stack Overflow answers, more so than in books, IIRC
let me take a question from sudokai, and I will come back to you in a bit
sudokai: hi! how can I help you today?
Grigore C.
sure
sudokai
Hi
How do you deep link into a screen
And make sure the back button works
By taking you to the parent screen
Instead of the main screen
I know there's TaskStackBuilder for activities
But what do you use for fragments
Mark M.
I cannot really answer that question, as it depends mostly on what you are doing for navigation
so, for example, if you are using Jetpack's Navigation component, it has built in support for deep links
sudokai
Nothing
I do it manually
With FragmentTransactions
And I called add and addToBackStack
The problem is that I don't want my intermediate screens to show
I just want to go to the final destination
But still have the back button work
9:15 AM
sudokai
So I go like this
A -> B -> C -> D
The problem is that when I open the "deep link"
I see for a brief moment
A, B and C
I would like to go to D directly
Mark M.
if you are going to do all of this manually, you would need to manually handle back navigation, recognize that you are in this deep link scenario, and run the correct fragment transaction(s)
sudokai
But if I just do a single transaction, when I hit back from D I go to A, not C
Mark M.
only if you let fragments handle back navigation, or you use popBackStack()
if *you* register your *own* back navigation listener and handle it all manually, you can do whatever you want, including a replace() to show C
sudokai
So you are saying that the trick is just displaying D and listen to the back navigation
Mark M.
yes
sudokai
And when the back navigation is clicked, then create C
Mark M.
yes
sudokai
Wow thanks
Mark M.
if you are lucky, you might be able to only deal with your deep link scenario manually and defer to the existing implementation for non-deep-link scenarios
sudokai
Can you pass data up?
What I mean is:
Sometimes I need
A-B-C-D
But other times it's
A-X-C-D
9:20 AM
sudokai
It depends on the data
Mark M.
um, when you create your C instance you can supply data via the arguments Bundle
sudokai
So C needs to know if it needs to go back to B or X
Okay, the standard arguments way
Mark M.
which could include details on what C should be showing next (B or X) when you are manually handling back navigation
sudokai
Thanks
Mark M.
right
sudokai
Wow thanks
Mark M.
OK, we are running out of chat time -- if anyone has any questions, go ahead!
Grigore C.
I'm good, thank you for your help!
sudokai
It seems an awful lot of work for such a simple use case
Mark M.
IMHO, it is not that simple of a use case
9:25 AM
Mark M.
but, that is why they created Jetpack Navigation -- to package up common navigation/routing patterns
sudokai
Well, the whole app just uses the first approach I told you
It's awful
9:30 AM
Mark M.
OK, that is all for today's chat
the transcript will be posted to https://commonsware.com/office-hours/ shortly
sudokai
Thanks!
Mark M.
the next chat is Saturday in the 4pm US Eastern time slot
have a pleasant day!
sudokai
You too
Kai H.
has left the room
Grigore C.
has left the room
sudokai
has left the room
Mark M.
turned off guest access

Tuesday, February 16

 

Office Hours

People in this transcript

  • Grigore Cristian-Andrei
  • Kai H.
  • Mark Murphy
  • sudokai