At Blockchain, we recently updated our Android app to use more robust push notifications via FCM, notifying users of BTC received to their wallets.
As you might expect, we added a custom vibration pattern to our notifications, but this presented a slight problem. As it turns out, devices where Android ≤4.3 will throw an errant SecurityException: Requires VIBRATE permission
. This is easily fixed, but how do we do this in an idiomatic way?
One suggestion was to try/catch firing the notification — this is obviously quite nasty and is a raw deal for users on old devices. The simple way would be to this would be to turn the builder into a local val
and then simply amend the builder separately:
This is absolutely fine but it breaks up the Builder pattern and we can do better. What if we could put this logic in-line?
Using extension functions, we can extend NotificationCompat.Builder
and create a new function that accepts a predicate, and calls either one function or another depending on the outcome. Taking advantage of function literals with receivers (ie, A.() -> A
), we can ensure that the functions to be triggered are both existing public methods of NotificationCompat.Builder
and return the NotificationCompat.Builder
object itself.
This allows us to do this:
Much cleaner, and doesn’t break the Builder flow. This ternary function seems pretty useful, can we generify it for use with any Builder class? Of course:
So this worked great and I felt pretty good about it for about 15 minutes, and then I realised that infact, Kotlin already had me covered:
apply
is in-fact what exactly I was looking for, as this
is both it’s receiver and return type. Sheepishly, I corrected my fun-but-not-idiomatic code and pushed it to origin.
Still, this was a fun learning experience that I thought I’d share. Kotlin and it’s high-order functions, including those built-in, are incredibly powerful and I love finding new applications for them.
Top comments (1)
Ooohh, wow. It's very useful. I'll to update my code xD.
Thanks for sharing.