如何在c# . net上通过GCM发送Android推送通知

本文关键字:发送 GCM Android 通知 net | 更新日期: 2023-09-27 18:11:02

我是Android GCM推送通知的新手,我已经阅读了堆栈帖子,但无法得到直接的答案。我也读过在android中创建推送通知,以便更好地理解GCM是如何工作的。我还使用了SDK提供的gcm-demo-server和gcm-demo-client。然而,以下是我的疑问和我到目前为止所做的尝试:

  1. 关于我放的链接,拥有应用程序的手机注册以获得注册密钥。这是所有使用同一应用程序的手机的唯一密钥吗?
  2. 这个注册密钥在任何情况下都会过期吗?(例如App在后台运行)
  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. 是否有一种直接的方式来发送推送通知,而无需手机首先在我们的自定义服务器中注册?

如何在c# . net上通过GCM发送Android推送通知

参考代码:

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

代码看起来有点长,但它可以工作。在c#项目中实现以下代码后,我刚刚向我的手机发送了一个推送通知。我参考了一个关于这个实现的链接,但是在这里找不到它。所以我将和你分享我的代码。如果您想在线测试通知,您可以访问此链接。

注:我已硬录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
What &为什么:这个键将在向GCM服务器发送请求时使用。
如何创建:参考这个帖子

deviceId
What &原因:此id也称为RegistrationId。这是唯一标识设备的id。当你想发送通知您需要此id的特定设备。
如何create:这取决于您如何实现应用程序。为科尔多瓦我使用了一个简单的推送通知插件,你可以简单地创建一个deviceId/RegistrationId使用这个插件。要做到这一点,你需要 senderId 。谷歌如何创建一个senderId它真的很简单=)

如果有人需要帮助,请留下评论。

快乐编码。
-Charitha——

只是为了这个帖子的新访客的信息,如果你想发送相同的消息到多个设备,那么只需在请求的registration_id参数中发送逗号分隔的设备id。

这里有一篇很好的文章http://www.codewithasp.net/2015/11/send-message-gcm-c-sharp-single-multiple.html

这对我来说从来没有工作过,而且很难调试,加上传递注册令牌列表不清楚-期望传递字符串数组而不是逗号分隔的字符串-事实上,这是非常简单的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; }
}
}

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

我曾使用Firebase的FCM与Android应用程序和IOS应用程序合作。这段代码是可以工作的,中间层是ASP。净API。在visual studio中启动一个项目并选择API。需要创建一个控制器。您的server_api_key和发送方id添加Web。配置文件。

添加用户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;
                    }
                }
            }
        }