【问题标题】:How to send Android push notifications via GCM on C# .Net如何在 C# .Net 上通过 GCM 发送 Android 推送通知
【发布时间】:2013-04-27 04:47:52
【问题描述】:

我是所有 Android GCM 推送通知的新手,我已阅读堆栈帖子但无法得到直接答案。我还阅读了 Create push notification in android 以更好地了解 GCM 的工作原理。我还使用了 SDK 提供的 gcm-demo-server 和 gcm-demo-client。但是,这是我的疑问以及到目前为止我所尝试的:

  1. 关于我放的链接,有应用程序的手机注册以获取注册密钥。这是所有使用相同应用的手机的唯一密钥吗?
  2. 此注册密钥是否会过期? (例如,在后台运行的应用)
  3. 假设我有注册密钥,我尝试了以下代码 sn-p 通过 GCM 将通知推送到我的应用程序。这是写在 c# .net 上的。请让我知道我上面提到的是否可以使用以下代码sn-p来实现:

         private string SendGCMNotification(string apiKey, string postData, string postDataContentType = "application/json")
        {
            ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
    
            // MESSAGE CONTENT
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);
    
            // CREATE REQUEST
            HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send");
            Request.Method = "POST";
            Request.KeepAlive = false;
            Request.ContentType = postDataContentType;
            Request.Headers.Add(string.Format("Authorization: key={0}", apiKey));
            Request.ContentLength = byteArray.Length;
    
            Stream dataStream = Request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();
    
            // SEND MESSAGE
            try
            {
                WebResponse Response = Request.GetResponse();
                HttpStatusCode ResponseCode = ((HttpWebResponse)Response).StatusCode;
                if (ResponseCode.Equals(HttpStatusCode.Unauthorized) || ResponseCode.Equals(HttpStatusCode.Forbidden))
                {
                    var text = "Unauthorized - need new token";
                }
                else if (!ResponseCode.Equals(HttpStatusCode.OK))
                {
                    var text = "Response from web service isn't OK";
                }
    
                StreamReader Reader = new StreamReader(Response.GetResponseStream());
                string responseLine = Reader.ReadToEnd();
                Reader.Close();
    
                return responseLine;
            }
            catch (Exception e)
            {
            }
            return "error";
        }
    
  4. 是否有直接发送推送通知的方法,而无需先在我们的自定义服务器中注册手机?

【问题讨论】:

    标签: c# android google-cloud-messaging


    【解决方案1】:

    参考代码:

    public class AndroidGCMPushNotification
    {
        public AndroidGCMPushNotification()
        {
            //
            // TODO: Add constructor logic here
            //
        }
        public string SendNotification(string deviceId, string message)
        {
            string SERVER_API_KEY = "server api key";        
            var SENDER_ID = "application number";
            var value = message;
            WebRequest tRequest;
            tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
            tRequest.Method = "post";
            tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
            tRequest.Headers.Add(string.Format("Authorization: key={0}", SERVER_API_KEY));
    
            tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));
    
            string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
            Console.WriteLine(postData);
            Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
            tRequest.ContentLength = byteArray.Length;
    
            Stream dataStream = tRequest.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();
    
            WebResponse tResponse = tRequest.GetResponse();
    
            dataStream = tResponse.GetResponseStream();
    
            StreamReader tReader = new StreamReader(dataStream);
    
            String sResponseFromServer = tReader.ReadToEnd();
    
    
            tReader.Close();
            dataStream.Close();
            tResponse.Close();
            return sResponseFromServer;
        }
    }
    

    参考链接:

    http://www.codeproject.com/Tips/434338/Android-GCM-Push-Notification

    【讨论】:

    • 由于某种原因,上面的代码不起作用。我假设设备 ID 是这里的注册密钥。但是,当我尝试使用 helmibaraja.com/gcm_demo.html 推送消息时,它可以工作。有什么想法吗?
    • 通过将“®istration_id=”更改为“&registration_id=”使其正常工作。谢谢大家:)
    • GoogleAppID = 服务器 api 密钥 && deviceid = 注册 ID(184 个字符) && SENDER_ID = 12 位应用 ID(项目编号)(感谢代码项目页面上的 cmets。
    • 这对我不起作用。 Charitha 的回答很有效。 :D
    【解决方案2】:

    代码看起来有点长,但它可以工作。通过在 C# 项目中实现以下代码,我在挣扎 2 天后刚刚向我的手机发送了推送通知。我提到了一个关于这个实现的链接,但找不到它在这里发布。所以将与您分享我的代码。如果您想在线测试通知,您可以访问此link

    注意:我有硬编码的 apiKey、deviceId 和 postData,请通过 您请求中的 apiKey、deviceId 和 postData 并将它们从 方法体。如果你也想传递消息字符串

    public string SendGCMNotification(string apiKey, string deviceId, string postData)
    {
        string postDataContentType = "application/json";
        apiKey = "AIzaSyC13...PhtPvBj1Blihv_J4"; // hardcorded
        deviceId = "da5azdfZ0hc:APA91bGM...t8uH"; // hardcorded
    
        string message = "Your text";
        string tickerText = "example test GCM";
        string contentTitle = "content title GCM";
        postData =
        "{ \"registration_ids\": [ \"" + deviceId + "\" ], " +
          "\"data\": {\"tickerText\":\"" + tickerText + "\", " +
                     "\"contentTitle\":\"" + contentTitle + "\", " +
                     "\"message\": \"" + message + "\"}}";
    
    
        ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
    
        //
        //  MESSAGE CONTENT
        byte[] byteArray = Encoding.UTF8.GetBytes(postData);
    
        //
        //  CREATE REQUEST
        HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send");
        Request.Method = "POST";
        Request.KeepAlive = false;
        Request.ContentType = postDataContentType;
        Request.Headers.Add(string.Format("Authorization: key={0}", apiKey));
        Request.ContentLength = byteArray.Length;
    
        Stream dataStream = Request.GetRequestStream();
        dataStream.Write(byteArray, 0, byteArray.Length);
        dataStream.Close();
    
        //
        //  SEND MESSAGE
        try
        {
            WebResponse Response = Request.GetResponse();
            HttpStatusCode ResponseCode = ((HttpWebResponse)Response).StatusCode;
            if (ResponseCode.Equals(HttpStatusCode.Unauthorized) || ResponseCode.Equals(HttpStatusCode.Forbidden))
            {
                var text = "Unauthorized - need new token";
            }
            else if (!ResponseCode.Equals(HttpStatusCode.OK))
            {
                var text = "Response from web service isn't OK";
            }
    
            StreamReader Reader = new StreamReader(Response.GetResponseStream());
            string responseLine = Reader.ReadToEnd();
            Reader.Close();
    
            return responseLine;
        }
        catch (Exception e)
        {
        }
        return "error";
    }
    
    public static bool ValidateServerCertificate(
    object sender,
    X509Certificate certificate,
    X509Chain chain,
    SslPolicyErrors sslPolicyErrors)
    {
        return true;
    }
    

    您可能不熟悉 apiKey、deviceId 之类的词。别担心,我会解释它们是什么以及如何创建它们。

    apiKey
    什么&为什么:这是向GCM服务器发送请求时使用的密钥。
    如何创建:Refer this post

    deviceId
    什么&为什么:这个ID也称为RegistrationId。这是用于识别设备的唯一 ID。当你想发送一个 通知您需要此 ID 的特定设备。
    如何 create:这取决于您如何实现应用程序。对于科尔多瓦 我用了一个简单的pushNotification Plugin 你可以简单地创建一个 deviceId/RegistrationId 使用这个插件。为此,您需要拥有 一个 senderId。 Google 如何创建 senderId 真的很简单 =)

    如果有人需要帮助,请发表评论。

    快乐编码。
    -Charitha-

    【讨论】:

    【解决方案3】:

    仅针对此帖子的新访问者的信息,如果您想向多个设备发送相同的消息,则只需在 request 的 registration_id 参数中发送逗号分隔的设备 ID。

    这是一篇不错的文章 http://www.codewithasp.net/2015/11/send-message-gcm-c-sharp-single-multiple.html

    【讨论】:

      【解决方案4】:

      This 从来没有为我工作过,而且很难调试加上传递注册令牌列表不清楚 - 期望传递一个字符串数组而不是逗号分隔的字符串 - 事实上这是非常简单的发布请求我使用返回服务器响应的方法创建了我自己的类,并且效果很好:

      用法

             //Registration Token 
              string[] registrationIds ={"diks4vp5......","erPjEb9....."};
      
              AndroidGcmPushNotification gcmPushNotification = new 
              AndroidGcmPushNotification(
                  "API KEY", registrationIds, "Hello World"
                  );
              gcmPushNotification.SendGcmNotification();
      

      using System;
      using System.IO;
      using System.Net;
      using System.Text;
      using System.Web.Script.Serialization;
      
      
      public class AndroidGcmPushNotification
      {
      private readonly string _apiAccessKey;
      private readonly string[] _registrationIds;
      private readonly string _message;
      private readonly string _title;
      private readonly string _subtitle;
      private readonly string _tickerText;
      private readonly bool _vibrate;
      private readonly bool _sound;
      
      public AndroidGcmPushNotification(string apiAccessKey, string[] registrationIds, string message, string title = "",
          string subtitle = "", string tickerText = "", bool vibrate = true, bool sound = true )
      {
          _apiAccessKey = apiAccessKey;
          _registrationIds = registrationIds;
          _message = message;
          _title = title;
          _subtitle = subtitle;
          _tickerText = tickerText;
          _vibrate = vibrate;
          _sound = sound;
      }
      
      public string SendGcmNotification()
      {
      
          //MESSAGE DATA
          GcmPostData data = new GcmPostData()
          {
              message = _message,
              title = _title,
              subtitle = _subtitle,
              tickerText = _tickerText,
              vibrate = _vibrate,
              sound = _sound
          };
      
          //MESSAGE FIELDS 
          GcmPostFields fields = new GcmPostFields();
          fields.registration_ids = _registrationIds;
          fields.data = data;
      
          //SERIALIZE TO JSON 
          JavaScriptSerializer jsonEncode = new JavaScriptSerializer();
      
          //CONTENTS
          byte[] byteArray = Encoding.UTF8.GetBytes(jsonEncode.Serialize(fields));
      
          //REQUEST
          HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send");
          request.Method = "POST";
          request.KeepAlive = false;
          request.ContentType = "application/json";
          request.Headers.Add($"Authorization: key={_apiAccessKey}");
          request.ContentLength = byteArray.Length;
      
          Stream dataStream = request.GetRequestStream();
          dataStream.Write(byteArray, 0, byteArray.Length);
          dataStream.Close();
      
      
          //SEND REQUEST
          try
          {
              WebResponse response = request.GetResponse();
              {
                  StreamReader reader = new StreamReader(response.GetResponseStream());
                  string responseLine = reader.ReadToEnd();
                  reader.Close();
      
                  return responseLine;
              }
          }
          catch (Exception e)
          {
              return e.Message;
          }
      
      }
      private class GcmPostFields
      {
          public string[] registration_ids { get; set; }
          public GcmPostData data { get; set; }
      
      }
      private class GcmPostData
      {
          public string message { get; set; }
          public string title { get; set; }
          public string subtitle { get; set; }
          public string tickerText { get; set; }
          public bool vibrate { get; set; }
          public bool sound { get; set; }
      }
      
      }
      

      【讨论】:

        【解决方案5】:

        有包PushSharp。 允许与几乎所有流行的通知 API 进行通信。

        示例代码:

        // Configuration
        var config = new GcmConfiguration ("GCM-SENDER-ID", "AUTH-TOKEN", null);
        
        // Create a new broker
        var gcmBroker = new GcmServiceBroker (config);
        
        // Wire up events
        gcmBroker.OnNotificationFailed += (notification, aggregateEx) => {
        
            aggregateEx.Handle (ex => {
        
                // See what kind of exception it was to further diagnose
                if (ex is GcmNotificationException) {
                    var notificationException = (GcmNotificationException)ex;
        
                    // Deal with the failed notification
                    var gcmNotification = notificationException.Notification;
                    var description = notificationException.Description;
        
                    Console.WriteLine ($"GCM Notification Failed: ID={gcmNotification.MessageId}, Desc={description}");
                } else if (ex is GcmMulticastResultException) {
                    var multicastException = (GcmMulticastResultException)ex;
        
                    foreach (var succeededNotification in multicastException.Succeeded) {
                        Console.WriteLine ($"GCM Notification Failed: ID={succeededNotification.MessageId}");
                    }
        
                    foreach (var failedKvp in multicastException.Failed) {
                        var n = failedKvp.Key;
                        var e = failedKvp.Value;
        
                        Console.WriteLine ($"GCM Notification Failed: ID={n.MessageId}, Desc={e.Description}");
                    }
        
                } else if (ex is DeviceSubscriptionExpiredException) {
                    var expiredException = (DeviceSubscriptionExpiredException)ex;
        
                    var oldId = expiredException.OldSubscriptionId;
                    var newId = expiredException.NewSubscriptionId;
        
                    Console.WriteLine ($"Device RegistrationId Expired: {oldId}");
        
                    if (!string.IsNullOrWhitespace (newId)) {
                        // If this value isn't null, our subscription changed and we should update our database
                        Console.WriteLine ($"Device RegistrationId Changed To: {newId}");
                    }
                } else if (ex is RetryAfterException) {
                    var retryException = (RetryAfterException)ex;
                    // If you get rate limited, you should stop sending messages until after the RetryAfterUtc date
                    Console.WriteLine ($"GCM Rate Limited, don't send more until after {retryException.RetryAfterUtc}");
                } else {
                    Console.WriteLine ("GCM Notification Failed for some unknown reason");
                }
        
                // Mark it as handled
                return true;
            });
        };
        
        gcmBroker.OnNotificationSucceeded += (notification) => {
            Console.WriteLine ("GCM Notification Sent!");
        };
        
        // Start the broker
        gcmBroker.Start ();
        
        foreach (var regId in MY_REGISTRATION_IDS) {
            // Queue a notification to send
            gcmBroker.QueueNotification (new GcmNotification {
                RegistrationIds = new List<string> { 
                    regId
                },
                Data = JObject.Parse ("{ \"somekey\" : \"somevalue\" }")
            });
        }
        
        // Stop the broker, wait for it to finish   
        // This isn't done after every message, but after you're
        // done with the broker
        gcmBroker.Stop ();
        

        【讨论】:

          【解决方案6】:

          我曾使用 Firebase 的 FCM 处理过 Android 应用程序和 IOS 应用程序。 此代码正在运行。中间层是 ASP.NET API。您在 Visual Studio 中启动一个项目并选择 API。要创建一个控制器。您的 server_api_key 和发送者 ID 添加 Web.config 文件。

          添加用户 fcm server_api_key 和发件人 ID。

          <appSettings>
              <add key="SERVER_API_KEY" value=""/>
              <add key="SENDER_ID" value=""/>
          </appSettings>
          

          下面的代码添加你的控制器

           using System;
              using System.Net;
              using System.Web.Http;
              using System.Web.Script.Serialization;
              using System.Configuration;
              using System.IO;
          
              namespace pushios.Controllers
                  {
          
                  public class HomeController : ApiController
                      {
                          [HttpGet]
          
                  [Route("sendmessage")]
          
                          public IHttpActionResult SendMessage()
                        {
                              var data = new {
                                  to = "Device Token",
                                  data = new
                                  {
                                     //To be adding your json data
                                      body="Test",
                                      confId= "",
                                      pageTitle= "test",
                                      pageFormat= "",
                                      dataValue= "",
                                      title= "C#",
                                      webviewURL= "",
                                      priority = "high",
                                      notificationBlastID = "0",
                                      status = true
                                  }
                              };
                              SendNotification(data);
                              return Ok();
                          }
                          public void SendNotification(object data)
                          {
                              var Serializer = new JavaScriptSerializer();
                              var json = Serializer.Serialize(data);
                              Byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(json);
          
                              SendNotification(byteArray);
                          }
                          public void SendNotification(Byte[] byteArray)
                          {
          
                              try
                              {
                                  String server_api_key = ConfigurationManager.AppSettings["SERVER_API_KEY"];
                                  String senderid = ConfigurationManager.AppSettings["SENDER_ID"];
          
                                  WebRequest type = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
                                  type.Method = "post";
                                  type.ContentType = "application/json";
                                  type.Headers.Add($"Authorization: key={server_api_key}");
                                  type.Headers.Add($"Sender: id={senderid}");
          
                                  type.ContentLength = byteArray.Length;
                                  Stream datastream = type.GetRequestStream();
                                  datastream.Write(byteArray, 0, byteArray.Length);
                                  datastream.Close();
          
                                  WebResponse respones = type.GetResponse();
                                  datastream = respones.GetResponseStream();
                                  StreamReader reader = new StreamReader(datastream);
          
                                  String sresponessrever = reader.ReadToEnd();
                                  reader.Close();
                                  datastream.Close();
                                  respones.Close();
          
                              }
                              catch (Exception)
                              {
                                  throw;
                              }
          
                          }
                      }
                  }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多