2013-04-27 242 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