I have been trying for several hours to enable push notification for Android so I can use it with Amazon SNS. Have tried to follow the code as described in the documentation: http://docs.aws.amazon.com/mobile/sdkforxamarin/developerguide/getting-started-sns-android.html
Seems like I am doing something wrong because the "intent" I create has "action" set to null which cause an exception in OnHandleIntent. Has anyone experience with that? I am pretty new to Android so my understanding of "intents", .. is rather limited.
Here is the MainActivity
[Activity (Label = "awst", MainLauncher = true, Icon = "@mipmap/icon")]
public class MainActivity : Activity
{
int count = 1;
protected override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button> (Resource.Id.myButton);
button.Click += delegate {
button.Text = string.Format ("{0} clicks!", count++);
var intent = new Intent (this, typeof (GCMIntentService));
};
}
}
[BroadcastReceiver(Permission = "com.google.android.c2dm.permission.SEND")]
[IntentFilter(new string[] {
"com.google.android.c2dm.intent.RECEIVE"
}, Categories = new string[] {
"com.companyname.awst" /* change to match your package */
})]
[IntentFilter(new string[] {
"com.google.android.c2dm.intent.REGISTRATION"
}, Categories = new string[] {
"com.companyname.awst" /* change to match your package */
})]
[IntentFilter(new string[] {
"com.google.android.gcm.intent.RETRY"
}, Categories = new string[] {
"com.companyname.awst" /* change to match your package */
})]
public class GCMBroadcastReceiver: BroadcastReceiver {
const string TAG = "PushHandlerBroadcastReceiver";
public override void OnReceive(Context context, Intent intent) {
GCMIntentService.RunIntentInService(context, intent);
SetResult(Result.Ok, null, null);
}
}
[BroadcastReceiver]
[IntentFilter(new[] {
Android.Content.Intent.ActionBootCompleted
})]
public class GCMBootReceiver: BroadcastReceiver {
public override void OnReceive(Context context, Intent intent) {
GCMIntentService.RunIntentInService(context, intent);
SetResult(Result.Ok, null, null);
}
}
}
and the Intent service
namespace awst.Droid
{
[Service]
public class GCMIntentService: IntentService {
static PowerManager.WakeLock sWakeLock;
static object LOCK = new object();
public static void RunIntentInService(Context context, Intent intent) {
lock(LOCK) {
if (sWakeLock == null) {
// This is called from BroadcastReceiver, there is no init.
var pm = PowerManager.FromContext(context);
sWakeLock = pm.NewWakeLock(
WakeLockFlags.Partial, "My WakeLock Tag");
}
}
sWakeLock.Acquire();
intent.SetClass(context, typeof(GCMIntentService));
//
context.StartService(intent);
}
protected override void OnHandleIntent(Intent intent) {
try {
Context context = this.ApplicationContext;
string action = intent.Action;
// !!!!!!
// this is where the code fails with action beeing null
// !!!!!!
if (action.Equals("com.google.android.c2dm.intent.REGISTRATION")) {
HandleRegistration(intent);
} else if (action.Equals("com.google.android.c2dm.intent.RECEIVE")) {
HandleMessage(intent);
}
} finally {
lock(LOCK) {
//Sanity check for null as this is a public method
if (sWakeLock != null) sWakeLock.Release();
}
}
}
private void HandleRegistration(Intent intent) {
Globals config = Globals.Instance;
string registrationId = intent.GetStringExtra("registration_id");
string error = intent.GetStringExtra("error");
string unregistration = intent.GetStringExtra("unregistered");
if (string.IsNullOrEmpty(error)) {
config.snsClient.CreatePlatformEndpointAsync(new CreatePlatformEndpointRequest {
Token = registrationId,
PlatformApplicationArn = config.AWS_PlaformARN /* insert your platform application ARN here */
});
}
}
private void HandleMessage(Intent intent) {
string message = string.Empty;
Bundle extras = intent.Extras;
if (!string.IsNullOrEmpty(extras.GetString("message"))) {
message = extras.GetString("message");
} else {
message = extras.GetString("default");
}
Log.Info("Messages", "message received = " + message);
ShowNotification("SNS Push", message);
//show the message
}
public void ShowNotification(string contentTitle,
string contentText) {
// Intent
Notification.Builder builder = new Notification.Builder(this)
.SetContentTitle(contentTitle)
.SetContentText(contentText)
.SetDefaults(NotificationDefaults.Sound | NotificationDefaults.Vibrate)
//todo
.SetSmallIcon(Resource.Mipmap.Icon)
.SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification));
// Get the notification manager:
NotificationManager notificationManager = this.GetSystemService(Context.NotificationService) as NotificationManager;
notificationManager.Notify(1001, builder.Build());
}
}
}
So questions:
How do I register the device so I can then send a push from SNS? Is there a different way I should consider??? Are there any other steps I must take for this to work? I did upload the certificate to AWS but do I need to configure any permissions in the app code??
Thanks a lot!!!
Chris