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.