{"_id":"5b720760c44b7600034b79e3","version":{"_id":"5b720760c44b7600034b7a08","project":"55e67aaa9cc7c62b00c4a1ea","__v":0,"forked_from":"5b1f2cbdfd653400031d8d9f","createdAt":"2015-09-02T04:27:23.612Z","releaseDate":"2015-09-02T04:27:23.612Z","categories":["5b720760c44b7600034b79a7","5b720760c44b7600034b79a8","5b720760c44b7600034b79a9","5b720760c44b7600034b79aa","5b720760c44b7600034b79ab","561c61b4ad272c0d00a892df","586c014c0abf1d0f000d04d4","58991d2ad207df0f0002186b","5b720760c44b7600034b79ac","5b720760c44b7600034b79ad","5af0fe494ca2730003cbc98a","5af0fe55ec80af0003804ca2"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"API V6","version_clean":"1.4.0","version":"1.4"},"__v":18,"category":{"_id":"5b720760c44b7600034b79ac","project":"55e67aaa9cc7c62b00c4a1ea","__v":0,"version":"5b720760c44b7600034b7a08","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2017-02-08T21:31:11.878Z","from_sync":false,"order":6,"slug":"advanced-techniques","title":"Advanced Techniques"},"project":"55e67aaa9cc7c62b00c4a1ea","githubsync":"","parentDoc":null,"user":"56035f358d58900d0051e976","updates":[],"next":{"pages":[],"description":""},"createdAt":"2015-12-14T01:44:05.193Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","apiSetting":null,"auth":"required","params":[],"url":""},"isReference":false,"order":10,"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! Its 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 Carnival’s notification extender. If you’d like us to still do our default notification extension, you can manually re-extend using `CarnivalNotificationExtender`\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\": \"class 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      builder.setContentTitle(\\\"SALE\\\")\\n        .setContentText(bundle.getString(\\\"alert\\\"));\\n    } else {\\n      return builder.extend(new CarnivalNotificationExtender());\\n    }\\n\\n    return builder;\\n  }\\n}\",\n      \"language\": \"java\"\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     Carnival.startEngine(getApplicationContext(), \\\"your sdk key\\\");\\n\\n     NotificationConfig notificationConfig = new NotificationConfig();\\n     notificationConfig.addNotificationExtender(new SaleNotificationExtender());\\n     Carnival.setNotificationConfig(notificationConfig);\\n   }\\n }\",\n      \"language\": \"java\"\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.carnival.sdk.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}\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    Carnival.startEngine(getApplicationContext(), \\\"your sdk key\\\");\\n\\n    NotificationConfig notificationConfig = new NotificationConfig();\\n    notificationConfig.addNotificationExtender(new SaleNotificationExtender());\\n    notificationConfig.setContentIntentBuilder(new SaleContentIntentBuilder());\\n    Carnival.setNotificationConfig(notificationConfig);\\n  }\\n}\",\n      \"language\": \"java\"\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 `Carnival.addNotificationReceivedListener`.\n* To listen for tapped notifications implement `NotificationTappedListener` and add your listener using `Carnival.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 = \\\"NotificationLogger\\\";\\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  @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}\n[/block]\nThen add these to `Carnival`\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    Carnival.startEngine(getApplicationContext(), \\\"your sdk key\\\");\\n\\n    Carnival.addNotificationReceivedListener(new MyNotificationReceivedListener());\\n    Carnival.addNotificationTappedListener(new MyNotificationTappedListener());\\n  }\\n}\",\n      \"language\": \"java\"\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    return bundle.containsKey(\\\"silent\\\");\\n  }\\n}\",\n      \"language\": \"java\"\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\\n    Carnival.startEngine(getApplicationContext(), \\\"your sdk key\\\");\\n    NotificationConfig notificationConfig = new NotificationConfig();\\n    notificationConfig.setSilencer(new MyNotificationSilencer());\\n    Carnival.setNotificationConfig(notificationConfig);\\n\\n  }\\n}\",\n      \"language\": \"java\"\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]","excerpt":"Overriding Sailthru Mobile's default behaviour","slug":"android-custom-notification-handling","type":"basic","title":"Android: Notification Handling"}

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! Its 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 Carnival’s notification extender. If you’d like us to still do our default notification extension, you can manually re-extend using `CarnivalNotificationExtender` 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": "class 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 builder.setContentTitle(\"SALE\")\n .setContentText(bundle.getString(\"alert\"));\n } else {\n return builder.extend(new CarnivalNotificationExtender());\n }\n\n return builder;\n }\n}", "language": "java" } ] } [/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 Carnival.startEngine(getApplicationContext(), \"your sdk key\");\n\n NotificationConfig notificationConfig = new NotificationConfig();\n notificationConfig.addNotificationExtender(new SaleNotificationExtender());\n Carnival.setNotificationConfig(notificationConfig);\n }\n }", "language": "java" } ] } [/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.carnival.sdk.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" } ] } [/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 Carnival.startEngine(getApplicationContext(), \"your sdk key\");\n\n NotificationConfig notificationConfig = new NotificationConfig();\n notificationConfig.addNotificationExtender(new SaleNotificationExtender());\n notificationConfig.setContentIntentBuilder(new SaleContentIntentBuilder());\n Carnival.setNotificationConfig(notificationConfig);\n }\n}", "language": "java" } ] } [/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 `Carnival.addNotificationReceivedListener`. * To listen for tapped notifications implement `NotificationTappedListener` and add your listener using `Carnival.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 = \"NotificationLogger\";\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 @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" } ] } [/block] Then add these to `Carnival` [block:code] { "codes": [ { "code": "public class MyApplication extends Application {\n \n @Override\n public void onCreate() {\n super.onCreate();\n\n Carnival.startEngine(getApplicationContext(), \"your sdk key\");\n\n Carnival.addNotificationReceivedListener(new MyNotificationReceivedListener());\n Carnival.addNotificationTappedListener(new MyNotificationTappedListener());\n }\n}", "language": "java" } ] } [/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 return bundle.containsKey(\"silent\");\n }\n}", "language": "java" } ] } [/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\n Carnival.startEngine(getApplicationContext(), \"your sdk key\");\n NotificationConfig notificationConfig = new NotificationConfig();\n notificationConfig.setSilencer(new MyNotificationSilencer());\n Carnival.setNotificationConfig(notificationConfig);\n\n }\n}", "language": "java" } ] } [/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]