Front-End Web & Mobile
Create an Android Mobile App with Pinpoint using Mobile Hub
Amazon Pinpoint is a new AWS service that makes it easy to run targeted campaigns to improve user engagement. Amazon Pinpoint helps you understand your users’ behavior so that you can define who to target, what messages to send, and when to deliver them. Amazon Pinpoint tracks how your users interact with your app so you can monitor the impact of your campaigns.
Amazon Pinpoint provides real-time analytics with dashboards for analyzing user engagement, monetization, user demographics, custom events, and funnels so you can understand how users engage with your app. You can analyze and understand your user data by drilling down based on the segments you’ve defined, segmentation attributes, or time.
With Amazon Pinpoint, you can define target segments from various data sources. You can identify segments from app user data collected by Amazon Pinpoint. You can build custom segments from user data collected by other AWS services, such as Amazon S3 and Amazon Redshift. You can also import user segments from third party sources, such as Salesforce via S3.
Once you define your segments, Amazon Pinpoint lets you send targeted notifications with personalized messages to each user in the segment based on custom attributes, such as game level, favorite team, and news preferences. Amazon Pinpoint can send push notifications immediately, at a time you define, or as a recurring campaign. By scheduling campaigns, you can optimize the push notifications to be delivered at a specific time across multiple time zones. Amazon Pinpoint supports rich notifications, so you can send images as part of your push notifications. Amazon Pinpoint also supports silent or data notifications, which allow you to control app behavior and configuration in the background.
Once your campaign is running, Amazon Pinpoint provides metrics to track the impact of your campaign, including the number of notifications received, number of times the app was opened as a result of the notifications, time of app open, push notification opt-out rate, and revenue. You can also export event data reported by your app and run custom analytics using your existing analytics systems.
You can run A/B tests for different messages, track results, and then send the best message to your target segment.
With Amazon Pinpoint there is no minimum fee, no setup cost, and no fixed monthly cost based on your total user pool. You only pay for the number of users you target or collect events from, the messages you send, and events you collect, so you can start small and scale as your application grows.
Now let’s have a look at how you integrate Amazon Pinpoint with your app.
Requirements
Latest version Android Studio: https://developer.android.com/studio/index.html
Step 1 – Mobile Hub
Create a new Mobile Hub project from the AWS Mobile Hub console. In this example, we are naming the project PinpointMobileHub.
Enable Amazon Pinpoint by clicking User Engagement.
Enable app and campaign analytics by clicking Enable Engagement.
Choose Android and add your API Key and Sender ID.
To provide your API Key and Sender ID, refer to the next section for information on how to get these credentials from your Google Developer Project using Firebase.
Getting Sender ID and API Key
Go to https://console.firebase.google.com. Create a new Firebase project called PinpointMobileHub.
Go to your project settings by clicking on the gear icon next to your project name, and then click on Project settings.
Click on the CLOUD MESSAGING tab. Copy the Sender ID (also called Project Number) and the API Key.
Back to Mobile Hub
Provide your sender ID and server key (API Key).
Click Save changes. Click Integrate with your app . You will be redirected to the Integrate feature of Mobile Hub. Click the Android tab to download the Android Mobile Hub sample.
The Android sample contains the Amazon Pinpoint SDK, along with a Demo fragment demonstrating how to record analytics events and how to enrich an endpoint profile with custom attributes so that you can target users based on their preferences.
Mobile Hub Android Sample
Unzip the downloaded file PinpointMobileHub-aws-my-sample-app-android.zip.
Open Android Studio.
Click Open an existing Android Studio project, and navigate to the MySampleApp directory.
Android Studio will open the sample project. Now you should be able to run the sample in your device or on the simulator.
You can verify that your credentials are correct by checking the AWSConfiguration file inside the com.amazonaws.mobile package. Verify that your project contains a value for the GOOGLE_CLOUD_MESSAGING_SENDER_ID key.
Note: The Mobile Hub sample project uses the Google Cloud Messaging SDK and not the Firebase SDK. If you are using the Firebase SDK in your application, Amazon Pinpoint will still work with your project, however, there are some extra steps you will need to take to make it work correctly. See the section on Firebase integration.
Run the application on a simulator or device, if you are running the application on the simulator you need to make sure that you have logged in to Google Account on the simulator so that Push Notifications will work on the simulator. To add an account, go to Settings -> Accounts -> Add account -> Google, and log in to your account.
Demo App Analytics
On the demo application, navigate to the User Engagement section and tap on Demo App Analytics. You will see two buttons on the bottom, the left button records a custom event and the right button records a monetization event.
You can add custom attributes and metrics to an event. The sample code is the following:
final AnalyticsClient analyticsClient = AWSMobileClient.defaultMobileClient().getPinpointManager().getAnalyticsClient();
final AnalyticsEvent event = analyticsClient.createEvent(“DemoCustomEvent”) // A music app use case might include attributes such as: // .withAttribute(“Playlist”, “Amazing Songs 2015”) // .withAttribute(“Artist”, “Various”)
// .withMetric(“Song playtime”, playTime);
.withAttribute(“DemoAttribute1”, “DemoAttributeValue1”) .withAttribute(“DemoAttribute2”, “DemoAttributeValue2”) .withMetric(“DemoMetric1”, Math.random());
analyticsClient.recordEvent(event); analyticsClient.submitEvents();
The sample app records a custom event with event type _monetization.purchase. You can add also custom attributes and metrics to a monetization event. A monetization event must have a price, a product ID, a quantity, and a transaction id. The sample code is the following:
final AnalyticsClient analyticsClient = AWSMobileClient.defaultMobileClient().getPinpointManager().getAnalyticsClient();
// This creates a Google Play monetization event. To create an Amazon monetization // event instead, use AmazonMonetizationEventBuilder. final AnalyticsEvent event = GooglePlayMonetizationEventBuilder.create(analyticsClient)
.withFormattedItemPrice(“$1.00”)
.withProductId(“DEMO_PRODUCT_ID”) .withQuantity(1.0) .withTransactionId(“DEMO_TRANSACTION_ID”).build();
analyticsClient.recordEvent(event); analyticsClient.submitEvents();
Demo user engagement
We will now run through the user engagement and targeting portion of the demo and get a notification sent to the device.
Update an endpoint profile
Amazon Pinpoint is able to segment and target users based on an endpoint profile. The endpoint profile contains information about the device, such as model, make, version, etc., as well as custom attributes or metrics.
To demo the targeting feature of the demo application, navigate to the User Engagement section and tap on Demo User Engagement.
On the User Engagement demo, you will see information about your endpoint profile, such as your current locale, platform, and version. You can also set custom attributes on the endpoint profile. The demo is setting a custom attribute named `season` to signify the favorite seasons of a user.
Go ahead and select your favorite seasons, we will use it later to create a segment that targets devices with those preferences. For this example, we will select all four seasons.
The sample code to update your profile with custom attributes is the following:
.defaultMobileClient().getPinpointManager() .getTargetingClient().addAttribute(“seasons”, Arrays.asList(“winter”,”spring”,”summer”,”fall”)
.defaultMobileClient().getPinpointManager()
AWSMobileClient
.getTargetingClient().updateEndpointProfile();
Creating a campaign
Go to the Amazon Pinpoint console: https://console.aws.amazon.com/pinpoint/home/
Select the PinpointMobileHub application we created in Mobile Hub. It will be named pinpointmobilehub_MobileHub since we created the app in Mobile Hub.
Click New Campaign.
Name your campaign My first campaign, keep the campaign type as a Standard campaign, and click Next step.
Now let’s create a segment to target users that have selected `Fall` as a favorite season. Name this segment `Fall` so that we can reuse it later.
In the section Filter by custom attributes, select fall and click Next step.
Give a title and body to the notification, then click Next step.
Schedule the campaign to be Immediate so that you get the notification right away.
Review your campaign and click Launch Campaign.
If you have the sample app in the foreground, an alert will show up. If the sample app is in the background, a banner will be displayed with the notification. You can also swipe down to see the notification center.
If your app is in the background and you tap on the notification, you will be able to see notification opens metrics in the Amazon Pinpoint console as a Directly Opened metric. Click on the Campaign analytics button.
At this point you should also be able to head over to Amazon Pinpoint Analytics and see the monetization and usage data populated in the console, it may take some time for the data to update.
SDK Integration
First add the Amazon Pinpoint SDK to your Gradle Build.
dependencies {
// … other dependencies go here …
compile(‘com.amazonaws:aws-android-sdk-core:2.3.5’) // add the Amazon Pinpoint SDK dependency
compile(‘com.amazonaws:aws-android-sdk-pinpoint:2.3.5’) }
Initializing the SDK
To initialize the SDK you must instantiate an instance of the PinpointManager class:
try { final CognitoCachingCredentialsProvider cognitoCachingCredentialsProvider =
new CognitoCachingCredentialsProvider( context, ”YOUR_IDENTITY_POOL_ID”, Regions.US_EAST_1,
new ClientConfiguration() final PinpointConfiguration config =
);
new PinpointConfiguration(context, “YOUR_APP_ID”,
Regions.US_EAST_1,
cognitoCachingCredentialsProvider); this.pinpointManager = new PinpointManager(config); //Save instance of pinpointManager
} catch (final AmazonClientException ex) {
Log.e(LOG_TAG, “Unable to initalize Amazon Mobile Analytics. ” + ex.getMessage(), ex); }
Mobile Hub initializes the SDK inside its AWSMobileClient class. You may use that class to manage initialization of AWS SDKs.
Instrumenting Session Data
You must instrument session data manually on Android. You must record session start and stop events in order for Analytics to work. A session must be started before an event is recorded, and they should be stopped once the application goes into the background. Mobile Hub has an example inside its Application class utilizing the AbstractApplicationLifeCycleHelper that provides callbacks to detect when your application goes into the background and comes to the foreground.
The following example is taken from Mobile Hub’s example code:
@Override
public void onCreate() { Log.d(LOG_TAG, “Application.onCreate – Initializing application…”); super.onCreate(); initializeApplication(); Log.d(LOG_TAG, “Application.onCreate – Application initialized OK”);
}
private void initializeApplication() {
AWSMobileClient.initializeMobileClientIfNecessary(getApplicationContext());
// The Helper registers itself to receive application lifecycle events when it is constructed. // A reference is kept here in order to pass through the onTrimMemory() call from // the Application class to properly track when the application enters the background. applicationLifeCycleHelper = new AbstractApplicationLifeCycleHelper(this) {
@Override
protected void applicationEnteredForeground() {
final PinpointManager pinpointManager = AWSMobileClient.defaultMobileClient()
.getPinpointManager(); pinpointManager.getSessionClient().startSession(); // handle any events that should occur when your app has come to the foreground…
}
@Override
protected void applicationEnteredBackground() { Log.d(LOG_TAG, “Detected application has entered the background.”); final PinpointManager pinpointManager = AWSMobileClient.defaultMobileClient()
.getPinpointManager(); pinpointManager.getSessionClient().stopSession(); pinpointManager.getAnalyticsClient().submitEvents(); // handle any events that should occur when your app has gone into the background…
} };
// …Put any application-specific initialization logic here…
}
@Override
public void onTrimMemory(final int level) { Log.d(LOG_TAG, “onTrimMemory ” + level); applicationLifeCycleHelper.handleOnTrimMemory(level); super.onTrimMemory(level);
}
Setting up push notification with GCM
The SDK needs to register the device token received from GCM with the endpoint profile. Implement the GCMTokenUpdateObserver in a class and override the onGCMTokenUpdate method. The following example is taken from Mobile Hub’s example code:
@Override
public void onGCMTokenUpdate(final String gcmToken, final boolean didTokenChange) { if (didTokenChange) {
Log.d(LOG_TAG, “GCM Token changed, registering for Campaign push.”);
// Register the Device Token to receive Campaign Push.
final NotificationClient notificationClient = AWSMobileClient.defaultMobileClient()
.getPinpointManager()
.getNotificationClient(); notificationClient.registerGCMDeviceToken(gcmToken);
} }
On your class that extends the GcmListenerService add the following code inside the onMessageReceived method:
AWSMobileClient.initializeMobileClientIfNecessary(this.getApplicationContext()); final NotificationClient notificationClient = AWSMobileClient.defaultMobileClient()
.getPinpointManager().getNotificationClient(); NotificationClient.CampaignPushResult pushResult =
notificationClient.handleGCMCampaignPush(from, data, this.getClass());
if (!NotificationClient.CampaignPushResult.NOT_HANDLED.equals(pushResult)) { if (NotificationClient.CampaignPushResult.APP_IN_FOREGROUND.equals(pushResult)) {
// You can handle the notification any way you like if the app is in the foreground.
}
return;
}
Add the following declarations to your AndroidManifest.xml. In this example taken from Mobile Hub, we register the PushListernerService to handle messages.
<uses-permission android:name=”android.permission.WAKE_LOCK”/> <uses-permission android:name=”com.google.android.c2dm.permission.RECEIVE” /> <permission android:name=”com.amazon.mysampleapp.permission.C2D_MESSAGE”
android:protectionLevel=”signature” />
<uses-permission android:name=”com.amazon.mysampleapp.permission.C2D_MESSAGE” />
<application
…
<receiver
android:name=”com.google.android.gms.gcm.GcmReceiver” android:exported=”true” android:permission=”com.google.android.c2dm.permission.SEND” > <intent-filter>
<action android:name=”com.google.android.c2dm.intent.RECEIVE” />
<category android:name=”@string/google_cloud_messaging_package” /> </intent-filter>
</receiver>
<!– BEGIN – PUSH NOTIFICATIONS WITH GOOGLE CLOUD MESSAGING (GCM) –>
<service
android:name=”.PushListenerService” android:exported=”false” > <intent-filter>
<action android:name=”com.google.android.c2dm.intent.RECEIVE” /> </intent-filter>
</service>
Setting up push notification with Firebase
The SDK needs to register the device token received from FCM with the endpoint profile. Extend the FirebaseInstanceIdService in a class, and override the onTokenRefresh method.
On your class that extends the FirebaseMessagingService, add the following code inside the onMessageReceived method:
@Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken(); AWSMobileClient.defaultMobileClient().getPinpointManager()
.getNotificationClient().registerGCMDeviceToken(refreshedToken); }
NotificationClient.CampaignPushResult pushResult = AWSMobileClient.defaultMobileClient().getPinpointManager().
getNotificationClient().handleFCMCampaignPush( remoteMessage.getFrom(), remoteMessage.getData());
if (!NotificationClient.CampaignPushResult.NOT_HANDLED.equals(pushResult)) { if (NotificationClient.CampaignPushResult.APP_IN_FOREGROUND.equals(pushResult)) {
// You can handle the notification any way you like if the app is in the foreground.
}
return;
}
Add the following declarations to your AndroidManifest.xml. You must register this receiver so that we can launch the app when the user taps on the notification.
<receiver
android:name=”com.amazonaws.mobileconnectors.pinpoint.targeting.notification.PinpointNotificationReceiver” android:exported=”false” > <intent-filter>
<action android:name=”com.amazonaws.intent.fcm.NOTIFICATION_OPEN” /> </intent-filter>
</receiver>