Notifications push dans la plateforme Android

266

Je cherche à écrire une application qui reçoit des alertes poussées d'un serveur. J'ai trouvé quelques méthodes pour ce faire.

  1. SMS - Intercepter le SMS entrant et lancer une extraction depuis le serveur
  2. Sondez le serveur périodiquement

Chacun a ses propres limites. SMS - aucune garantie sur l'heure d'arrivée. Le sondage peut décharger la batterie.

Avez-vous une meilleure suggestion s'il vous plaît? Merci beaucoup.

Vinod
la source
4
Vous pouvez également regarder la présentation Google I / O 2010 sur la notification push developer.android.com/videos/index.html#v=PLM4LajwDVc
vokilam
Je pense que vous pouvez consulter ce post: stackoverflow.com/questions/17629942/… Avec Worklight, vous pouvez recevoir des push via différents canaux, y compris GCM.
Neeraj Krishna du
1
La présentation Google I / O 2010 est disponible sur youtube.com/watch?v=PLM4LajwDVc
elcuco
"Le sondage peut décharger la batterie." Vous pouvez planifier un sondage avec AlarmManager, afin que la batterie ne soit pas épuisée. C'est une solution simple et gratuite (pas besoin de payer, comme avec GCM).
Deepscorn
ont le même problème stackoverflow.com/questions/35812304/…
albert

Réponses:

203

La réponse officielle de Google est le cadre de messagerie Android Cloud to Device (obsolète) Google Cloud Messaging (obsolète) Firebase Cloud Messaging

Cela fonctionnera sur Android> = 2.2 (sur les téléphones qui ont le Play Store).

BoD
la source
il est actuellement en version bêta, mais vous pouvez vous inscrire dans l'espoir d'être activé.
brack
3
Vous pouvez généralement être activé très rapidement, et il est utilisé pour des choses comme GMail, il est donc important de travailler en production. Malheureusement, leur exemple de code pour communiquer avec l'aspect côté serveur de C2DM fait défaut. J'ai rédigé un tutoriel pour cet aspect ici blog.boxedice.com/2010/10/07/…
davidmytton
6
Le problème est que vous avez besoin d'un compte Google pour vos utilisateurs: ce qui est, je pense, une contrainte.
kaffein
33
Notez que le cadre de messagerie Android Cloud to Device est obsolète. Le nouveau cadre s'appelle Google Cloud Messaging et peut être trouvé ici: developer.android.com/guide/google/gcm/index.html
Ryan Berger
Le 10 avril 2018, Google a déconseillé GCM. Le serveur GCM et les API client ont été supprimés le 29 mai 2019. Migrez les applications GCM vers Firebase Cloud Messaging (FCM), qui hérite de l'infrastructure GCM fiable et évolutive, ainsi que de nombreuses nouvelles fonctionnalités. Consultez le guide de migration pour en savoir plus.
paiego
29

( publication croisée d'une réponse que j'ai donnée à une question similaire - Android prend-il en charge la notification push en temps quasi réel? )

J'ai récemment commencé à jouer avec MQTT http://mqtt.org pour Android comme moyen de faire ce genre de chose (c'est-à-dire une notification push qui n'est pas SMS mais pilotée par les données, la livraison de messages presque immédiate, pas d'interrogation, etc.)

J'ai un article de blog avec des informations générales à ce sujet au cas où cela serait utile

http://dalelane.co.uk/blog/?p=938

(Remarque: MQTT est une technologie IBM, et je dois souligner que je travaille pour IBM.)

dalelane
la source
Salut Dale, j'ai lu votre article de blog sur MQTT et il semble définitivement correspondre à la facture pour une notification presque instantanée sur les mobiles. Mais je n'ai pas pu trouver d'informations sur la façon dont il le fait réellement. Maintient-il une prise ouverte à tout moment? Comment informe-t-il le serveur si son adresse IP a changé? Je vous serais reconnaissant de bien vouloir éclairer ce point. Cheers Naren
Naren
2
Il maintient une connexion ouverte. Dans un article de suivi ( dalelane.co.uk/blog/?p=1009 ), j'ai parlé davantage des implications de maintenir une connexion ouverte - l'avez-vous vu? Si la connexion est rompue, le serveur et le client peuvent être avertis. Ensuite, c'est une décision de la couche application de décider comment répondre (par exemple, se reconnecter). Il y a plus d'informations dans les documents mentionnés dans le post (par exemple IA92: www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006 pdf sur cette page, et Javadoc dans le zip sur cette page)
dalelane
18

Ma compréhension / expérience avec la notification push Android est:

  1. C2DM GCM - Si votre plate-forme Android cible est 2.2+, alors allez-y. Un seul hic, les utilisateurs d'appareils doivent toujours être connectés avec un compte Google pour recevoir les messages.

  2. MQTT - Approche basée sur Pub / Sub, nécessite une connexion active de l'appareil, peut décharger la batterie si elle n'est pas implémentée de manière sensée.

  3. Diacre - Peut ne pas être bon à long terme en raison du soutien limité de la communauté.

Edit : Ajouté le 25 novembre 2013

GCM - Google dit ...

Pour les appareils antérieurs à 3.0, les utilisateurs doivent configurer leur compte Google sur leurs appareils mobiles. Un compte Google n'est pas obligatoire sur les appareils fonctionnant sous Android 4.0.4 ou supérieur. *

Lalit
la source
Bien qu'un compte Google ne soit pas requis pour 4.0.4 ou supérieur, il semble que vous ayez installé l'application Google Play. Je me demande comment vous installez cela sans avoir de compte Google.
Jan
1
@Jan: l'application Google Play est installée avec l'appareil. L'utilisateur n'a pas besoin d'installer.
Dexter
@Dexter, Google Play n'est pas installé par défaut sur tous les appareils Android. La plupart l'ont installé par défaut, en particulier les appareils achetés auprès de fournisseurs de téléphones réputés, mais les appareils sur lesquels le système d'exploitation Android est flashé peuvent ne pas toujours avoir Google Play. (Par exemple, de nombreux émulateurs Android, tels que les nouveaux appareils Genymotion, n'ont pas Google Play par défaut.)
Spencer D
Alors ... MQTT est-il la meilleure option pour les appareils Android sur lesquels Google Play n'est pas installé?
Yeung
17

Cadre de messagerie Android Cloud to Device

Important: C2DM est officiellement obsolète depuis le 26 juin 2012. Cela signifie que C2DM a cessé d'accepter de nouveaux utilisateurs et demandes de quota. Aucune nouvelle fonctionnalité ne sera ajoutée à C2DM. Cependant, les applications utilisant C2DM continueront de fonctionner. Les développeurs C2DM existants sont encouragés à migrer vers la nouvelle version de C2DM, appelée Google Cloud Messaging pour Android (GCM). Voir le document de migration C2DM vers GCM pour plus d'informations. Les développeurs doivent utiliser GCM pour les nouveaux développements.

Veuillez vérifier le lien suivant:

http://developer.android.com/guide/google/gcm/index.html

chiranjib
la source
17

Ici, j'ai écrit quelques étapes pour savoir comment obtenir RegID et notification à partir de zéro

  1. Créer / enregistrer une application sur Google Cloud
  2. Configurer le SDK Cloud avec le développement
  3. Configurer le projet pour GCM
  4. Obtenir l'ID d'enregistrement de l'appareil
  5. Envoyer des notifications push
  6. Recevoir des notifications push

Vous pouvez trouver un tutoriel complet dans le lien URL ci-dessous

Prise en main d'Android Push Notification: dernière version de Google Cloud Messaging (GCM) - tutoriel complet étape par étape

entrez la description de l'image ici

Coupure de code pour obtenir l'ID d'enregistrement (jeton de périphérique pour la notification push).

Configurer le projet pour GCM


Mettre à jour le fichier AndroidManifest

Pour activer GCM dans notre projet, nous devons ajouter quelques autorisations dans notre fichier manifeste. Allez sur AndroidManifest.xml et ajoutez le code ci-dessous Ajouter une autorisation

<uses-permission android:name="android.permission.INTERNET”/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<uses-permission android:name="android.permission.VIBRATE" />

<uses-permission android:name=“.permission.RECEIVE" />
<uses-permission android:name=“<your_package_name_here>.permission.C2D_MESSAGE" />
<permission android:name=“<your_package_name_here>.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

Ajouter une déclaration de récepteur de diffusion GCM

ajoutez la déclaration GCM Broadcast Receiver dans votre balise d'application

<application
        <receiver
            android:name=".GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" ]]>
            <intent-filter]]>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="" />
            </intent-filter]]>

        </receiver]]>
     
<application/>

Ajouter la déclaration GCM Servie

<application
     <service android:name=".GcmIntentService" />
<application/>

Obtenir l'ID d'enregistrement (jeton d'appareil pour la notification push)

Allez maintenant à votre activité de lancement / Splash

Ajouter des constantes et des variables de classe

private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
public static final String EXTRA_MESSAGE = "message";
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
private final static String TAG = "LaunchActivity";
protected String SENDER_ID = "Your_sender_id";
private GoogleCloudMessaging gcm =null;
private String regid = null;
private Context context= null;

Mettre à jour les méthodes OnCreate et OnResume

@Override
protected void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_launch);
     context = getApplicationContext();
         if (checkPlayServices()) 
     {
            gcm = GoogleCloudMessaging.getInstance(this);
            regid = getRegistrationId(context);

            if (regid.isEmpty())
            {
                registerInBackground();
            }
            else
            {
            Log.d(TAG, "No valid Google Play Services APK found.");
            }
      }
 }

@Override protected void onResume()
{
       super.onResume();       checkPlayServices();
}


# Implement GCM Required methods (Add below methods in LaunchActivity)

private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                        PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Log.d(TAG, "This device is not supported - Google Play Services.");
                finish();
            }
            return false;
        }
        return true;
 }

private String getRegistrationId(Context context) 
{
   final SharedPreferences prefs = getGCMPreferences(context);
   String registrationId = prefs.getString(PROPERTY_REG_ID, "");
   if (registrationId.isEmpty()) {
       Log.d(TAG, "Registration ID not found.");
       return "";
   }
   int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
   int currentVersion = getAppVersion(context);
   if (registeredVersion != currentVersion) {
        Log.d(TAG, "App version changed.");
        return "";
    }
    return registrationId;
}

private SharedPreferences getGCMPreferences(Context context) 
{
    return getSharedPreferences(LaunchActivity.class.getSimpleName(),
                Context.MODE_PRIVATE);
}

private static int getAppVersion(Context context) 
{
     try 
     {
         PackageInfo packageInfo = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            return packageInfo.versionCode;
      } 
      catch (NameNotFoundException e) 
      {
            throw new RuntimeException("Could not get package name: " + e);
      }
}


private void registerInBackground() 
{     new AsyncTask() {
     Override
     protected Object doInBackground(Object... params) 
     {
          String msg = "";
          try 
          {
               if (gcm == null) 
               {
                        gcm = GoogleCloudMessaging.getInstance(context);
               }
               regid = gcm.register(SENDER_ID);               Log.d(TAG, "########################################");
               Log.d(TAG, "Current Device's Registration ID is: "+msg);     
          } 
          catch (IOException ex) 
          {
              msg = "Error :" + ex.getMessage();
          }
          return null;
     }     protected void onPostExecute(Object result) 
     { //to do here };
  }.execute(null, null, null);
}

Remarque : veuillez stocker REGISTRATION_KEY, il est important pour l'envoi d'un message PN à GCM de garder également dans le mien ce sera unique pour tous les appareils, en utilisant cela seul GCM enverra une notification push.

Recevoir des notifications push

Ajouter une classe de récepteur de diffusion GCM

Comme nous avons déjà déclaré «GcmBroadcastReceiver.java» dans notre fichier manifeste, nous allons donc créer ce code de classe de récepteur de mise à jour de classe de cette façon

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) 
    {        ComponentName comp = new ComponentName(context.getPackageName(),
                GcmIntentService.class.getName());        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
        Toast.makeText(context, wow!! received new push notification", Toast.LENGTH_LONG).show();
    }
}

Ajouter une classe de service GCM

Comme nous avons déjà déclaré «GcmBroadcastReceiver.java» dans notre fichier manifeste, nous allons donc créer ce code de classe de récepteur de mise à jour de classe de cette façon

public class GcmIntentService extends IntentService
{     public static final int NOTIFICATION_ID = 1;     private NotificationManager mNotificationManager;     private final static String TAG = "GcmIntentService";     public GcmIntentService() {
     super("GcmIntentService");     
     }     @Override
     protected void onHandleIntent(Intent intent) {
          Bundle extras = intent.getExtras();
          Log.d(TAG, "Notification Data Json :" + extras.getString("message"));

          GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
          String messageType = gcm.getMessageType(intent);          if (!extras.isEmpty()) {          if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
               .equals(messageType)) {
               sendNotification("Send error: " + extras.toString());
          } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
          .equals(messageType)) {
          sendNotification("Deleted messages on server: "
          + extras.toString());          // If it's a regular GCM message, do some work.
          } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
          .equals(messageType)) {
          // This loop represents the service doing some work.
          for (int i = 0; i < 5; i++) {
               Log.d(TAG," Working... " + (i + 1) + "/5 @ "
               + SystemClock.elapsedRealtime());               try {
                    Thread.sleep(5000);
               } catch (InterruptedException e) {
               }
             }
             Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
             sendNotification(extras.getString("message"));
           }
        }        // Release the wake lock provided by the WakefulBroadcastReceiver.
        GcmBroadcastReceiver.completeWakefulIntent(intent);
     }     // Put the message into a notification and post it.
     // This is just one simple example of what you might choose to do with
     // a GCM message.
     private void sendNotification(String msg) {          mNotificationManager = (NotificationManager) this
          .getSystemService(Context.NOTIFICATION_SERVICE);
          PendingIntent contentIntent = PendingIntent.getActivity(this, 0,          new Intent(this, LaunchActivity.class), 0);

          NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(          this)
          .setSmallIcon(R.drawable.icon)
          .setContentTitle("Ocutag Snap")
          .setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
          .setContentText(msg)
          .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);

          mBuilder.setContentIntent(contentIntent);          mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
     }
}
swiftBoy
la source
@Rohit avez-vous vérifié le lien en ayant un tutoriel complet. veuillez également me faire savoir ce qui manque, je mettrai à jour la réponse.
swiftBoy
11

Il y a un nouvel effort open source pour développer une bibliothèque Java pour les notifications push sur Android basée sur le serveur Web Meteor. Vous pouvez le vérifier sur le blog du projet Deacon , où vous trouverez des liens vers Meteor et le référentiel GitHub du projet. Nous avons besoin de développeurs, alors faites passer le mot!

mtbkrdave
la source
9

Vous pouvez utiliser Xtify ( http://developer.xtify.com ) - ils ont un service Web de notifications push qui fonctionne avec leur SDK. c'est gratuit et jusqu'à présent, cela a très bien fonctionné pour moi.

peter
la source
3
J'ai reçu une réponse de leur vice-président disant qu'il n'était pas prévu de facturer le service push. C'est un SDK assez étonnant.
Crowe T. Robot
8

ou....

3) Gardez une connexion au serveur, envoyez des messages persistants toutes les quelques minutes et le serveur peut envoyer des messages instantanément. C'est ainsi que Gmail, Google Talk, etc. fonctionnent.

Isaac Waller
la source
5
Je pense que cela produira, malheureusement, une lourde charge de batterie. SI vous empruntez cette route, assurez-vous de limiter la durée de cette opération.
haseman
Non, en fait, ce ne sera pas le cas, car les connexions TCP / IP inactives ne prennent presque pas d'alimentation sur le modem cellulaire.
Isaac Waller, le
En fait, cela prendra beaucoup de temps, alors vous avez raison. L'envoi de souvenirs persistants avec de longs intervalles aide aussi beaucoup.
Isaac Waller, le
Que sont les "longs intervalles" à cet égard? Je sais que Gmail Push fonctionne comme ça, mais je ne sais pas quels intervalles de temporisation ils utilisent.
tobsen
J'ai trouvé cette image sur les performances de la batterie Pull vs Push: labs.ericsson.com/files/battery.jpg Je l'ai tirée de l'API Ericsson Push ici: labs.ericsson.com/apis/mobile-java-push/documentation
Menda
6

Je recommande d'utiliser GCM - Google Cloud Messaging pour Android C'est gratuit, et pour des utilisations simples, cela devrait être très facile.

Cependant, il nécessite de maintenir un serveur tiers pour envoyer les notifications en votre nom. Si vous voulez éviter qu'il existe de très bonnes solutions industrielles pour le service de notifications push Android:

  • Urban Airship - gratuit jusqu'à 1M de notifications par mois, après quoi vous êtes facturé pour 1000 notifications
  • PushApps - gratuit pour 1M de notifications par mois et notifications illimitées pour 19,99 par mois
  • PushWoosh - gratuit pour les appareils 1M, les plans premium sont à partir de 39 EURO

Diclaimer - Je travaille dans PushApps et j'utilise également leur produit dans mes applications depuis plus d'un an maintenant.

Orr
la source
6

Depuis le 18/05/2016, Firebase est la plate-forme unifiée de Google pour les développeurs mobiles, y compris les notifications push.

Freek Nortier
la source
4

Je crains que vous n'ayez trouvé les deux méthodes possibles. Google allait, au moins initialement, implémenter une API GChat que vous pourriez utiliser pour une implémentation push / pull. Malheureusement, cette bibliothèque a été supprimée par Android 1.0.

haseman
la source
1
Ils ont promis de le ramener une fois que les problèmes de sécurité auront été résolus ... si cela se produit.
Jeremy Logan
3

Je ne sais pas si c'est toujours utile. J'ai réalisé quelque chose comme ça avec une bibliothèque java à http://www.pushlets.com/

Bien que le faire dans un service n'empêchera pas Android de le fermer et de tuer le fil d'écoute.

n3utrino
la source
2

C2DM: vos utilisateurs d'applications doivent avoir le compte gmail.

MQTT: lorsque votre connexion atteindra 1024, il cessera de fonctionner car il a utilisé "select model" de linux.

Il existe un service push gratuit et une api pour Android, vous pouvez l'essayer: http://push-notification.org

Jacky
la source
2

Méthode gratuite et facile:

Si votre base d'utilisateurs cible n'est pas importante (moins de 1 000) et que vous souhaitez commencer par un service gratuit, alors Airbop est le meilleur et le plus pratique.

Site Airbop Il utilise le service Google Cloud Messaging via son API et offre de bonnes performances. Je l'ai utilisé pour deux de mes projets et c'était facile à mettre en œuvre.

Des services comme et Urbanship sont excellents mais fournissent une pile de déploiement complète et pas seulement la chose des notifications push.

Si seul le service push est votre cible, Airbop fonctionnera bien.

Je n'ai pas utilisé Pushwoosh , mais c'est aussi un excellent choix. Il permet de pousser jusqu'à 1 000 000 d'appareils gratuitement

adimoh
la source
1

Je suggère d'utiliser à la fois SMS et HTTP. Si l'utilisateur n'est pas connecté, envoyez un SMS à son téléphone pour l'informer qu'il y a un message en attente.

Voilà comment fonctionne ce service Ericsson Labs: https://labs.ericsson.com/apis/mobile-java-push/

Si vous l'implémentez vous-même, la partie délicate consiste à supprimer le SMS entrant sans que l'utilisateur ne le voie. Ou peut-être que ce n'est pas grave s'ils le voient dans votre cas.

Il semble que cela fonctionne: Suppression de SMS à l'aide de BroadCastReceiver - Android

Oui, écrire du code comme celui-ci peut être dangereux et vous pouvez potentiellement ruiner la vie de quelqu'un parce que votre application a supprimé un SMS qu'elle ne devrait pas avoir.

Sarel Botha
la source
1
lol: "Oui, écrire du code comme celui-ci peut être dangereux et vous pouvez potentiellement ruiner la vie de quelqu'un parce que votre application a supprimé un SMS qu'elle ne devrait pas avoir." voter pour cela. lol.
Kumar Ravi
Le lien vers Mobile Java Push est mort et le service lui-même semble obsolète.
naXa
1

Vous pouvez utiliser Google Cloud Messaging ou GCM , c'est gratuit et facile à utiliser. Vous pouvez également utiliser des serveurs push tiers comme PushWoosh, ce qui vous donne plus de flexibilité

Mohsen Afshin
la source
1

Il y a beaucoup de serveurs tiers comme Urban Airship , Xtify, Mainline , ... qui permettent d'envoyer non seulement sur Android, mais aussi sur iOs, Windows Phone ...

Panchine Lac
la source
1

Messagerie cloud Firebase (FCM) est la nouvelle version de GCM. FCM est une solution de messagerie multiplateforme qui vous permet d'envoyer des messages en toute sécurité et gratuitement. Hérite de l'infrastructure centrale de GCM pour délivrer des messages de manière fiable sur Android, iOS, Web (javascript), Unity et C ++.

Au 10 avril 2018, Google avait refusé GCM. Le serveur GCM et les API clientes sont obsolètes et seront supprimés le 11 avril 2019. Google recommande de migrer les applications GCM vers Firebase Cloud Messaging (FCM), qui hérite de l'infrastructure GCM fiable et évolutive.

Ressource

Fahed Hermoza
la source
0

Vous pouvez utiliser Pusher

Il s'agit d'un service hébergé qui facilite l'ajout de données et de fonctionnalités en temps réel aux applications Web et mobiles.
Pusher propose des bibliothèques à intégrer dans tous les principaux runtimes et frameworks.

PHP, Ruby, Python, Java, .NET, Go and Nodesur le serveur
JavaScript, Objective-C (iOS) and Java (Android)sur le client.

Arash Hatami
la source