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

标签 android amazon-web-services xamarin push-notification amazon-sns

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

似乎我做错了什么,因为我创建的“Intent ”将“操作”设置为 null,这会导致 OnHandleIntent 中出现异常。有人有这方面的经验吗?我对 Android 还很陌生,所以我对“Intent ”的理解相当有限。

这是主要 Activity

[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 中的 SNS 示例或通过Xamarin component store为了增强入门能力,您可能会发现入门指南中缺少并且未完全涵盖的一些内容。引起我注意的是示例中存在但代码中不存在的东西是主 Activity 中的 RegisterForGCM() :

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

关于android - 如何在 Android (Xamarin) 上为 AWS SNS 启用推送通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35949709/

相关文章:

java - SharedPreferences 是否合适,或者有更好的选择吗?

amazon-web-services - 将 EC2 公共(public) IP 地址指向子域

amazon-web-services - AWS SAM 生成的构建规范从哪里获取 S3_BUCKET 值?

ios - 在一个项目中有两个 Realm 数据库并将其合并

ios - Xamarin iOS 和 .Net Standard 2.0 依赖服务

android - Asus Zenfone (Android) TextView\TextWatcher 键盘输入错误

android - 如何确定我的 android 应用程序是否存在内存泄漏?

java - 适用于 Android 的 Firebase 实时(在线)数据库的安全性如何?

hadoop - 在Amazon Elastic MapReduce和S3中读取参数文件

c# - 标签 TapGesture 不会触发 Xamarin Forms