2013-04-27 143 views
9

我是新来的所有Android GCM推送通知,我已经阅读过帖子,但无法得到直接的答案。我也读了Create push notification in android以获得更好的理解GCM如何工作。我也使用了SDK提供的gcm-demo-server和gcm-demo-client。但是,这里是我的疑惑,以及我迄今为止所尝试的:如何在C#.Net上通过GCM发送Android推送通知

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

     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. 是否有发送推送通知,而无需首先在我们的自定义服务器中注册的电话直接的方式?

回答

19

参考代码:

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

+0

出于某种原因上述代码无法正常工作。我在这里假设设备ID是注册码。但是,当我尝试推送消息使用http://helmibaraja.com/gcm_demo.html它的作品。有任何想法吗? – 2013-04-27 17:44:36

+1

通过将“®istration_id=”更改为“&registration_id =”来实现它。感谢所有:) – 2013-04-27 18:03:49

+2

GoogleAppID =服务器API密钥&& deviceid =注册ID(184个字符)&& SENDER_ID = 12位数的应用程序ID(项目编号)(感谢代码项目页面上的注释 – 2014-11-12 02:01:02

2

This从来没有为我工作的一个很好的文章,这是很难调试加上经过注册令牌的名单尚不清楚-would指望通过一个字符串数组,而不是逗号分隔字符串 - ,事实证明这是很简单的POST请求我创建了自己的类返回服务器响应的方法,以及它工作得很好:

使用

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

} 
1

有包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(); 
7

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

注:我已经hardcorded apiKey,DEVICEID和POSTDATA,请绕道 的apiKey,设备ID和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。
如何创建 :这取决于您如何实现应用程序。对于科尔多瓦 我使用了一个简单的pushNotification Plugin你可以简单地使用这个插件创建一个 deviceId/RegistrationId。要做到这一点,你需要有 a senderId。谷歌如何创建一个senderId它真的很简单=)

如果有人需要一些帮助发表评论。

快乐编码。
-Charitha-

+1

感谢好友... – 2016-06-08 11:16:41

+1

Grt !!!正在找这个。谢谢。 – Venkat 2016-06-21 07:05:08

+0

检查链接https://srimansaswat.wordpress.com/2016/11/15/how-to - 发送推送通知到您,Android系统的设备使用-C代码/ – 2016-11-17 05:32:31