如何通过C#Net上的GCM发送Android推送通知
我对所有Android GCM推送通知都是新手,我读过堆栈帖子,但没有得到一个直接的答案。我也读过一些书,以便更好地了解GCM的工作原理。我还使用了SDK提供的gcm演示服务器和gcm演示客户端。然而,以下是我的疑问和我迄今为止所做的尝试:如何通过C#Net上的GCM发送Android推送通知,c#,android,google-cloud-messaging,C#,Android,Google Cloud Messaging,我对所有Android GCM推送通知都是新手,我读过堆栈帖子,但没有得到一个直接的答案。我也读过一些书,以便更好地了解GCM的工作原理。我还使用了SDK提供的gcm演示服务器和gcm演示客户端。然而,以下是我的疑问和我迄今为止所做的尝试: 关于我放的链接,有应用程序的手机注册以获取注册密钥。这是使用同一应用程序的所有手机的唯一密钥吗 在任何情况下,此注册密钥是否过期?(例如,后台运行的应用程序) 假设我有注册密钥,我已经尝试使用以下代码片段通过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";
}
参考代码:
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() + "®istration_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;
}
}
参考链接:
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() + "®istration_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;
}
}
仅为本帖新访问者提供信息,如果您想向多个设备发送相同的消息,只需在请求的注册id参数中发送逗号分隔的设备id即可 这是一篇关于这方面的好文章 对我来说从来都不起作用,而且很难调试,加上传递注册令牌列表不清楚-希望传递字符串数组而不是逗号分隔的字符串-,事实上这是非常简单的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; }
}
}
有一个包裹。
允许与几乎所有流行的通知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 ();
//配置
var config=新的GCM配置(“GCM-SENDER-ID”、“AUTH-TOKEN”,null);
//创建一个新的代理
var gcmBroker=新的GcmServiceBroker(配置);
//连接事件
gcmBroker.OnNotificationFailed+=(通知、聚合eEx)=>{
aggregateEx.Handle(ex=>{
//查看需要进一步诊断的异常类型
if(例如GcmNotificationException){
var notificationException=(GcmNotificationException)ex;
//处理失败的通知
var gcmNotification=notificationException.Notification;
变量说明=notificationException.description;
Console.WriteLine($“GCM通知失败:ID={gcmNotification.MessageId},Desc={description}”);
}else if(ex为GCMMultipcasterSultException){
var multicastException=(GCMMulticasterSultException)ex;
foreach(multicastException中的var succeededNotification.succeed){
Console.WriteLine($“GCM通知失败:ID={succeededNotification.MessageId}”);
}
foreach(multicastException.Failed中的var failedKvp){
var n=故障KVP.键;
var e=故障kVp.值;
Console.WriteLine($“GCM通知失败:ID={n.MessageId},Desc={e.Description}”);
}
}else if(ex为DeviceSubscriptionExpiredException){
var expiredException=(DeviceSubscriptionExpiredException)ex;
var oldId=expiredException.OldSubscriptionId;
var newId=expiredException.NewSubscriptionId;
Console.WriteLine($“设备注册ID已过期:{oldId}”);
如果(!string.IsNullOrWhitespace(newId)){
//如果此值不为null,则我们的订阅已更改,应该更新数据库
Console.WriteLine($“设备注册ID更改为:{newId}”);
}
}else if(ex为RetryAfterException){
var retryException=(RetryAfterException)ex;
//如果您受到速率限制,则应在RetryAfterUtc日期之前停止发送消息
Console.WriteLine($“GCM速率有限,在{retryException.RetryAfterUtc}之后才发送更多数据”);
}否则{
Console.WriteLine(“GCM通知因未知原因失败”);
}
//标记为已处理
返回true;
});
};
gcmBroker.onNotificationSuccessed+=(通知)=>{
Console.WriteLine(“已发送GCM通知!”);
};
//启动经纪人
gcmBroker.Start();
foreach(我的注册ID中的变量regId){
//将要发送的通知排队
gcmBroker.QueueNotification(新的GcmNotification{
注册ID=新列表{
雷吉德
},
Data=JObject.Parse(“{\'somekey\':\'somevalue\'}”)
});
}
//停止代理,等待它完成
//这并不是在每封邮件之后都做,而是在你
//与经纪人达成协议
gcmBroker.Stop();
代码看起来有点长,但可以工作。我刚刚通过在C#project中实现以下代码向我的手机发送了一个推送通知。我引用了一个关于这个实现的链接,但是在这里找不到它。因此,我将与您共享我的代码。如果您想在线测试通知,可以访问此
注意:我有硬记录的apiKey、deviceId和postData,请通过
请求中的apiKey、deviceId和postData,并将其从
方法主体。如果您还想传递消息字符串
您可能不熟悉apiKey、deviceId等词。别担心,我会解释它们是什么以及如何创建它们
apiKey什么和为什么:这是向GCM服务器发送请求时使用的密钥。
如何创建: 设备id
什么和为什么:此id也称为注册id。这是用于标识设备的唯一id。当您想发送 通知您需要此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;
}
}
}
}