如何为 AWS SNS 在 Android (Xamarin) 上启用推送通知

how to enable push notifications on Android (Xamarin) for AWS SNS

我已经尝试了几个小时来为 Android 启用推送通知,以便我可以将其与 Amazon SNS 一起使用。已尝试遵循文档中描述的代码:http://docs.aws.amazon.com/mobile/sdkforxamarin/developerguide/getting-started-sns-android.html

似乎我做错了什么,因为我创建的 "intent" 已将 "action" 设置为 null,这会导致 OnHandleIntent 中出现异常。有没有人有这方面的经验?我是 Android 的新手,所以我对 "intents" 的理解非常有限。

这是 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);
    }
}
}

和 Intent 服务

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());
    }
}
}

所以问题:

如何注册设备以便我可以从 SNS 发送推送?我应该考虑其他方式吗??? 我必须采取任何其他步骤才能使它起作用吗?我确实将证书上传到 AWS,但我需要在应用程序代码中配置任何权限吗??

非常感谢!!!

克里斯

您可能需要查看 GitHub or via the Xamarin component store 中的 SNS 示例来补充入门,您可能会发现一些您遗漏的内容并且在入门指南中没有完全涵盖。示例中出现但您的代码中没有的东西是 RegisterForGCM() in the main activity:

private void RegisterForGCM()
{
    string senders = Constants.GoogleConsoleProjectId;
    Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
    intent.SetPackage("com.google.android.gsf");
    intent.PutExtra("app", PendingIntent.GetBroadcast(this, 0, new Intent(), 0));
    intent.PutExtra("sender", senders);
    StartService(intent);
}