{"_id":"5d728eeec7ca1001f9550ed0","project":"55dd9f2e0efd5821000d54d9","version":{"_id":"55dd9f4dab0e4d210045aae9","__v":45,"project":"55dd9f2e0efd5821000d54d9","createdAt":"2015-08-26T11:13:17.024Z","releaseDate":"2015-08-26T11:13:17.024Z","categories":["55dd9f4dab0e4d210045aaea","55ddb5fa9067202b00ddff6f","55e0472c6bad670d0081f213","55e04764a44fae0d00214671","55e047a9a44fae0d00214672","55e047b258c5460d0076a9a7","55e95e337fc27b2d00d32cf2","55e979bda7ca823900ad549a","55edb8c18dcb210d0056900b","55f0365c8563861700a33765","55f03677d58f9b1900acf996","55f036938eeefc23001ea5de","55f036a38563861700a33767","55f036c08563861700a33769","55f036d02911b72100482cd7","55f036e92911b72100482cd9","55f036fa8563861700a3376b","55f0370ee507711900e58c69","55f0371df6101b1900c70700","55f0374f2911b72100482cdb","55f0375e2911b72100482cdc","560eb0f659cb8d0d0015cd52","560eb25239fad419002ae1e0","561fb64d4d67490d00804b2a","562b9f775a39cd0d009aff22","562ba0505a39cd0d009aff23","562ba149d56bc30d00f0cb18","562ba595f68a5f0d007b1f3b","562ba78fd56bc30d00f0cb1b","562ba8b95a39cd0d009aff27","562baadf6562140d001501d2","562bab37f68a5f0d007b1f3d","562bc1bf9ebc950d000f7523","562bc99ced4bea0d00c11dfa","562bd29c1b98640d00714520","562bd5875a39cd0d009aff60","562bdfabff2da50d002c0aaf","562be0bd5a39cd0d009aff75","57a0b476d8313e1900454439","5b19051beece890003020163","5b34ded01cb20f000391ad6d","5b3a325acffe770003fd29e5","5b3c737a7f7b890003365501","5b3c929b367036000391b11e","5b7c1e210dc2e20003871521"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"2.0.0","version":"2"},"category":{"_id":"5b34ded01cb20f000391ad6d","project":"55dd9f2e0efd5821000d54d9","version":"55dd9f4dab0e4d210045aae9","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2018-06-28T13:12:48.898Z","from_sync":false,"order":1,"slug":"push-notifications","title":"Push notifications"},"user":"55114030a226890d00911658","__v":0,"parentDoc":null,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2019-09-06T16:53:02.299Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"settings":"","results":{"codes":[]},"auth":"required","params":[],"url":""},"isReference":false,"order":9,"body":"Our Android App Messaging SDK uses [Firebase Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging/) to send push notifications to your Android app users.\n\nTo embed in your native Android apps, complete the following tasks:\n\n1. [Install the SDK](#section-installing-the-sdk)\n2. [Configure the SDK](#section-configuring-the-android-sdk)\n3. [Initialise the SDK](#section-initialising-the-android-sdk)\n4. *Optional:* [Change the icon or colour of your push notifications](#section-changing-the-icon-or-colour-of-push-notification)\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"You can use either standard callbacks or observable streams to handle asynchronous requests. If you want to use observable streams, you need to add the RxJava library to your app. This tutorial explains how to use standard callbacks, but you can find a full sample of the RxJava code in the ['Android sample code' section](#section-android-sample-code).\",\n  \"title\": \"Handling asynchronous requests\"\n}\n[/block]\n# Installing the SDK\n\n1. Add the App Messaging SDK to your module-level `build.gradle` file and change the `minSDKVersion` attribute to 16 using the snippet below:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"defaultConfig {\\n...\\nminSdkVersion 16\\n...\\n}\\nDependencies {\\n...\\nimplementation 'com.comapi:foundation:1.2.0'\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"body\": \"The SDK has a `minSDKVersion` attribute of 16, your attribute must have a value of at least 16.\",\n  \"title\": \"Seeing a 'Manifest merger' error?\"\n}\n[/block]\n2. Add the Google services plugin to your module-level `build.gradle` file using the snippet below:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"apply plugin: 'com.google.gms.google-services'\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n3. Add the following dependencies to your module-level `build.gradle` file using the snippet below:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"implementation ('com.google.android.gms:play-services-base:15.0.1') {force = true}\\nimplementation ('com.google.firebase:firebase-messaging:17.0.0') {force = true}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"success\",\n  \"body\": \"Remember to synchronise `build.gradle` files after making any changes.\",\n  \"title\": \"Sync Now\"\n}\n[/block]\n# Configuring the Android SDK\n\nBefore you can configure the Android SDK, you need the following:\n\n* The value of the [API space ID field in Engagement Cloud](doc:creating-a-push-notification-profile-new#section-finding-your-api-space-id)\n* A class that [creates a JWT token](https://developer.dotdigital.com/v2/docs/creating-a-json-web-token-new#section-android-jwt-code-sample)\n\n1. Create a new instance of the `ComapiConfig` class, pass your API Space Id to the `apiSpaceId()` method, and an instance of the class that creates a JWT to the `authenticator()` method using the snippet below:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"ComapiConfig config = new ComapiConfig() .apiSpaceId(\\\"<API_SPACE_ID>\\\") .authenticator(new ChallengeHandler());\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n## Displaying push notifications when the app is in the foreground\n\nPush notifications are automatically displayed only while the app is in the background. These notifications are sent to the system tray and launch your app when users tap them.\n\nIf you want to display the push notification message while the app is in the foreground, do the following:\n\n1. Create a class that implements the `pushMessageListener` class (here, we've called the example class `PushHandler`). You'll need to decide what you want to do with the push notification and implement the logic by overriding the `onMessageReceived()` [method](https://firebase.google.com/docs/cloud-messaging/android/receive). This method is called when a push notification is received while the app is in the foreground.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"If a push notification is delivered while the app is in the foreground, you can build your own in the 'onMessageReceived()` method that [creates a link to a particular activity in your app](https://developer.android.com/training/notify-user/build-notification#click).\",\n  \"title\": \"Deep links\"\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class PushHandler implements PushMessageListener {\\n\\n    :::at:::Override\\n    public void onMessageReceived(RemoteMessage message) {\\n      // Check if message contains a notification payload.\\n        if (message.getNotification() != null) {\\n        Log.i(\\\"TAG\\\", \\\"Push notification: \\\" + message.getNotification().getBody());\\n      // Do something with the message to notify the user\\n          // Example\\n          createNotificationChannel(context);\\n          Notification.Builder b = new Notification.Builder(context);\\n          b.setAutoCancel(true)\\n            .setDefaults(NotificationCompat.DEFAULT_ALL)\\n            .setWhen(System.currentTimeMillis())\\n            .setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)\\n            .setContentTitle(\\\"foreground message\\\")\\n            .setContentText(body)\\n            .setContentInfo(\\\"INFO\\\");\\n          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\\n            b.setChannelId(\\\"test_channel_id1\\\");\\n          }\\n          NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);\\n          nm.notify(1, b.build());\\n        }\\n    }\\n}\\n\\nprivate void createNotificationChannel(Context context) {\\n        // Create the NotificationChannel, but only on devices that have the Google API 26+ because the NotificationChannel class is new and not in supported in older libraries\\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\\n            CharSequence name = \\\"test channel\\\";\\n            String description = \\\"some description\\\";\\n            int importance = NotificationManager.IMPORTANCE_DEFAULT;\\n            NotificationChannel channel = new NotificationChannel(\\\"test_channel_id1\\\", name, importance);\\n            channel.setDescription(description);\\n            // Register the channel with the system; you can't change the importance\\n            // or other notification behaviors after this\\n            NotificationManager notificationManager = context.getSystemService(NotificationManager.class);\\n            notificationManager.createNotificationChannel(channel);\\n        }\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n2. Pass your class to the `pushMessageListener()` on the `ComapiConfig` object \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"config.pushMessageListener(new PushHandler());\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n## Configuring logs and proxy servers\n\nYou can set internal file logs, console logs, and network logs to the following levels. By default all log levels are set to `WARNING`:\n\n* `OFF`\n* `FATAL`\n* `ERROR`\n* `WARNING`\n* `INFO`\n* `DEBUG`\n\nTo change the log levels, add the following line to the `ComapiConfig` object and use the appropriate method on the `LogConfig` object:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \".logConfig(new LogConfig().setFileLevel(LogLevel.DEBUG).setConsoleLevel(LogLevel.INFO).setNetworkLevel(LogLevel.ERROR));\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nYou can also set a custom limit for the size of internal log files by calling the following method on the `ComapiConfig` object:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \".logSizeLimitKilobytes(limit);\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nIf your app connects through a proxy server, add the following line to the `ComapiConfig` object:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \".apiConfiguration(new APIConfig().proxy(\\\"http://xx.xxx.xx.xxx:xxxx\\\"));\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n# Initialising the Android SDK\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"body\": \"Initialisation needs to be performed in the `onCreate()` [method](https://developer.android.com/reference/android/app/Application#onCreate() of the Android `Application` class so that your app users' profiles don't change every time they open the app.\",\n  \"title\": \"Where to initialise the Android SDK in the activity lifecycle\"\n}\n[/block]\n1. After you've configured the SDK, import the `com.google.firebase.FirebaseApp` class into your java file, and initialise the Firebase SDK.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"FirebaseApp.initializeApp(this);\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n2 Pass the `ComapiConfig` object to one of the following initialisation methods. These methods return a `ComapiClient` object that you can use to access the `session` and `profile` services, which are used to create and update the user's profile.\n\n* The `initialiseShared()` method: When you use this method, the SDK stores the  'ComapiClient' object, and you can access it at any time by calling the `Comapi.getShared()` method (Java) or the `RxComapi.getShared()` method (RxJava)\n* The `initialise()` method:  When you use this method, you need to store the `ComapiClient` object yourself. The `getShared()` method is not available when you use this method.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class MyApplication extends Application {\\n\\n    @Override\\n    public void onCreate()\\n    {\\n        super.onCreate();\\n      \\n      \\tFirebaseApp.initializeApp(this);\\n\\n        ComapiConfig config = new ComapiConfig();\\n        //<API space ID> string must be the same as the value of the 'API space ID' field in your push notification profile in Engagement Cloud. \\n        config.apiSpaceId(\\\"<API space ID>\\\");\\n        //Set handler for authentication challenges (SDK asks for a JWT token)\\n        config.authenticator(new ChallengeHandler());\\n\\n        Comapi.initialiseShared(this, config, new Callback<ComapiClient>() {\\n            @Override\\n            public void success(final ComapiClient client) {\\n              //Use ComapiClient object to communicate with services\\n            }\\n            @Override\\n            public void error(Throwable t) {\\n\\t\\t\\t\\t\\t\\t\\t//Error\\n            }\\n        }); \",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n# Changing the icon or colour of push notification\n\nOur Android SDK uses [Firebase Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging/) to send push notifications to your Android app users. As such, you can use the Android `<meta-data>` [tag](https://developer.android.com/guide/topics/manifest/meta-data-element) in your `AndroidManifest.xml` file to change the icon and colour of your push notifications.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<!-- Set icon used with incoming notification messages. This is used when no icon is set for the incoming notification message. -->\\n<meta-data\\nandroid:name=\\\"com.google.firebase.messaging.default_notification_icon\\\"\\nandroid:resource=\\\"@mipmap/ic_launcher_round\\\" />\\n<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming notification message. -->\\n<meta-data\\nandroid:name=\\\"com.google.firebase.messaging.default_notification_color\\\"\\nandroid:resource=\\\"@color/colorAccent\\\" />\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"success\",\n  \"body\": \"Now ensure your app passes an email address to the SDK for the app user to ensure they get a contact created in Engagement Cloud by [following these instructions](setting-up-push-notifications-new#section-pass-app-user-information-to-the-sdk)\",\n  \"title\": \"Next steps\"\n}\n[/block]\n# Android Sample Code\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"package com.example.testapp;\\n\\nimport com.google.firebase.FirebaseApp;\\n\\nimport com.comapi.Comapi;\\nimport com.comapi.ComapiClient;\\nimport android.app.Application;\\n\\nimport com.comapi.Callback;\\nimport com.comapi.ComapiConfig;\\nimport com.comapi.Session;\\nimport com.comapi.internal.network.ComapiResult;\\n\\nimport java.util.HashMap;\\nimport java.util.Map;\\n\\npublic class MyApplication extends Application {\\n\\n  @Override\\n  public void onCreate()\\n  {\\n    super.onCreate();\\n    \\n    FirebaseApp.initializeApp(this);\\n\\n    ComapiConfig config = new ComapiConfig();\\n    //<API space ID> string must be the same as the value of the 'API space ID' field in your push notification profile in Engagement Cloud.\\n    config.apiSpaceId(\\\"<API space ID>\\\");\\n    //Set the handler for authentication challenges (SDK asking for JWT token)\\n    config.authenticator(new AuthChallengeHandler());\\n\\n    Comapi.initialiseShared(this, config, new Callback<ComapiClient>() {\\n      @Override\\n      public void success(final ComapiClient client) {\\n        if(client.getSession() != null && client.getSession().isSuccessfullyCreated()) {\\n          client.service().profile().getProfile(client.getSession().getProfileId(), new Callback<ComapiResult<Map<String, Object>>>() {\\n            @Override\\n            public void success(ComapiResult<Map<String, Object>> result) {\\n              Map <String, Object> additionalMap = new HashMap<>();\\n              //Add the user's email address to the profile\\n              additionalMap.put(\\\"email\\\", \\\"exampleappuser1@gmail.com\\\");\\n              client.service().profile().patchMyProfile(additionalMap, result.getETag(), new Callback<ComapiResult<Map<String, Object>>>() {\\n                @Override\\n                public void success(ComapiResult<Map<String, Object>> result) {\\n                }\\n                @Override\\n                public void error(Throwable t) {\\n                }\\n              });\\n            }\\n            @Override\\n            public void error(Throwable t) {\\n            }\\n          }\\n                                               );\\n        } else {\\n          client.service().session().startSession(new Callback<Session>() {\\n            @Override\\n            public void success(Session result) {\\n\\n            }\\n\\n            @Override\\n            public void error(Throwable t) {\\n\\n            }\\n          });\\n        }\\n\\n      }\\n\\n      @Override\\n      public void error(Throwable t) {\\n        //Error\\n      }\\n    });\\n  }\\n}\",\n      \"language\": \"java\",\n      \"name\": \"Java sample application\"\n    }\n  ]\n}\n[/block]\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"package com.example.testapp;\\n\\nimport android.app.Application;\\n\\nimport com.google.firebase.FirebaseApp;\\n\\nimport com.comapi.ComapiConfig;\\nimport com.comapi.RxComapi;\\nimport com.comapi.RxComapiClient;\\nimport com.comapi.internal.network.ComapiResult;\\n\\nimport java.util.HashMap;\\nimport java.util.Map;\\n\\nimport rx.Observable;\\nimport rx.Subscriber;\\nimport rx.functions.Func1;\\n\\npublic class MyApplication extends Application {\\n\\n  @Override\\n  public void onCreate()\\n  {\\n    super.onCreate();\\n    \\n    FirebaseApp.initializeApp(this);\\n\\n    RxComapi.initialise(\\n      this, new ComapiConfig()\\n      //<API space ID> string must be the same as the value of the 'API space ID' field in your push notification profile in Engagement Cloud.\\n      .apiSpaceId(\\\"<API space ID>\\\")\\n      //Set the handler for authentication challenges (SDK asking for JWT token)\\n      .authenticator(new ChallengeHandler(getSharedPreferences(Const.PREFS_NAME, MODE_PRIVATE)))\\n    ).flatMap(new Func1<RxComapiClient, Observable<RxComapiClient>>() {\\n      @Override\\n      public Observable<RxComapiClient> call(final RxComapiClient client) {\\n        if (client.getSession() != null && client.getSession().isSuccessfullyCreated()) {  \\n            return Observable.fromCallable(new Callable<RxComapiClient>() {\\n              @Override\\n              public RxComapiClient call() throws Exception {\\n                return client;\\n              }\\n            });\\n          } else {\\n            return client.service().session().startSession().map(new Func1<Session, RxComapiClient>() {\\n              @Override\\n              public RxComapiClient call(Session session) {\\n                return client;\\n              }\\n            });\\n        }\\n      }\\n    }).flatMap(new Func1<RxComapiClient, Observable<ComapiResult<Map<String, Object>>>>() {\\n      @Override\\n      public Observable<ComapiResult<Map<String, Object>>> call(final RxComapiClient client) {\\n        if (!client.getSession().isSuccessfullyCreated()) {\\n          return Observable.error(new Exception(\\\"Failed to update profile\\\"));\\n        }\\n        return client.service()\\n          .profile()\\n          .getProfile(client.getSession().getProfileId())\\n          .flatMap(new Func1<ComapiResult<Map<String, Object>>, Observable<ComapiResult<Map<String, Object>>>>() {\\n            @Override\\n            public Observable<ComapiResult<Map<String, Object>>> call(ComapiResult<Map<String, Object>> result) {\\n              Map<String, Object> additionalMap = new HashMap<>();\\n              //Add the user's email address to the profile\\n              additionalMap.put(\\\"email\\\", \\\"exampleappuser1@gmail.com\\\");\\n              return client.service().profile().patchMyProfile(additionalMap, result.getETag());\\n            }\\n          }\\n                  );\\n      }\\n    }).subscribe(new Subscriber<ComapiResult<Map<String, Object>>>() {\\n      @Override\\n      public void onCompleted() {\\n      }\\n      @Override\\n      public void onError(Throwable e) {\\n      }\\n      @Override\\n      public void onNext(ComapiResult<Map<String, Object>> result) {\\n      }\\n    });\\n  }\\n}\\n\",\n      \"language\": \"java\",\n      \"name\": \"RxJava sample application\"\n    }\n  ]\n}\n[/block]","excerpt":"A tutorial for adding the Android App Messaging SDK code to your app to allow your app users to receive push notifications from your Engagement Cloud account","slug":"android-sdk-new","type":"basic","title":"Using the Android App Messaging SDK"}

Using the Android App Messaging SDK

A tutorial for adding the Android App Messaging SDK code to your app to allow your app users to receive push notifications from your Engagement Cloud account

Our Android App Messaging SDK uses [Firebase Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging/) to send push notifications to your Android app users. To embed in your native Android apps, complete the following tasks: 1. [Install the SDK](#section-installing-the-sdk) 2. [Configure the SDK](#section-configuring-the-android-sdk) 3. [Initialise the SDK](#section-initialising-the-android-sdk) 4. *Optional:* [Change the icon or colour of your push notifications](#section-changing-the-icon-or-colour-of-push-notification) [block:callout] { "type": "info", "body": "You can use either standard callbacks or observable streams to handle asynchronous requests. If you want to use observable streams, you need to add the RxJava library to your app. This tutorial explains how to use standard callbacks, but you can find a full sample of the RxJava code in the ['Android sample code' section](#section-android-sample-code).", "title": "Handling asynchronous requests" } [/block] # Installing the SDK 1. Add the App Messaging SDK to your module-level `build.gradle` file and change the `minSDKVersion` attribute to 16 using the snippet below: [block:code] { "codes": [ { "code": "defaultConfig {\n...\nminSdkVersion 16\n...\n}\nDependencies {\n...\nimplementation 'com.comapi:foundation:1.2.0'\n}", "language": "java" } ] } [/block] [block:callout] { "type": "warning", "body": "The SDK has a `minSDKVersion` attribute of 16, your attribute must have a value of at least 16.", "title": "Seeing a 'Manifest merger' error?" } [/block] 2. Add the Google services plugin to your module-level `build.gradle` file using the snippet below: [block:code] { "codes": [ { "code": "apply plugin: 'com.google.gms.google-services'", "language": "java" } ] } [/block] 3. Add the following dependencies to your module-level `build.gradle` file using the snippet below: [block:code] { "codes": [ { "code": "implementation ('com.google.android.gms:play-services-base:15.0.1') {force = true}\nimplementation ('com.google.firebase:firebase-messaging:17.0.0') {force = true}", "language": "java" } ] } [/block] [block:callout] { "type": "success", "body": "Remember to synchronise `build.gradle` files after making any changes.", "title": "Sync Now" } [/block] # Configuring the Android SDK Before you can configure the Android SDK, you need the following: * The value of the [API space ID field in Engagement Cloud](doc:creating-a-push-notification-profile-new#section-finding-your-api-space-id) * A class that [creates a JWT token](https://developer.dotdigital.com/v2/docs/creating-a-json-web-token-new#section-android-jwt-code-sample) 1. Create a new instance of the `ComapiConfig` class, pass your API Space Id to the `apiSpaceId()` method, and an instance of the class that creates a JWT to the `authenticator()` method using the snippet below: [block:code] { "codes": [ { "code": "ComapiConfig config = new ComapiConfig() .apiSpaceId(\"<API_SPACE_ID>\") .authenticator(new ChallengeHandler());", "language": "java" } ] } [/block] ## Displaying push notifications when the app is in the foreground Push notifications are automatically displayed only while the app is in the background. These notifications are sent to the system tray and launch your app when users tap them. If you want to display the push notification message while the app is in the foreground, do the following: 1. Create a class that implements the `pushMessageListener` class (here, we've called the example class `PushHandler`). You'll need to decide what you want to do with the push notification and implement the logic by overriding the `onMessageReceived()` [method](https://firebase.google.com/docs/cloud-messaging/android/receive). This method is called when a push notification is received while the app is in the foreground. [block:callout] { "type": "info", "body": "If a push notification is delivered while the app is in the foreground, you can build your own in the 'onMessageReceived()` method that [creates a link to a particular activity in your app](https://developer.android.com/training/notify-user/build-notification#click).", "title": "Deep links" } [/block] [block:code] { "codes": [ { "code": "public class PushHandler implements PushMessageListener {\n\n @Override\n public void onMessageReceived(RemoteMessage message) {\n // Check if message contains a notification payload.\n if (message.getNotification() != null) {\n Log.i(\"TAG\", \"Push notification: \" + message.getNotification().getBody());\n // Do something with the message to notify the user\n // Example\n createNotificationChannel(context);\n Notification.Builder b = new Notification.Builder(context);\n b.setAutoCancel(true)\n .setDefaults(NotificationCompat.DEFAULT_ALL)\n .setWhen(System.currentTimeMillis())\n .setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)\n .setContentTitle(\"foreground message\")\n .setContentText(body)\n .setContentInfo(\"INFO\");\n if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n b.setChannelId(\"test_channel_id1\");\n }\n NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);\n nm.notify(1, b.build());\n }\n }\n}\n\nprivate void createNotificationChannel(Context context) {\n // Create the NotificationChannel, but only on devices that have the Google API 26+ because the NotificationChannel class is new and not in supported in older libraries\n if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n CharSequence name = \"test channel\";\n String description = \"some description\";\n int importance = NotificationManager.IMPORTANCE_DEFAULT;\n NotificationChannel channel = new NotificationChannel(\"test_channel_id1\", name, importance);\n channel.setDescription(description);\n // Register the channel with the system; you can't change the importance\n // or other notification behaviors after this\n NotificationManager notificationManager = context.getSystemService(NotificationManager.class);\n notificationManager.createNotificationChannel(channel);\n }\n}", "language": "java" } ] } [/block] 2. Pass your class to the `pushMessageListener()` on the `ComapiConfig` object [block:code] { "codes": [ { "code": "config.pushMessageListener(new PushHandler());", "language": "java" } ] } [/block] ## Configuring logs and proxy servers You can set internal file logs, console logs, and network logs to the following levels. By default all log levels are set to `WARNING`: * `OFF` * `FATAL` * `ERROR` * `WARNING` * `INFO` * `DEBUG` To change the log levels, add the following line to the `ComapiConfig` object and use the appropriate method on the `LogConfig` object: [block:code] { "codes": [ { "code": ".logConfig(new LogConfig().setFileLevel(LogLevel.DEBUG).setConsoleLevel(LogLevel.INFO).setNetworkLevel(LogLevel.ERROR));", "language": "java" } ] } [/block] You can also set a custom limit for the size of internal log files by calling the following method on the `ComapiConfig` object: [block:code] { "codes": [ { "code": ".logSizeLimitKilobytes(limit);", "language": "java" } ] } [/block] If your app connects through a proxy server, add the following line to the `ComapiConfig` object: [block:code] { "codes": [ { "code": ".apiConfiguration(new APIConfig().proxy(\"http://xx.xxx.xx.xxx:xxxx\"));", "language": "java" } ] } [/block] # Initialising the Android SDK [block:callout] { "type": "warning", "body": "Initialisation needs to be performed in the `onCreate()` [method](https://developer.android.com/reference/android/app/Application#onCreate() of the Android `Application` class so that your app users' profiles don't change every time they open the app.", "title": "Where to initialise the Android SDK in the activity lifecycle" } [/block] 1. After you've configured the SDK, import the `com.google.firebase.FirebaseApp` class into your java file, and initialise the Firebase SDK. [block:code] { "codes": [ { "code": "FirebaseApp.initializeApp(this);", "language": "java" } ] } [/block] 2 Pass the `ComapiConfig` object to one of the following initialisation methods. These methods return a `ComapiClient` object that you can use to access the `session` and `profile` services, which are used to create and update the user's profile. * The `initialiseShared()` method: When you use this method, the SDK stores the 'ComapiClient' object, and you can access it at any time by calling the `Comapi.getShared()` method (Java) or the `RxComapi.getShared()` method (RxJava) * The `initialise()` method: When you use this method, you need to store the `ComapiClient` object yourself. The `getShared()` method is not available when you use this method. [block:code] { "codes": [ { "code": "public class MyApplication extends Application {\n\n @Override\n public void onCreate()\n {\n super.onCreate();\n \n \tFirebaseApp.initializeApp(this);\n\n ComapiConfig config = new ComapiConfig();\n //<API space ID> string must be the same as the value of the 'API space ID' field in your push notification profile in Engagement Cloud. \n config.apiSpaceId(\"<API space ID>\");\n //Set handler for authentication challenges (SDK asks for a JWT token)\n config.authenticator(new ChallengeHandler());\n\n Comapi.initialiseShared(this, config, new Callback<ComapiClient>() {\n @Override\n public void success(final ComapiClient client) {\n //Use ComapiClient object to communicate with services\n }\n @Override\n public void error(Throwable t) {\n\t\t\t\t\t\t\t//Error\n }\n }); ", "language": "java" } ] } [/block] # Changing the icon or colour of push notification Our Android SDK uses [Firebase Cloud Messaging (FCM)](https://firebase.google.com/docs/cloud-messaging/) to send push notifications to your Android app users. As such, you can use the Android `<meta-data>` [tag](https://developer.android.com/guide/topics/manifest/meta-data-element) in your `AndroidManifest.xml` file to change the icon and colour of your push notifications. [block:code] { "codes": [ { "code": "<!-- Set icon used with incoming notification messages. This is used when no icon is set for the incoming notification message. -->\n<meta-data\nandroid:name=\"com.google.firebase.messaging.default_notification_icon\"\nandroid:resource=\"@mipmap/ic_launcher_round\" />\n<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming notification message. -->\n<meta-data\nandroid:name=\"com.google.firebase.messaging.default_notification_color\"\nandroid:resource=\"@color/colorAccent\" />", "language": "java" } ] } [/block] [block:callout] { "type": "success", "body": "Now ensure your app passes an email address to the SDK for the app user to ensure they get a contact created in Engagement Cloud by [following these instructions](setting-up-push-notifications-new#section-pass-app-user-information-to-the-sdk)", "title": "Next steps" } [/block] # Android Sample Code [block:code] { "codes": [ { "code": "package com.example.testapp;\n\nimport com.google.firebase.FirebaseApp;\n\nimport com.comapi.Comapi;\nimport com.comapi.ComapiClient;\nimport android.app.Application;\n\nimport com.comapi.Callback;\nimport com.comapi.ComapiConfig;\nimport com.comapi.Session;\nimport com.comapi.internal.network.ComapiResult;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class MyApplication extends Application {\n\n @Override\n public void onCreate()\n {\n super.onCreate();\n \n FirebaseApp.initializeApp(this);\n\n ComapiConfig config = new ComapiConfig();\n //<API space ID> string must be the same as the value of the 'API space ID' field in your push notification profile in Engagement Cloud.\n config.apiSpaceId(\"<API space ID>\");\n //Set the handler for authentication challenges (SDK asking for JWT token)\n config.authenticator(new AuthChallengeHandler());\n\n Comapi.initialiseShared(this, config, new Callback<ComapiClient>() {\n @Override\n public void success(final ComapiClient client) {\n if(client.getSession() != null && client.getSession().isSuccessfullyCreated()) {\n client.service().profile().getProfile(client.getSession().getProfileId(), new Callback<ComapiResult<Map<String, Object>>>() {\n @Override\n public void success(ComapiResult<Map<String, Object>> result) {\n Map <String, Object> additionalMap = new HashMap<>();\n //Add the user's email address to the profile\n additionalMap.put(\"email\", \"exampleappuser1@gmail.com\");\n client.service().profile().patchMyProfile(additionalMap, result.getETag(), new Callback<ComapiResult<Map<String, Object>>>() {\n @Override\n public void success(ComapiResult<Map<String, Object>> result) {\n }\n @Override\n public void error(Throwable t) {\n }\n });\n }\n @Override\n public void error(Throwable t) {\n }\n }\n );\n } else {\n client.service().session().startSession(new Callback<Session>() {\n @Override\n public void success(Session result) {\n\n }\n\n @Override\n public void error(Throwable t) {\n\n }\n });\n }\n\n }\n\n @Override\n public void error(Throwable t) {\n //Error\n }\n });\n }\n}", "language": "java", "name": "Java sample application" } ] } [/block] [block:code] { "codes": [ { "code": "package com.example.testapp;\n\nimport android.app.Application;\n\nimport com.google.firebase.FirebaseApp;\n\nimport com.comapi.ComapiConfig;\nimport com.comapi.RxComapi;\nimport com.comapi.RxComapiClient;\nimport com.comapi.internal.network.ComapiResult;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport rx.Observable;\nimport rx.Subscriber;\nimport rx.functions.Func1;\n\npublic class MyApplication extends Application {\n\n @Override\n public void onCreate()\n {\n super.onCreate();\n \n FirebaseApp.initializeApp(this);\n\n RxComapi.initialise(\n this, new ComapiConfig()\n //<API space ID> string must be the same as the value of the 'API space ID' field in your push notification profile in Engagement Cloud.\n .apiSpaceId(\"<API space ID>\")\n //Set the handler for authentication challenges (SDK asking for JWT token)\n .authenticator(new ChallengeHandler(getSharedPreferences(Const.PREFS_NAME, MODE_PRIVATE)))\n ).flatMap(new Func1<RxComapiClient, Observable<RxComapiClient>>() {\n @Override\n public Observable<RxComapiClient> call(final RxComapiClient client) {\n if (client.getSession() != null && client.getSession().isSuccessfullyCreated()) { \n return Observable.fromCallable(new Callable<RxComapiClient>() {\n @Override\n public RxComapiClient call() throws Exception {\n return client;\n }\n });\n } else {\n return client.service().session().startSession().map(new Func1<Session, RxComapiClient>() {\n @Override\n public RxComapiClient call(Session session) {\n return client;\n }\n });\n }\n }\n }).flatMap(new Func1<RxComapiClient, Observable<ComapiResult<Map<String, Object>>>>() {\n @Override\n public Observable<ComapiResult<Map<String, Object>>> call(final RxComapiClient client) {\n if (!client.getSession().isSuccessfullyCreated()) {\n return Observable.error(new Exception(\"Failed to update profile\"));\n }\n return client.service()\n .profile()\n .getProfile(client.getSession().getProfileId())\n .flatMap(new Func1<ComapiResult<Map<String, Object>>, Observable<ComapiResult<Map<String, Object>>>>() {\n @Override\n public Observable<ComapiResult<Map<String, Object>>> call(ComapiResult<Map<String, Object>> result) {\n Map<String, Object> additionalMap = new HashMap<>();\n //Add the user's email address to the profile\n additionalMap.put(\"email\", \"exampleappuser1@gmail.com\");\n return client.service().profile().patchMyProfile(additionalMap, result.getETag());\n }\n }\n );\n }\n }).subscribe(new Subscriber<ComapiResult<Map<String, Object>>>() {\n @Override\n public void onCompleted() {\n }\n @Override\n public void onError(Throwable e) {\n }\n @Override\n public void onNext(ComapiResult<Map<String, Object>> result) {\n }\n });\n }\n}\n", "language": "java", "name": "RxJava sample application" } ] } [/block]