

适用于 Xamarin 的 AWS 移动 SDK 现已包含在。 适用于 .NET 的 AWS SDK本指南参考了适用于 Xamarin 的 Mobile SDK 的存档版本。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 SNS 接收推送通知 (Xamarin Android)
<a name="getting-started-sns-android"></a>

本教程介绍了如何使用 Amazon Simple Notification Service (SNS) 和适用于 .NET 和 Xamarin 的 AWS Mobile SDK 将推送通知发送到 Xamarin Android 应用程序。

## 项目设置
<a name="project-setup"></a>

### 先决条件
<a name="prerequisites"></a>

在开始本教程前，必须先完成有关[设置适用于 .NET 和 Xamarin 的 AWS Mobile SDK](setup.md) 的说明中的所有步骤。

### 设置 SNS 权限
<a name="set-permissions-for-sns"></a>

按照[设置适用于 .NET 和 Xamarin 的 AWS Mobile SDK](setup.md) 中第 2 步的说明操作，将下述策略附加到您应用程序的角色中。这样可为您的应用程序提供访问 SNS 的适当权限：

1. 转到 [IAM 控制台](https://console.aws.amazon.com/iam/home)，然后选择您要配置的 IAM 角色。

1. 单击 “**附加策略**”，选择 Amazon SNSFull 访问策略，然后单击 “**附加策略**”。

**警告**  
不建议在生产环境中SNSFull使用 Amazon Access。我们在此处使用它是为了让您快速启动并运行。有关为 IAM 角色指定权限的更多信息，请参阅 [IAM 角色权限概述](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies_permissions.html)。

### 在 Google Cloud 上启用推送通知
<a name="enable-push-notifications-on-google-cloud"></a>

首先，添加一个新的 Google API 项目：

1. 转到 [Google Developers Console](https://console.developers.google.com)。

1. 单击 **Create Project**。

1. 在 **New Project** 框中，输入项目名称，记下项目 ID (稍后您会用到它)，然后单击 **Create**。

接下来，为您的项目启用 Google Cloud Messaging (GCM) 服务：

1. 在 [Google Developers Console](https://console.developers.google.com) 中，系统应该已经选择了您的新项目。如果没有，请在页面顶部的下拉列表中选择。

1. 从页面左侧的侧栏中选择 **APIs & auth**。

1. 在搜索框中，键入“Google Cloud Messaging for Android”，然后单击**Google Cloud Messaging for Android**链接。

1. 单击 **Enable API**。

最后，获取 API 密钥：

1. 在 Google 开发者控制台中，选择并**验证 APIs >** **凭据**。

1. 在 **Public API access** 下，单击 **Create new key**。

1. 在 **Create a new key** 对话框中，单击 **Server key**。

1. 在出现的对话框中，单击 **Create**，然后复制显示的 API 密钥。稍后，您将使用此 API 密钥来执行身份验证。

### 使用项目 ID 在 SNS 控制台中创建平台 ARN
<a name="use-project-id-to-create-a-platform-arn-in-sns-console"></a>

1. 转到 [SNS 控制台](https://console.aws.amazon.com/sns/v2/home)。

1. 单击屏幕左侧的 **Applications**。

1. 单击 **Create platform application**，以创建新的 SNS 平台应用程序。

1. 输入 **Application Name**。

1. 对于 **Push notification platform**，选择 **Google Cloud Messaging (GCM)**。

1. 将 API 密钥粘贴到标记为 **API key** 的文本框中。

1. 单击 **Create platform application**。

1. 选择您刚创建的平台应用程序，然后复制应用程序 ARN。

### 将 Pack NuGet age for SNS 添加到您的项目中
<a name="add-nuget-package-for-sns-to-your-project"></a>

按照[设置适用于.NET 和 Xamarin 的 AWS 移动软件开发工具](setup.md)包中说明的第 4 步，将亚马逊简单通知 NuGet服务包添加到您的项目中。

## 创建 SNS 客户端
<a name="create-an-sns-client"></a>

```
var snsClient = new AmazonSimpleNotificationServiceClient(credentials, region);
```

## 为您的应用程序注册远程通知
<a name="register-your-application-for-remote-notifications"></a>

要在 Android 上注册远程通知，您需要创建一个可以接收 Google Cloud 消息 BroadcastReceiver 的。请按照下方的提示，更改程序包名称：

```
[BroadcastReceiver(Permission = "com.google.android.c2dm.permission.SEND")]
[IntentFilter(new string[] {
      "com.google.android.c2dm.intent.RECEIVE"
}, Categories = new string[] {
      "com.amazonaws.sns" /* change to match your package */
})]
[IntentFilter(new string[] {
      "com.google.android.c2dm.intent.REGISTRATION"
}, Categories = new string[] {
      "com.amazonaws.sns" /* change to match your package */
})]
[IntentFilter(new string[] {
      "com.google.android.gcm.intent.RETRY"
}, Categories = new string[] {
      "com.amazonaws.sns" /* 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);
      }
}
```

以下是接收来自的推送通知 BroadcastReceiver 并在设备的通知栏上显示通知的服务：

```
[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;

      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) {
    string registrationId = intent.GetStringExtra("registration_id");
    string error = intent.GetStringExtra("error");
    string unregistration = intent.GetStringExtra("unregistered");

    if (string.IsNullOrEmpty(error)) {
      var response = await SnsClient.CreatePlatformEndpointAsync(new CreatePlatformEndpointRequest {
        Token = registrationId,
        PlatformApplicationArn = "YourPlatformArn" /* 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(this, "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)
      .SetSmallIcon(Resource.Drawable.Icon)
      .SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification));

    // Get the notification manager:
    NotificationManager notificationManager = this.GetSystemService(Context.NotificationService) as NotificationManager;

    notificationManager.Notify(1001, builder.Build());
  }
}
```

## 将消息从 SNS 控制台发送到端点
<a name="send-a-message-from-the-sns-console-to-your-endpoint"></a>

1. 转到 [SNS 控制台 >“Applications (应用程序)”](https://console.aws.amazon.com/sns/v2/home)。

1. 依次选择您的平台应用程序和端点，然后单击 **Publish to endpoint**。

1. 在文本框中键入文本消息，然后单击 **Publish message** 发布消息。