9

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

  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. 有没有直接在我们的自定义服务器中注册手机的情况下发送推送通知的方法?

4

6 回答 6

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

于 2013-04-27T04:51:03.093 回答
7

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

注意:我有硬编码的 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 & why : 这是向 GCM 服务器发送请求时使用的密钥。
如何创建:参考这篇文章

deviceId 内容
和原因:此 id 也称为 RegistrationId。这是用于识别设备的唯一 ID。当您想向特定设备发送通知时,您需要此 ID。
如何创建:这取决于您如何实现应用程序。对于 cordova,我使用了一个简单的pushNotification 插件 您可以使用此插件简单地创建一个 deviceId/RegistrationId。为此,您需要有一个senderId。Google 如何创建 senderId 真的很简单 =)

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

快乐编码。
-Charitha-

于 2016-06-03T09:46:02.300 回答
3

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

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

于 2015-11-26T12:34:53.727 回答
2

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

用法

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

}
于 2016-04-22T18:09:39.753 回答
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 ();
于 2016-05-19T08:50:25.937 回答
0

我曾使用 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;
                    }

                }
            }
        }
于 2019-06-19T12:14:20.370 回答