如何在 Android (Xamarin) 上为 AWS SNS 启用推送通知
Posted
技术标签:
【中文标题】如何在 Android (Xamarin) 上为 AWS SNS 启用推送通知【英文标题】:how to enable push notifications on Android (Xamarin) for AWS SNS 【发布时间】:2016-03-11 20:53:05 【问题描述】:我已经尝试了几个小时来为 android 启用推送通知,以便可以将它与 Amazon SNS 一起使用。已尝试按照文档中描述的代码进行操作:http://docs.aws.amazon.com/mobile/sdkforxamarin/developerguide/getting-started-sns-android.html
似乎我做错了什么,因为我创建的“意图”将“动作”设置为 null,这会导致 OnHandleIntent 中出现异常。有没有人有这方面的经验?我对 Android 还很陌生,所以我对“意图”的理解……相当有限。
这里是 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,但我需要在应用代码中配置任何权限吗??
非常感谢!!!
克里斯
【问题讨论】:
【参考方案1】:您可能希望查看 GitHub 中的 SNS 示例或通过 Xamarin component store 来增加入门指南,您可能会发现一些您遗漏的内容并且未在入门指南中完整介绍。示例中存在但您的代码中没有的东西是主要活动中的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);
【讨论】:
非常感谢 - 这绝对是缺失的。我已经下载了示例并正在尝试它:我认为在 Constants.GoogleConsoleProjectId 中,我实际上需要但项目编号而不是 id。是对的吗?现在我已经能够运行示例,并且确实在 SNS 上注册了一个新端点,但是当我使用 SNS 控制台发送推送时,什么也没有发生。还有什么我需要做的吗?我需要订阅应用程序中的某些主题吗?我可以检查什么是错的吗? ....谢谢 已解决 - 刚刚在 GCM 上重新生成项目并更新了 SNS,它就可以工作了! 你救了我无数个小时! aws 文档很烂,所以过时了.. 我一直在他们的文档中寻找几个小时,但没有运气! 嗨@chrisb - 我也在努力遵循这些示例,我似乎已经达到了与您相同的点,即创建端点但设备没有收到通知。我正在通过模拟器运行它(它有 Google API 和 Google 帐户),我只是想知道除了重新生成项目并使用项目编号而不是应用程序 ID 之外,您是否做了任何其他事情,因为它们都不适合我?谢谢 好吧,我真的想不出我做过的任何其他事情,这也是不久前的事了。我的建议是重新生成所有密钥、项目……看看是否可行以上是关于如何在 Android (Xamarin) 上为 AWS SNS 启用推送通知的主要内容,如果未能解决你的问题,请参考以下文章