{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"required","params":[],"results":{"codes":[]},"settings":"","apiSetting":null},"next":{"description":"","pages":[]},"title":"Android: Notification Handling","type":"basic","slug":"android-custom-notification-handling","excerpt":"Overriding Sailthru Mobile's default behaviour","body":"These methods will give you the most control over how your application reacts to incoming push notifications. \n- If you want to work with the bundle data or collaborate with your app before posting a notification to the user. \n- If you want to silently receive data from a push notification without posting any notification to the user whatsoever.\n- If you want to action something before posting a notification, for example downloading something before telling the user there is new data available.\n- If you want to take advantage of specific notification utilities above the default ones Sailthru Mobile provides.\n- Or any combination of anything you can think of! It's entirely up to you.\n\n## Customising the appearance of a Push Notification\n\nTo customise the appearance or content of a notification, implement as many `NotificationCompat.Extender`s as you like, and add them to Sailthru Mobile's `NotificationConfig`.\n\nNote that if any extenders are added, they will by default override Sailthru Mobile’s notification extender. If you’d like us to still do our default notification extension, you can manually re-extend using our SDK's `NotificationExtender`\n\nFor example, if we wanted to change the title of push notifications with the custom field `special_price`, we could implement the following `NotificationCompat.Extender`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import com.sailthu.mobile.sdk.NotificationExtender;\\n\\nclass SaleNotificationExtender implements NotificationCompat.Extender {\\n    \\n  :::at:::Override\\n  public NotificationCompat.Builder extend(NotificationCompat.Builder builder) {\\n      Bundle bundle = builder.getExtras();\\n      Context context = builder.mContext;\\n      if(bundle.containsKey(\\\"special_price\\\")) {\\n        \\tbuilder.setContentTitle(\\\"SALE\\\")\\n          \\t     .setContentText(bundle.getString(\\\"alert\\\"));\\n      } else {\\n       \\t  return builder.extend(new NotificationExtender());\\n      }\\n\\n      return builder;\\n    }\\n}\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"import com.sailthu.mobile.sdk.NotificationExtender\\n\\ninternal class SaleNotificationExtender : NotificationCompat.Extender {\\n    fun extend(builder: NotificationCompat.Builder): NotificationCompat.Builder {\\n        val bundle: Bundle = builder.getExtras()\\n        val context: Context = builder.mContext\\n        if (bundle.containsKey(\\\"special_price\\\")) {\\n            builder.setContentTitle(\\\"SALE\\\")\\n                   .setContentText(bundle.getString(\\\"alert\\\"))\\n        } else {\\n            return builder.extend(NotificationExtender())\\n        }\\n        return builder\\n    }\\n}\",\n      \"language\": \"kotlin\"\n    }\n  ]\n}\n[/block]\nThen add it to our `NotificationConfig`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \" public class MyApplication extends Application {\\n   @Override\\n   public void onCreate() {\\n     super.onCreate();\\n\\n     SailthruMobile sailthruMobile = new SailthruMobile();\\n     sailthruMobile.startEngine(getApplicationContext(), \\\"your sdk key\\\");\\n\\n     NotificationConfig notificationConfig = new NotificationConfig();\\n     notificationConfig.addNotificationExtender(new SaleNotificationExtender());\\n     sailthruMobile.setNotificationConfig(notificationConfig);\\n   }\\n }\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"class MyApplication : Application() {\\n    fun onCreate() {\\n        super.onCreate()\\n        val sailthruMobile = SailthruMobile()\\n        sailthruMobile.startEngine(applicationContext, \\\"your sdk key\\\")\\n        val notificationConfig = NotificationConfig()\\n        notificationConfig.addNotificationExtender(SaleNotificationExtender())\\n        sailthruMobile.setNotificationConfig(notificationConfig)\\n    }\\n}\",\n      \"language\": \"kotlin\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"success\",\n  \"body\": \"Having access to the `NotificationCompat.Builder` means you can change pretty much whatever you like about the style and content of the notification. Check out the official [Android Notification documentation](http://developer.android.com/guide/topics/ui/notifiers/notifications.html).\"\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"danger\",\n  \"body\": \"Please don't set a `PendingIntent` using `setContentIntent` directly, as it's defined by Sailthru Mobile so we can track opens properly. If you want to change the `Intent` to be executed when a notification is tapped, check the next section.\"\n}\n[/block]\n## Customising the action to be executed when a notification is tapped\n\nTo direct users to an activity of your choosing, you can implement a `ContentIntentBuilder` and set it using `NotificationConfig`.\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"body\": \"Note that this `ContentIntentBuilder` will not be called when the notitication has a deep-link attached.\"\n}\n[/block]\nTo extend the previous example, if we wanted to direct users to some activity `SaleActivity` when a notification has the custom field `special_price` defined we could create a new class implementing `ContentIntentBuilder`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import com.sailthru.mobile.sdk.interfaces.ContentIntentBuilder;\\n    \\npublic class SaleContentIntentBuilder implements ContentIntentBuilder {\\n  @Nullable\\n  @Override\\n  public PendingIntent build(Context context, Bundle bundle) {\\n    if(bundle.containsKey(\\\"special_price\\\")) {\\n      Intent intent = new Intent(context, SaleActivity.class);\\n      return PendingIntent.getActivity(context, 12345, intent, PendingIntent.FLAG_UPDATE_CURRENT);\\n    }\\n\\n    // return null to keep the default behavior\\n    return null;\\n  }\\n}\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"import com.sailthru.mobile.sdk.interfaces.ContentIntentBuilder\\n\\nclass SaleContentIntentBuilder : ContentIntentBuilder {\\n    \\n    override fun build(context: Context?, bundle: Bundle): PendingIntent? {\\n        if (bundle.containsKey(\\\"special_price\\\")) {\\n            val intent = Intent(context, SaleActivity::class.java)\\n            return PendingIntent.getActivity(context, 12345, intent, PendingIntent.FLAG_UPDATE_CURRENT)\\n        }\\n\\n        // return null to keep the default behavior\\n        return null\\n    }\\n}\",\n      \"language\": \"kotlin\"\n    }\n  ]\n}\n[/block]\nThen, like last time, add an instance to `NotificationConfig`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class MyApplication extends Application {\\n    @Override\\n    public void onCreate() {\\n        super.onCreate();\\n\\n        SailthruMobile sailthruMobile = new SailthruMobile();\\n        sailthruMobile.startEngine(getApplicationContext(), \\\"your sdk key\\\");\\n\\n        NotificationConfig notificationConfig = new NotificationConfig();\\n        notificationConfig.addNotificationExtender(new SaleNotificationExtender());\\n        notificationConfig.setContentIntentBuilder(new SaleContentIntentBuilder());\\n        sailthruMobile.setNotificationConfig(notificationConfig);\\n    }\\n}\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"class MyApplication : Application() {\\n    override fun onCreate() {\\n        super.onCreate()\\n        val sailthruMobile = SailthruMobile()\\n        sailthruMobile.startEngine(applicationContext, \\\"your sdk key\\\")\\n        val notificationConfig = NotificationConfig()\\n        notificationConfig.addNotificationExtender(SaleNotificationExtender())\\n        notificationConfig.setContentIntentBuilder(SaleContentIntentBuilder())\\n        sailthruMobile.setNotificationConfig(notificationConfig)\\n    }\\n}\",\n      \"language\": \"kotlin\"\n    }\n  ]\n}\n[/block]\n## Listening to Received Notifications or Tapped Notifications\n\nIt's easy to listen on when a notification was received, and when a user has tapped the notification.\n\n* To listen for received notifications implement `NotificationReceivedListener` and add your listener using `addNotificationReceivedListener`.\n* To listen for tapped notifications implement `NotificationTappedListener` and add your listener using `addNotificationReceivedListener`.\n\nFor example, if we wanted to log when we got notifications with the custom field 'special_price' present, we could implement a received and a tapped listener:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class MyNotificationReceivedListener implements NotificationReceivedListener {\\n  private static final String TAG = \\\"ReceivedLogger\\\";\\n  @Override\\n  public void onNotificationReceived(Context context, Bundle bundle) {\\n    if(bundle.containsKey(\\\"special_price\\\")) {\\n      Log.i(TAG, \\\"Sale Notification received\\\");\\n    }\\n  }\\n}\\n    \\npublic class MyNotificationTappedListener implements NotificationTappedListener {\\n  private static final String TAG = \\\"TappedLogger\\\";\\n  @Override\\n  public void onNotificationTapped(Context context, Bundle bundle) {\\n    if(bundle.containsKey(\\\"special_price\\\")) {\\n      Log.i(TAG, \\\"Sale Notification tapped! That's a good push!\\\");\\n    }\\n  }\\n}\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"class MyNotificationReceivedListener : NotificationReceivedListener {\\n    override fun onNotificationReceived(context: Context?, bundle: Bundle) {\\n        if (bundle.containsKey(\\\"special_price\\\")) {\\n            Log.i(TAG, \\\"Sale Notification received\\\")\\n        }\\n    }\\n\\n    companion object {\\n        private const val TAG = \\\"ReceivedLogger\\\"\\n    }\\n}\\n\\nclass MyNotificationTappedListener : NotificationTappedListener {\\n    override fun onNotificationTapped(context: Context?, bundle: Bundle) {\\n        if (bundle.containsKey(\\\"special_price\\\")) {\\n            Log.i(TAG, \\\"Sale Notification tapped! That's a good push!\\\")\\n        }\\n    }\\n\\n    companion object {\\n        private const val TAG = \\\"TappedLogger\\\"\\n    }\\n}\",\n      \"language\": \"kotlin\"\n    }\n  ]\n}\n[/block]\nThen add these to `SailthruMobile`\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class MyApplication extends Application {\\n    \\n    @Override\\n    public void onCreate() {\\n        super.onCreate();\\n\\n        SailthruMobile sailthruMobile = new SailthruMobile();\\n        sailthruMobile.startEngine(getApplicationContext(), \\\"your sdk key\\\");\\n\\n        sailthruMobile.addNotificationReceivedListener(new MyNotificationReceivedListener());\\n        sailthruMobile.addNotificationTappedListener(new MyNotificationTappedListener());\\n    }\\n}\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"class MyApplication : Application() {\\n    fun onCreate() {\\n        super.onCreate()\\n        val sailthruMobile = SailthruMobile()\\n        sailthruMobile.startEngine(applicationContext, \\\"your sdk key\\\")\\n    sailthruMobile.addNotificationReceivedListener(MyNotificationReceivedListener())\\n        sailthruMobile.addNotificationTappedListener(MyNotificationTappedListener())\\n    }\\n}\",\n      \"language\": \"kotlin\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"These listeners will be called for all notifications, including deep link notifications using `_u`.\"\n}\n[/block]\n## Silent Push Notifications\n\nImplement `NotificationSilencer` if you want to suppress any received notification from the user\n\n-  You can silence notifications from other providers\n-  or Receive a notification to start a special background service using a `NotificationReceivedListener`\n\n \nExample of usage to silence notifications when the custom key `silent` is present.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"class MyNotificationSilencer implements NotificationSilencer {\\n    @Override\\n    boolean isSilent(Context context, Bundle bundle) {\\n      \\treturn bundle.containsKey(\\\"silent\\\");\\n    }\\n}\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"internal class MyNotificationSilencer : NotificationSilencer {\\n    override fun isSilent(context: Context?, bundle: Bundle): Boolean {\\n        return bundle.containsKey(\\\"silent\\\")\\n    }\\n}\",\n      \"language\": \"kotlin\"\n    }\n  ]\n}\n[/block]\nAdd your implementation using `notificationConfig.setSilencer(NotificationSilencer)`\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class MyApplication extends Application {\\n    \\n  @Override\\n  public void onCreate() {\\n    super.onCreate();\\n\\t\\t\\n    SailthruMobile sailthruMobile = new SailthruMobile();\\n    sailthruMobile.startEngine(getApplicationContext(), \\\"your sdk key\\\");\\n    NotificationConfig notificationConfig = new NotificationConfig();\\n    notificationConfig.setSilencer(new MyNotificationSilencer());\\n    sailthruMobile.setNotificationConfig(notificationConfig);\\n\\n  }\\n}\",\n      \"language\": \"java\"\n    },\n    {\n      \"code\": \"class MyApplication : Application() {\\n    override fun onCreate() {\\n        super.onCreate()\\n        val sailthruMobile = SailthruMobile()\\n        sailthruMobile.startEngine(applicationContext, \\\"your sdk key\\\")\\n        val notificationConfig = NotificationConfig()\\n        notificationConfig.setSilencer(MyNotificationSilencer())\\n        sailthruMobile.setNotificationConfig(notificationConfig)\\n    }\\n}\",\n      \"language\": \"kotlin\"\n    }\n  ]\n}\n[/block]\n## Bundle Data\n\nOn all customisations available the Bundle will contain all data that was attached to the push and can be used in building your notification.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/258db45-image_16.png\",\n        \"image_16.png\",\n        570,\n        376,\n        \"#e4ecf3\"\n      ]\n    }\n  ]\n}\n[/block]\nThe above push notification would result in a bundle containing the following data:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"alert\\\": \\\"<push message>\\\", \\n  \\\"badge\\\": \\\"5\\\", \\n  \\\"sound\\\": \\\"<sound name>\\\", \\n  \\\"<custom key>\\\": \\\"<custom value>\\\"\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]","updates":[],"order":0,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"5e6156bf5e4a51006dcd8159","version":{"version":"1.5","version_clean":"1.5.0","codename":"ST Rebrand","is_stable":true,"is_beta":false,"is_hidden":false,"is_deprecated":false,"categories":["5e6156bf5e4a51006dcd8120","5e6156bf5e4a51006dcd8121","5e6156bf5e4a51006dcd8122","5e6156bf5e4a51006dcd8123","5e6156bf5e4a51006dcd8124","561c61b4ad272c0d00a892df","586c014c0abf1d0f000d04d4","58991d2ad207df0f0002186b","5e6156bf5e4a51006dcd8125","5e6156bf5e4a51006dcd8126","5af0fe494ca2730003cbc98a","5af0fe55ec80af0003804ca2","5e69868cbd5dcb006b35867b","5e6986ca2c6652006791b6e8"],"_id":"5e6156bf5e4a51006dcd818c","project":"55e67aaa9cc7c62b00c4a1ea","__v":2,"forked_from":"5b720760c44b7600034b7a08","createdAt":"2015-09-02T04:27:23.612Z","releaseDate":"2015-09-02T04:27:23.612Z"},"__v":18,"category":{"sync":{"isSync":false,"url":""},"pages":[],"title":"Android Techniques","slug":"android-techniques","order":9999,"from_sync":false,"reference":false,"_id":"5e69868cbd5dcb006b35867b","createdAt":"2020-03-12T00:47:08.696Z","version":"5e6156bf5e4a51006dcd818c","project":"55e67aaa9cc7c62b00c4a1ea","__v":0},"project":"55e67aaa9cc7c62b00c4a1ea","createdAt":"2015-12-14T01:44:05.193Z","githubsync":"","parentDoc":null,"user":"56035f358d58900d0051e976"}

Android: Notification Handling

Overriding Sailthru Mobile's default behaviour

These methods will give you the most control over how your application reacts to incoming push notifications. - If you want to work with the bundle data or collaborate with your app before posting a notification to the user. - If you want to silently receive data from a push notification without posting any notification to the user whatsoever. - If you want to action something before posting a notification, for example downloading something before telling the user there is new data available. - If you want to take advantage of specific notification utilities above the default ones Sailthru Mobile provides. - Or any combination of anything you can think of! It's entirely up to you. ## Customising the appearance of a Push Notification To customise the appearance or content of a notification, implement as many `NotificationCompat.Extender`s as you like, and add them to Sailthru Mobile's `NotificationConfig`. Note that if any extenders are added, they will by default override Sailthru Mobile’s notification extender. If you’d like us to still do our default notification extension, you can manually re-extend using our SDK's `NotificationExtender` For example, if we wanted to change the title of push notifications with the custom field `special_price`, we could implement the following `NotificationCompat.Extender`: [block:code] { "codes": [ { "code": "import com.sailthu.mobile.sdk.NotificationExtender;\n\nclass SaleNotificationExtender implements NotificationCompat.Extender {\n \n @Override\n public NotificationCompat.Builder extend(NotificationCompat.Builder builder) {\n Bundle bundle = builder.getExtras();\n Context context = builder.mContext;\n if(bundle.containsKey(\"special_price\")) {\n \tbuilder.setContentTitle(\"SALE\")\n \t .setContentText(bundle.getString(\"alert\"));\n } else {\n \t return builder.extend(new NotificationExtender());\n }\n\n return builder;\n }\n}", "language": "java" }, { "code": "import com.sailthu.mobile.sdk.NotificationExtender\n\ninternal class SaleNotificationExtender : NotificationCompat.Extender {\n fun extend(builder: NotificationCompat.Builder): NotificationCompat.Builder {\n val bundle: Bundle = builder.getExtras()\n val context: Context = builder.mContext\n if (bundle.containsKey(\"special_price\")) {\n builder.setContentTitle(\"SALE\")\n .setContentText(bundle.getString(\"alert\"))\n } else {\n return builder.extend(NotificationExtender())\n }\n return builder\n }\n}", "language": "kotlin" } ] } [/block] Then add it to our `NotificationConfig`: [block:code] { "codes": [ { "code": " public class MyApplication extends Application {\n @Override\n public void onCreate() {\n super.onCreate();\n\n SailthruMobile sailthruMobile = new SailthruMobile();\n sailthruMobile.startEngine(getApplicationContext(), \"your sdk key\");\n\n NotificationConfig notificationConfig = new NotificationConfig();\n notificationConfig.addNotificationExtender(new SaleNotificationExtender());\n sailthruMobile.setNotificationConfig(notificationConfig);\n }\n }", "language": "java" }, { "code": "class MyApplication : Application() {\n fun onCreate() {\n super.onCreate()\n val sailthruMobile = SailthruMobile()\n sailthruMobile.startEngine(applicationContext, \"your sdk key\")\n val notificationConfig = NotificationConfig()\n notificationConfig.addNotificationExtender(SaleNotificationExtender())\n sailthruMobile.setNotificationConfig(notificationConfig)\n }\n}", "language": "kotlin" } ] } [/block] [block:callout] { "type": "success", "body": "Having access to the `NotificationCompat.Builder` means you can change pretty much whatever you like about the style and content of the notification. Check out the official [Android Notification documentation](http://developer.android.com/guide/topics/ui/notifiers/notifications.html)." } [/block] [block:callout] { "type": "danger", "body": "Please don't set a `PendingIntent` using `setContentIntent` directly, as it's defined by Sailthru Mobile so we can track opens properly. If you want to change the `Intent` to be executed when a notification is tapped, check the next section." } [/block] ## Customising the action to be executed when a notification is tapped To direct users to an activity of your choosing, you can implement a `ContentIntentBuilder` and set it using `NotificationConfig`. [block:callout] { "type": "warning", "body": "Note that this `ContentIntentBuilder` will not be called when the notitication has a deep-link attached." } [/block] To extend the previous example, if we wanted to direct users to some activity `SaleActivity` when a notification has the custom field `special_price` defined we could create a new class implementing `ContentIntentBuilder`: [block:code] { "codes": [ { "code": "import com.sailthru.mobile.sdk.interfaces.ContentIntentBuilder;\n \npublic class SaleContentIntentBuilder implements ContentIntentBuilder {\n @Nullable\n @Override\n public PendingIntent build(Context context, Bundle bundle) {\n if(bundle.containsKey(\"special_price\")) {\n Intent intent = new Intent(context, SaleActivity.class);\n return PendingIntent.getActivity(context, 12345, intent, PendingIntent.FLAG_UPDATE_CURRENT);\n }\n\n // return null to keep the default behavior\n return null;\n }\n}", "language": "java" }, { "code": "import com.sailthru.mobile.sdk.interfaces.ContentIntentBuilder\n\nclass SaleContentIntentBuilder : ContentIntentBuilder {\n \n override fun build(context: Context?, bundle: Bundle): PendingIntent? {\n if (bundle.containsKey(\"special_price\")) {\n val intent = Intent(context, SaleActivity::class.java)\n return PendingIntent.getActivity(context, 12345, intent, PendingIntent.FLAG_UPDATE_CURRENT)\n }\n\n // return null to keep the default behavior\n return null\n }\n}", "language": "kotlin" } ] } [/block] Then, like last time, add an instance to `NotificationConfig`: [block:code] { "codes": [ { "code": "public class MyApplication extends Application {\n @Override\n public void onCreate() {\n super.onCreate();\n\n SailthruMobile sailthruMobile = new SailthruMobile();\n sailthruMobile.startEngine(getApplicationContext(), \"your sdk key\");\n\n NotificationConfig notificationConfig = new NotificationConfig();\n notificationConfig.addNotificationExtender(new SaleNotificationExtender());\n notificationConfig.setContentIntentBuilder(new SaleContentIntentBuilder());\n sailthruMobile.setNotificationConfig(notificationConfig);\n }\n}", "language": "java" }, { "code": "class MyApplication : Application() {\n override fun onCreate() {\n super.onCreate()\n val sailthruMobile = SailthruMobile()\n sailthruMobile.startEngine(applicationContext, \"your sdk key\")\n val notificationConfig = NotificationConfig()\n notificationConfig.addNotificationExtender(SaleNotificationExtender())\n notificationConfig.setContentIntentBuilder(SaleContentIntentBuilder())\n sailthruMobile.setNotificationConfig(notificationConfig)\n }\n}", "language": "kotlin" } ] } [/block] ## Listening to Received Notifications or Tapped Notifications It's easy to listen on when a notification was received, and when a user has tapped the notification. * To listen for received notifications implement `NotificationReceivedListener` and add your listener using `addNotificationReceivedListener`. * To listen for tapped notifications implement `NotificationTappedListener` and add your listener using `addNotificationReceivedListener`. For example, if we wanted to log when we got notifications with the custom field 'special_price' present, we could implement a received and a tapped listener: [block:code] { "codes": [ { "code": "public class MyNotificationReceivedListener implements NotificationReceivedListener {\n private static final String TAG = \"ReceivedLogger\";\n @Override\n public void onNotificationReceived(Context context, Bundle bundle) {\n if(bundle.containsKey(\"special_price\")) {\n Log.i(TAG, \"Sale Notification received\");\n }\n }\n}\n \npublic class MyNotificationTappedListener implements NotificationTappedListener {\n private static final String TAG = \"TappedLogger\";\n @Override\n public void onNotificationTapped(Context context, Bundle bundle) {\n if(bundle.containsKey(\"special_price\")) {\n Log.i(TAG, \"Sale Notification tapped! That's a good push!\");\n }\n }\n}", "language": "java" }, { "code": "class MyNotificationReceivedListener : NotificationReceivedListener {\n override fun onNotificationReceived(context: Context?, bundle: Bundle) {\n if (bundle.containsKey(\"special_price\")) {\n Log.i(TAG, \"Sale Notification received\")\n }\n }\n\n companion object {\n private const val TAG = \"ReceivedLogger\"\n }\n}\n\nclass MyNotificationTappedListener : NotificationTappedListener {\n override fun onNotificationTapped(context: Context?, bundle: Bundle) {\n if (bundle.containsKey(\"special_price\")) {\n Log.i(TAG, \"Sale Notification tapped! That's a good push!\")\n }\n }\n\n companion object {\n private const val TAG = \"TappedLogger\"\n }\n}", "language": "kotlin" } ] } [/block] Then add these to `SailthruMobile` [block:code] { "codes": [ { "code": "public class MyApplication extends Application {\n \n @Override\n public void onCreate() {\n super.onCreate();\n\n SailthruMobile sailthruMobile = new SailthruMobile();\n sailthruMobile.startEngine(getApplicationContext(), \"your sdk key\");\n\n sailthruMobile.addNotificationReceivedListener(new MyNotificationReceivedListener());\n sailthruMobile.addNotificationTappedListener(new MyNotificationTappedListener());\n }\n}", "language": "java" }, { "code": "class MyApplication : Application() {\n fun onCreate() {\n super.onCreate()\n val sailthruMobile = SailthruMobile()\n sailthruMobile.startEngine(applicationContext, \"your sdk key\")\n sailthruMobile.addNotificationReceivedListener(MyNotificationReceivedListener())\n sailthruMobile.addNotificationTappedListener(MyNotificationTappedListener())\n }\n}", "language": "kotlin" } ] } [/block] [block:callout] { "type": "info", "body": "These listeners will be called for all notifications, including deep link notifications using `_u`." } [/block] ## Silent Push Notifications Implement `NotificationSilencer` if you want to suppress any received notification from the user - You can silence notifications from other providers - or Receive a notification to start a special background service using a `NotificationReceivedListener` Example of usage to silence notifications when the custom key `silent` is present. [block:code] { "codes": [ { "code": "class MyNotificationSilencer implements NotificationSilencer {\n @Override\n boolean isSilent(Context context, Bundle bundle) {\n \treturn bundle.containsKey(\"silent\");\n }\n}", "language": "java" }, { "code": "internal class MyNotificationSilencer : NotificationSilencer {\n override fun isSilent(context: Context?, bundle: Bundle): Boolean {\n return bundle.containsKey(\"silent\")\n }\n}", "language": "kotlin" } ] } [/block] Add your implementation using `notificationConfig.setSilencer(NotificationSilencer)` [block:code] { "codes": [ { "code": "public class MyApplication extends Application {\n \n @Override\n public void onCreate() {\n super.onCreate();\n\t\t\n SailthruMobile sailthruMobile = new SailthruMobile();\n sailthruMobile.startEngine(getApplicationContext(), \"your sdk key\");\n NotificationConfig notificationConfig = new NotificationConfig();\n notificationConfig.setSilencer(new MyNotificationSilencer());\n sailthruMobile.setNotificationConfig(notificationConfig);\n\n }\n}", "language": "java" }, { "code": "class MyApplication : Application() {\n override fun onCreate() {\n super.onCreate()\n val sailthruMobile = SailthruMobile()\n sailthruMobile.startEngine(applicationContext, \"your sdk key\")\n val notificationConfig = NotificationConfig()\n notificationConfig.setSilencer(MyNotificationSilencer())\n sailthruMobile.setNotificationConfig(notificationConfig)\n }\n}", "language": "kotlin" } ] } [/block] ## Bundle Data On all customisations available the Bundle will contain all data that was attached to the push and can be used in building your notification. [block:image] { "images": [ { "image": [ "https://files.readme.io/258db45-image_16.png", "image_16.png", 570, 376, "#e4ecf3" ] } ] } [/block] The above push notification would result in a bundle containing the following data: [block:code] { "codes": [ { "code": "{\n \"alert\": \"<push message>\", \n \"badge\": \"5\", \n \"sound\": \"<sound name>\", \n \"<custom key>\": \"<custom value>\"\n}", "language": "json" } ] } [/block]