web-dev-qa-db-fra.com

Implémentation de base Android GCM

UPDATE: J'ai corrigé les problèmes dans le code ci-dessous, ce qui en fait un bon exemple de base d'utilisation de GCM


J'essaie donc d'implémenter Android GCM dans mon application. Voici les parties pertinentes que j'ai ajoutées au manifeste:

<uses-sdk Android:minSdkVersion="8" Android:targetSdkVersion="20" />

<permission
    Android:name=".permission.C2D_MESSAGE"
    Android:protectionLevel="signature" />
<uses-permission Android:name="com.google.Android.c2dm.permission.RECEIVE" />
<uses-permission Android:name=".permission.C2D_MESSAGE" />
<uses-permission Android:name="Android.permission.WAKE_LOCK"/>
<uses-permission Android:name="Android.permission.GET_ACCOUNTS"/>

...

<receiver
    Android:name="com.google.Android.gcm.GCMBroadcastReceiver"
    Android:permission="com.google.Android.c2dm.permission.SEND" >
    <intent-filter>
        <action Android:name="com.google.Android.c2dm.intent.RECEIVE" />
        <action Android:name="com.google.Android.c2dm.intent.REGISTRATION" />
        <category Android:name="com.badbob.app.gmctestapp" />
    </intent-filter>
</receiver>

<service Android:name=".GCMIntentService" />

J'ai ajouté le code suivant à la onCreate de mon activité principale:

    GCMRegistrar.checkDevice( this );
    GCMRegistrar.checkManifest( this );
    final String regId = GCMRegistrar.getRegistrationId( this );
    if( regId.equals( "" ) ) {
        GCMRegistrar.register( this, GCM_SENDER_ID );
    }
    else {
        Log.v( LOG_TAG, "Already registered" );
    }

J'ai aussi créé la classe GCMIntenetService comme ceci:

public class GCMIntentService extends GCMBaseIntentService {

    private static final String LOG_TAG = "GetAClue::GCMIntentService";

    public GCMIntentService() {
        super( GCM_SENDER_ID );
        // TODO Auto-generated constructor stub
        Log.i( LOG_TAG, "GCMIntentService constructor called" );
    }

    @Override
    protected void onError( Context arg0, String errorId ) {
        // TODO Auto-generated method stub
        Log.i( LOG_TAG, "GCMIntentService onError called: " + errorId );
    }

    @Override
    protected void onMessage( Context arg0, Intent intent ) {
        // TODO Auto-generated method stub
        Log.i( LOG_TAG, "GCMIntentService onMessage called" );
        Log.i( LOG_TAG, "Message is: " + intent.getStringExtra( "message" ) );
    }

    @Override
    protected void onRegistered( Context arg0, String registrationId ) {
        // TODO Auto-generated method stub
        Log.i( LOG_TAG, "GCMIntentService onRegistered called" );
        Log.i( LOG_TAG, "Registration id is: " + registrationId );
    }

    @Override
    protected void onUnregistered( Context arg0, String registrationId ) {
        // TODO Auto-generated method stub
        Log.i( LOG_TAG, "GCMIntentService onUnregistered called" );
        Log.i( LOG_TAG, "Registration id is: " + registrationId );
    }
}

Quand je lance ceci je reçois ceci dans LogCat :

07-11 11:28:46.340: V/GCMRegistrar(27435): Registering receiver
07-11 11:28:46.370: D/GCMRegistrar(27435): resetting backoff for com.badbob.app.getacluebeta
07-11 11:28:46.380: V/GCMRegistrar(27435): Registering app com.badbob.app.getacluebeta of senders 128205395388

D'après ce que j'ai découvert dans d'autres publications, je devrais obtenir un identifiant d'enregistrement dans LogCat mais je ne le suis pas. De plus, onRegistered() dans GCMIntentService n'est jamais appelé.

28
Rooster242

ceci est une erreur

protected GCMIntentService( String senderId ) {         
super(senderId);}

Comme il est dit dans la documentation. vous devez déclarer un constructeur PUBLIC, NO ARGUMENT pour GCMIntentService. Sinon, GCMIntentService ne peut pas être instancié correctement par les services d'intention d'arrière-plan.

public GCMIntentService(){
super(senderID);}

le senderID peut être une chaîne constante codée en dur car elle ne changera plus avec le nouveau GCM . Il est également très important d'utiliser le bon senderID. 24 heures suffisent pour que le vôtre soit actif. Par conséquent, si la solution ci-dessus ne fonctionne pas, vous utilisez un ID émetteur incorrect. Tout le reste a l'air bien.

Le senderID se trouve dans l'URL de votre navigateur Web lorsque vous naviguez sur la page d'accès à l'API Google. Cliquez sur GCM et un numéro à 12 chiffres sera présent dans l'URL du navigateur. C'est la clé correcte à utiliser. PAS votre clé API. Cela est utilisé du côté du serveur d'applications.

18
Ryan Gray

J'ai aussi eu ce bug ANNOYing, jusqu'à maintenant. Le problème était que j’ai déclaré l’intentservice dans un autre paquet ... même si j’ai déclaré le nom dans le manifeste Android et qu’aucune exception classnotfound n’avait eu lieu intentservice se trouve dans le package racine.

8
redestructa
3
duggu

Je pense que vous avez des problèmes dans le code.

Vous devez enregistrer votre propre récepteur de radiodiffusion dans le fichier manifeste et ce récepteur déclenchera le <service Android:name=".GCMIntentService" />.

Par conséquent, vous devez faire quelque chose comme je l'écris ci-dessous.

  • Le destinataire doit être déclaré comme:

    <receiver
        Android:name="your.package.name.YourBroadCastReceiver"
        Android:permission="com.google.Android.c2dm.permission.SEND" >
        <intent-filter>
            <action Android:name="com.google.Android.c2dm.intent.RECEIVE" />
            <action Android:name="com.google.Android.c2dm.intent.REGISTRATION" />
        </intent-filter>
    

  • Votre récepteur de radiodiffusion qui lancera le service.

    public class YourBroadCastReceiver extends BroadcastReceiver {
    
    @Override
     public final void onReceive(Context context, Intent intent) {
         GCMIntentService .runIntentInService(context, intent);
         setResult(Activity.RESULT_OK, null, null);
     }  
    }
    

Je vous conseille de consulter le document officiel GCM documentation où vous pouvez trouver un bon exemple.

Et ... n'oubliez pas d'activer le service Google Cloud Messaging dans la page principale de la console des API Google.

Faites-moi savoir si cela aide!

3
yugidroid

Si vous ne recevez pas de réponse de l'enregistrement, l'une des raisons principales est que votre fichier manifeste n'est pas configuré correctement - donnez en particulier le "package_name" (le nom de votre package d'application tel que com.xxx.yyy) dans les codes <permission> et <intent filter>.

0
Vinoth Prakash K

Pas sûr que cela soit lié à votre problème spécifique, cependant, je rencontrais le même problème. Autant que je sache, tout était configuré correctement, mais le gestionnaire onRegistered() n'a jamais été appelé.

J'avais les méthodes de service standard onCreate(), onStart() et onDestroy() dans le cadre de ma classe GCMIntentService. Une fois que je les ai retirés, le gestionnaire a été appelé, comme prévu.

Mon hypothèse est qu'en redéfinissant ces méthodes, je contournais l'initialisation du code nécessaire.

0
ClouDeveloper

Vous devez également vous inscrire auprès de votre serveur d'applications dans le répertoire GCMBaseIntentService.onRegistered () callback. Sinon, vous ne pourrez pas envoyer les messages de votre application.

Vous devriez vraiment acheter le client de démonstration GCM de Google car il fournit un exemple de travail avec tout le code correct. Nous avons également un échantillon de travail sur github: airbop-client . Il fournit un exemple un peu plus complet dans la mesure où il entretient des interactions de travail avec un serveur d'applications, ce qui est nécessaire pour une application compatible GCM. Cela fonctionne avec les AirBop serveurs (que j'ai aidé à créer), qui sont libres jusqu'à 1000 appareils.

0
selsine

Après avoir lu le message de ClouDeveloper, j'ai supprimé onCreate(), onDestroy() et les autres méthodes onXXX () callback. De plus, mon GCMIntentService.onRegistered(Context, regId) est appelé avec la regId.

Merci ClouDeveloper!

0
tt6