如何为 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);
}
我已经尝试了几个小时来为 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);
}