Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何通过C#Net上的GCM发送Android推送通知_C#_Android_Google Cloud Messaging - Fatal编程技术网

如何通过C#Net上的GCM发送Android推送通知

如何通过C#Net上的GCM发送Android推送通知,c#,android,google-cloud-messaging,C#,Android,Google Cloud Messaging,我对所有Android GCM推送通知都是新手,我读过堆栈帖子,但没有得到一个直接的答案。我也读过一些书,以便更好地了解GCM的工作原理。我还使用了SDK提供的gcm演示服务器和gcm演示客户端。然而,以下是我的疑问和我迄今为止所做的尝试: 关于我放的链接,有应用程序的手机注册以获取注册密钥。这是使用同一应用程序的所有手机的唯一密钥吗 在任何情况下,此注册密钥是否过期?(例如,后台运行的应用程序) 假设我有注册密钥,我已经尝试使用以下代码片段通过GCM将通知推送到我的应用程序。这是写在c#net

我对所有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() + "&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;
        }
    }
    
    参考链接:

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

    仅为本帖新访问者提供信息,如果您想向多个设备发送相同的消息,只需在请求的注册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;
                        }
    
                    }
                }
            }