web-dev-qa-db-fra.com

Comment envoyer des notifications Push Android via GCM sur C # .Net

Je suis nouveau dans toutes les notifications GCM Android d'Android et j'ai lu les articles de la pile, mais je n'ai pas pu obtenir de réponse directe. J'ai aussi lu Créer une notification Push dans Android pour mieux comprendre le fonctionnement de GCM. J'ai également utilisé gcm-demo-server et gcm-demo-client fournis par le SDK. Cependant, voici mes doutes et ce que j'ai essayé jusqu'à présent:

  1. En ce qui concerne le lien que j'ai mis, le téléphone qui dispose de l'application s'inscrit pour obtenir la clé d'enregistrement. Est-ce une clé unique pour tous les téléphones utilisant la même application?
  2. Cette clé d'enregistrement expire-t-elle dans tous les cas? (Par exemple, une application fonctionnant en arrière-plan)
  3. En supposant que je dispose de la clé d'enregistrement, j'ai essayé l'extrait de code suivant dans la notification Push via GCM vers mon application. Ceci est écrit sur c # .net. S'il vous plaît laissez-moi savoir si ce que j'ai mentionné ci-dessus peut être réalisé en utilisant l'extrait de code suivant:

         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. Existe-t-il un moyen direct d’envoyer des notifications Push sans que le téléphone n’ait d’abord été enregistré sur notre serveur personnalisé?

9
Pavan Welihinda

Code de référence:

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

Lien de référence:

http://www.codeproject.com/Tips/434338/Android-GCM-Push-Notification

19
Freelancer

Le code a l'air un peu long mais ça marche. Je viens d'envoyer une notification Push à mon téléphone après 2 jours de difficultés en implémentant le code suivant dans le projet C #. J'ai fait référence à un lien concernant cette implémentation, mais je n'ai pas pu le trouver à poster ici. Alors partagerons mon code avec vous. Si vous souhaitez tester la notification en ligne, vous pouvez vous rendre sur ce lien .

remarque: j'ai apiKey, deviceId et postData en dur, veuillez transmettre apiKey, deviceId et postData dans votre demande et supprimez-les de le corps de la méthode. Si vous voulez également transmettre la chaîne de message

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

Vous ne connaissez peut-être pas des mots comme apiKey, deviceId. Ne vous inquiétez pas, je vais vous expliquer ce qu'ils sont et comment les créer. 

clé API 
Quoi & pourquoi: Il s'agit d'une clé qui sera utilisée lors de l'envoi de demandes au serveur GCM.
Comment créer: Report this post _

Reference de l'appareil 
Quoi & pourquoi: Cet identifiant est également connu sous le nom RegistrationId. C'est un identifiant unique pour identifier le périphérique. Quand vous voulez envoyer un notification à un appareil spécifique, vous avez besoin de cet identifiant. 
Comment create: Cela dépend de la manière dont vous implémentez l'application. Pour Cordova J'ai utilisé un simple plug-in pushNotification Vous pouvez simplement créer un deviceId/RegistrationId utilisant ce plugin. Pour ce faire, vous devez avoir un senderId. Google comment créer un senderId c'est vraiment simple =)

Si quelqu'un a besoin d'aide, laissez un commentaire.

Bonne codage.
- Charitha-

7

Juste pour l'information des nouveaux visiteurs sur ce post, si vous voulez envoyer le même message à plusieurs appareils, envoyez simplement des identifiants d'appareil séparés par des virgules dans le paramètre registration_id de la requête.

Voici un article de Nice sur ce sujet http://www.codewithasp.net/2015/11/send-message-gcm-c-sharp-single-multiple.html

3
Nikhil Gaur

Cela n'a jamais fonctionné pour moi et il est difficile de déboguer plus de passer une liste de jetons d'enregistrement n'est pas clair - je m'attendrais à passer un tableau de chaînes de caractères au lieu d'une chaîne séparée par des virgules -, le fait qu'il s'agisse d'une demande de post très simple ma propre classe avec une méthode qui renvoie la réponse du serveur, et cela fonctionne très bien: 

Utilisation

       //Registration Token 
        string[] registrationIds ={"diks4vp5......","erPjEb9....."};

        AndroidGcmPushNotification gcmPushNotification = new 
        AndroidGcmPushNotification(
            "API KEY", registrationIds, "Hello World"
            );
        gcmPushNotification.SendGcmNotification();

Classe

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

}
2
Mina Gabriel

Il existe un paquet PushSharp . Permet de communiquer avec presque toutes les API de notification populaires.

Exemple de code:

// 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 ();
1
dariol