Amazon Device Messaging (ADM) is the recommended method for sending push notifications to the Kindle. Unfortunately we cannot use Google Cloud Messaging (GCM) as it relies on the Google Services Framework which is not installed on the Kindle. This article will provide some direction on how to utilize ADM in your app using Xamarin.

CODE WALKTHROUGH

SERVER

Before we dive into the Xamarin code, a server needs to be setup to send the ADM push notifications. Below is an example of how to do this in .NET using PushSharp. PushSharp is available via NuGet or directly at https://github.com/Redth/PushSharp

private void SendADMPushNotification(String clientId, String clientSecret, String registrationId, String dataXml)
{
  var settings = new PushSharp.Amazon.Adm.AdmPushChannelSettings(clientId, clientSecret);
  var channel = new PushSharp.Amazon.Adm.AdmPushChannel(settings);
  var notification = new PushSharp.Amazon.Adm.AdmNotification();

  notification.Data.Add("data", dataXml);
  notification.RegistrationId = registrationId;
  channel.SendNotification(notification, (s, r) => { });
}

You can obtain your client identifier (clientId) and client secret (clientSecret) from Amazon by following the instructions here https://developer.amazon.com/public/apis/engage/device-messaging/tech-docs/02-obtaining-adm-credentials

We will obtain the registration identifier (registrationId) in the client code, which is explained below. Once the client receives the registration identifier from Amazon, it should be stored on the server so that the server is aware of which devices are registered to receive notifications.

 

CLIENT – ADM Bindings Library

The Android Device Messaging Jar package, which is included in the Amazon Mobile App SDK, is required to receive push notifications. Download the Amazon Mobile App SDK here https://developer.amazon.com/public/resources/development-tools/sdk

Because the ADM library is a Java Jar package and not a .NET library, we must create a Xamarin Java Bindings Library project in Visual Studio or Xamarin Studio.

adm-1

Locate the amazon-device-messaging-x.x.x.jar file and copy it to the “Jars” directory in your Java Bindings Library project. Verify that the Build Action of the ADM Jar is set to “InputJar”.

adm-2  

That’s it for the Bindings Library. You can now build your project so that it can be used as a reference.

CLIENT – Android App

Now we can finally start adding code to receive push notification to our Android app.

The following is required to create an Android app capable of receiving ADM push notifications.

  1. ADM Library Reference
  2. Permissions
  3. API Key
  4. Broadcast Receiver
  5. Intent Service
  6. Initiate ADM Registration

ADM Bindings Library Reference

Add the ADM Bindings Library that you created to the references of your Android App project.

adm-3

Add the following permissions to your AndroidManifest.xml

<permission android:name="
[YOUR PACKAGE NAME].permission.RECEIVE_ADM_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="[YOUR PACKAGE NAME].permission.RECEIVE_ADM_MESSAGE" /> <uses-permission android:name="com.amazon.device.messaging.permission.RECEIVE" /> <uses-permission android:name="android.permission.WAKE_LOCK" />

API Key

Obtain an API Key from Amazon by following the instructions at https://developer.amazon.com/public/apis/engage/device-messaging/tech-docs/02-obtaining-adm-credentials

Once you have an API Key, copy it into a text file named api_key.txt and put that file into the “Assets” folder.

adm-4

 

Broadcast Receiver

A Broadcast Receiver is required to receive the push notifications from the server and forward them onto an Intent Service. Below is an example of a Broadcast Receiver that will receive ADM push notifications and forward them onto an Intent Service named “ADMIntentService”. The following section explains how to create the Intent Service.

[BroadcastReceiver(Permission = "com.amazon.device.messaging.permission.SEND")]
[IntentFilter(new string[] { "com.amazon.device.messaging.intent.RECEIVE" }, Categories = new string[] { "@PACKAGE_NAME@" })]
[IntentFilter(new string[] { "com.amazon.device.messaging.intent.REGISTRATION" }, Categories = new string[] { "@PACKAGE_NAME@" })]
public class ADMReceiver : BroadcastReceiver
{

  public override void OnReceive(Context context, Intent intent)
  {
    ADMIntentService.RunIntentInService(context, intent);

    SetResult(Result.Ok, null, null);
  }
}

Intent Service

An Intent Service is required to handle the ADM push notifications and, based on the notification, perform any necessary business logic. The official Xamarin documentation has a great example of setting up an Intent Service in the “Creating the Intent Service” section of this doc: Remote Notifications. Use this to setup your Intent Service and then add the following methods below to handle receipt of registration and standard messages.

The HandleRegistration method below shows how to obtain the registration identifier, which the server needs to send the push notifications to each device. This method is called as a result of the server sending the com.amazon.device.messaging.intent.REGISTRATION intent action.

private void HandleRegistration(Context context, Intent intent)
{
  var registrationId = intent.GetStringExtra("registration_id");

  var error = intent.GetStringExtra("error");

  var unregistered = intent.GetStringExtra("unregistered");

  if (String.IsNullOrEmpty(MainActivity.ADMRegistrationId))
    MainActivity.ADMRegistrationId = registrationId;
}

Create a HandleMessage method to extract the data from the intent and use it. Once you have the data that has been pushed from the server, you may do what you want with it. This method is called as a result of the server sending the com.amazon.device.messaging.intent.RECEIVE intent action.

private void HandleMessage(Context context, Intent intent)
{
  String data = intent.GetStringExtra("data");

  //Do something with the data
  //…
  //…
}

Initiate Registration

The final step in setting up your ADM push notifications is to register your app with the server.

Below is an example of how you accomplish this. This code should be called from the OnCreate() method of your app’s main activity. This will ensure it is called every time your app is launched.

Using your ADM Bindings Library, we will create a new instance of the ADM object and check if the app has already been registered. If it hasn’t, StartRegister() will be called informing the server that a registration notification (com.amazon.device.messaging.intent.REGISTRATION) needs to be sent to this ADM client. 

Com.Amazon.Device.Messaging.ADM adm = new Com.Amazon.Device.Messaging.ADM(this);
if (adm.RegistrationId == null)
{
  adm.StartRegister();
}

Now simply run your code and a registration notification will be sent to your app and handled by the HandleRegistration method in your Intent Service. Use the registration identifier that you received to send push notifications from the server.