C2DMBroadcastReceiver onReceive not executing (for registration)

Im developing a C2DM Messaging application. In this case, I get the registration identifier im using classes C2DMBroadcastReceiver, C2DMBaseReceiverand C2DMMessaging. I will be C2DMReceiverin my package, which expands C2DMBaseReceiver.

Here is my code snippet

C2DMMessaging.java

package com.google.android.c2dm;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.Log;

public class C2DMessaging {
    public static final String EXTRA_SENDER = "sender";
    public static final String EXTRA_APPLICATION_PENDING_INTENT = "app";
    public static final String REQUEST_UNREGISTRATION_INTENT = "com.google.android.c2dm.intent.UNREGISTER";
    public static final String REQUEST_REGISTRATION_INTENT = "com.google.android.c2dm.intent.REGISTER";
    public static final String LAST_REGISTRATION_CHANGE = "last_registration_change";
    public static final String BACKOFF = "backoff";
    public static final String GSF_PACKAGE = "com.google.android.gsf";

    // package
    static final String PREFERENCE = "com.google.android.c2dm";

    private static final long DEFAULT_BACKOFF = 30000;

    /**
     * Initiate c2d messaging registration for the current application
     */
    public static void register(Context context,
            String senderId) {
        Intent registrationIntent = new Intent(REQUEST_REGISTRATION_INTENT);
        registrationIntent.setPackage(GSF_PACKAGE);
        registrationIntent.putExtra(EXTRA_APPLICATION_PENDING_INTENT,
                PendingIntent.getBroadcast(context, 0, new Intent(), 0));
        registrationIntent.putExtra(EXTRA_SENDER, senderId);
        context.startService(registrationIntent);
        Log.e("C2DM Services","Service Started");

    }

    /**
     * Unregister the application. New messages will be blocked by server.
     */
    public static void unregister(Context context) {
        Intent regIntent = new Intent(REQUEST_UNREGISTRATION_INTENT);
        regIntent.setPackage(GSF_PACKAGE);
        regIntent.putExtra(EXTRA_APPLICATION_PENDING_INTENT, PendingIntent.getBroadcast(context,
                0, new Intent(), 0));
        context.startService(regIntent);
        Log.e("C2DM Services","unregister");
    }

    /**
     * Return the current registration id.
     *
     * If result is empty, the registration has failed.
     *
     * @return registration id, or empty string if the registration is not complete.
     */
    public static String getRegistrationId(Context context) {
        final SharedPreferences prefs = context.getSharedPreferences(
                PREFERENCE,
                Context.MODE_PRIVATE);
        String registrationId = prefs.getString("dm_registration", "");
        Log.e("C2DM Services","get registration id");
        return registrationId;

    }

    public static long getLastRegistrationChange(Context context) {
        final SharedPreferences prefs = context.getSharedPreferences(
                PREFERENCE,
                Context.MODE_PRIVATE);
        Log.e("C2DM Services","getlastregchange");
        return prefs.getLong(LAST_REGISTRATION_CHANGE, 0);
    }

    static long getBackoff(Context context) {
        final SharedPreferences prefs = context.getSharedPreferences(
                PREFERENCE,
                Context.MODE_PRIVATE);
        Log.e("C2DM Services","getbackoff");
        return prefs.getLong(BACKOFF, DEFAULT_BACKOFF);
    }

    static void setBackoff(Context context, long backoff) {
        final SharedPreferences prefs = context.getSharedPreferences(
                PREFERENCE,
                Context.MODE_PRIVATE);
        Editor editor = prefs.edit();
        editor.putLong(BACKOFF, backoff);
        editor.commit();
        Log.e("C2DM Services","setbackoff");
    }

    // package
    static void clearRegistrationId(Context context) {
        final SharedPreferences prefs = context.getSharedPreferences(
                PREFERENCE,
                Context.MODE_PRIVATE);
        Editor editor = prefs.edit();
        editor.putString("dm_registration", "");
        editor.putLong(LAST_REGISTRATION_CHANGE, System.currentTimeMillis());
        editor.commit();
        Log.e("C2DM Services","clearregid");
    }

    // package
    static void setRegistrationId(Context context, String registrationId) {
        final SharedPreferences prefs = context.getSharedPreferences(
                PREFERENCE,
                Context.MODE_PRIVATE);
        Editor editor = prefs.edit();
        editor.putString("dm_registration", registrationId);
        editor.commit();
        Log.e("C2DM Services","setregid");
    }
}

C2DMBroadcastReceiver.java

package com.google.android.c2dm;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class C2DMBroadcastReceiver extends BroadcastReceiver {

    @Override
    public final void onReceive(Context context, Intent intent) {
        // To keep things in one place.
           Log.e("C2DM Broadcast receiver","onReceive");
        C2DMBaseReceiver.runIntentInService(context, intent);
        setResult(Activity.RESULT_OK, null /* data */, null /* extra */);        
    }

}

Manifest file

<permission android:name="com.sample.gt.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
 <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.sample.gt.permission.C2D_MESSAGE" />
    <!-- Permissions -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <service android:name="com.sample.gt.c2dm.C2DMReceiver" />

    <!--
        Only C2DM servers can send messages for the app. If permission is not
        set - any other app can generate it
    -->
    <receiver android:name="com.google.android.c2dm.C2DMBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND">
        <!-- Receive the actual message -->
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="com.sample.gt.c2dm" />
        </intent-filter>
        <!-- Receive the registration id -->
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
            <category android:name="com.sample.gt.c2dm" />
        </intent-filter>
    </receiver>

C2DMMessaging.java

public class C2DMessaging {
    public static final String EXTRA_SENDER = "sender";
    public static final String EXTRA_APPLICATION_PENDING_INTENT = "app";
    public static final String REQUEST_UNREGISTRATION_INTENT = "com.google.android.c2dm.intent.UNREGISTER";
    public static final String REQUEST_REGISTRATION_INTENT = "com.google.android.c2dm.intent.REGISTER";
    public static final String LAST_REGISTRATION_CHANGE = "last_registration_change";
    public static final String BACKOFF = "backoff";
    public static final String GSF_PACKAGE = "com.google.android.gsf";


    // package
    static final String PREFERENCE = "com.google.android.c2dm";

    private static final long DEFAULT_BACKOFF = 30000;

    /**
     * Initiate c2d messaging registration for the current application
     */
    public static void register(Context context,
            String senderId) {
        Intent registrationIntent = new Intent(REQUEST_REGISTRATION_INTENT);
        registrationIntent.setPackage(GSF_PACKAGE);
        registrationIntent.putExtra(EXTRA_APPLICATION_PENDING_INTENT,
                PendingIntent.getBroadcast(context, 0, new Intent(), 0));
        registrationIntent.putExtra(EXTRA_SENDER, senderId);
        context.startService(registrationIntent);
        Log.e("C2DM Services","Service Started");
   }
   ..........

}

Now my problem is:

I call Register from C2DMMessaging from my activity, passing context. The service is created in C2DMMessaging, after which im does not receive anything in C2DMBroadcastReceiver onReceive () .

, vogille.de. , , , .

- n googled, , manifest .

, . - ?

+5
3

C2DMReceiver , . , ... :

service android:name="com.sample.gt.c2dm.C2DMReceiver" 

service android:name=".C2DMReceiver"

( )

 <!--C2DM -->
    <service android:name=".C2DMReceiver" />
    <receiver android:name="com.google.android.c2dm.C2DMBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND">
        <!-- Receive the actual message -->
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="my.package" />
        </intent-filter>
        <!-- Receive the registration id -->
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
            <category android:name="my.package" />
        </intent-filter>
    </receiver>
+7

, C2DM , vogille.de . C2DM.jar, eclipse " Android Connected Android Project" ( "" > "" > "" > Google).

: - ! http://code.google.com/eclipse/beta/docs/download.html

:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      ...
>
    <permission
        android:name="my_package_name.permission.C2D_MESSAGE"
        android:protectionLevel="signature"
    />
    <uses-permission android:name="my_package_name.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <application
       ...
    >
        <!-- Only C2DM servers can send messages for the app. If permission is not set - any other app can generate it --> 
        <receiver
            android:name="com.google.android.c2dm.C2DMBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND"
        >
            <!-- Receive the actual message -->
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="my_package_name" />
            </intent-filter>
            <!-- Receive the registration id -->
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="my_package_name" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

, C2DM:

package my_package_name

import com.google.android.c2dm.C2DMBaseReceiver;
import com.google.android.c2dm.C2DMessaging;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

/**
 * Receive C2DM state changes.
 * 
 * Be careful: the various onX receivers may be called from a mysterious
 * context -- in particular they cannot safely create new AsyncTask objects.
 */
public class C2DMReceiver extends C2DMBaseReceiver {

    // GMail account associated with the C2DM application.  Must agree with
    // what the 3rd party server uses to authenticate with C2DM.
    private static final String C2DM_SENDER = "my_email@gmail.com";

    // -----------------------------------------------------------------

    /**
     * Ask this device to register for C2DM messaging.  Will trigger
     * onRegistered (or onError) when finished.
     */
    public static void register(Context context) {
        C2DMessaging.register(context, C2DM_SENDER);
    }

    /**
     * Unregister this device from further C2DM messaging.
     */
    public static void unregister(Context context) {
        C2DMessaging.unregister(context);
    }

    // -----------------------------------------------------------------

    public C2DMReceiver() {
        super(C2DM_SENDER);
    }

    @Override
    protected void onMessage(Context context, Intent intent) {
        // Extras contains whatever your server put into the C2DM message.
        final Bundle extras = intent.getExtras();
    }

    @Override
    public void onError(Context context, String error_id) {
    }

    @Override
    public void onRegistered(Context context, String registration_id) {
    }

    @Override
    public void onUnregistered(Context context) {
    }
}

AppEngine Java. python, , :

class C2dmAuthToken(db.Model):
    """Maintain an auth token used to talk to the C2DM service.  There is at
    most one of these records."""
    role_email = db.StringProperty(indexed=False, default='my_email@gmail.com')
    passwd = db.StringProperty(indexed=False, default='my_password')
    token = db.TextProperty(indexed=False, default='')

class C2dmRegistration(db.Model):
    """Map from user to the C2DM registration id needed for the C2DM
    service to send messages to the registered device."""
    user_id = db.IntegerProperty(required=True)
    registration_id = db.StringProperty(indexed=False)

class RegisterHandler(MyRequestHandler.MyRequestHandler):
    def post(self):
        # Parse arguments.
        user_id = self.parseId('user_id')
        registration_id = self.parseStr('registration_id')

        # Create or update the device record.
        record = C2dmRegistration.gql('WHERE user_id = :1', user_id).get()
        if record == None:
            record = C2dmRegistration(user_id=user_id)
        record.registration_id = registration_id
        record.put()

class UnregisterHandler(MyRequestHandler.MyRequestHandler):
    def post(self):
        # Parse arguments.
        user_id = self.parseId('user_id')

        # Unregister this device.
        record = C2dmRegistration.gql('WHERE user_id = :1', user_id).get()
        if record != None:
            record.delete()

def getAuthToken():
    """Return an auth token associated with the role account.  Login to
    Google and store the auth token if needed."""
    token_record = C2dmAuthToken.all().get()
    if token_record == None:
        token_record = C2dmAuthToken()

    if len(token_record.token) > 0:
        return token_record.token

    form_fields = {
        'accountType' : 'GOOGLE',
        'Email' : token_record.role_email,
        'Passwd' : token_record.passwd,
        'service' : 'ac2dm',
        'source' : 'my_source_name',
    }
    headers = {
        'Content-Type' : 'application/x-www-form-urlencoded',
    }
    result = urlfetch.fetch(url='https://www.google.com/accounts/ClientLogin',
                            payload=urllib.urlencode(form_fields),
                            method=urlfetch.POST,
                            headers=headers)
    if result.status_code != 200:
        logging.warning('getAuthToken: client login http error %d' % result.status_code)
        return None

    for line in result.content.split('\n'):
        if line.startswith('Auth='):
            token_record.token = line[5:]

    if len(token_record.token) == 0:
        logging.warning('getAuthToken: no token')
        return None

    logging.info('getAuthToken allocated new token %s' % token_record.token)
    token_record.put()
    return token_record.token

def setAuthToken(token):
    """Update the auth token."""
    token_record = C2dmAuthToken.all().get()
    if token_record == None:
        token_record = C2dmAuthToken()
    token_record.token = token
    token_record.put()

def sendMessage(dst_user_id, message):
    """Send a message to the dst user device using C2DM."""

    registration_record = C2dmRegistration.gql('WHERE user_id = :1', dst_user_id).get()
    if registration_record == None:
        logging.warning('SendMessage: no such dst_user_id %ld' % dst_user_id)
        return False

    # Use http and not https to avoid an invalid certificate error.
    # Since the request originates inside google hopefully it is
    # never snoop-able to the outside world, and does not contain
    # critically secure info (such as the role password).
    form_fields = {
        'registration_id' : registration_record.registration_id,
        'collapse_key' : '%d' % int(time.time() * 1000),
        'data.message' : message,
    }
    headers = {
        'Content-Type' : 'application/x-www-form-urlencoded',
        'Authorization': 'GoogleLogin auth=%s' % getAuthToken(),
    }
    result = urlfetch.fetch(url='http://android.apis.google.com/c2dm/send',
                            payload=urllib.urlencode(form_fields),
                            method=urlfetch.POST,
                            headers=headers)
    if result.status_code != 200:
        logging.warning('sendMessage: http error %d' % result.status_code)
        return None
    if 'Update-Client-Auth' in result.headers:
        logging.info('updating auth token')
        setAuthToken(result.headers['Update-Client-Auth'])
    return True

def main():    
    application = webapp.WSGIApplication([
        ('/c2dm/register', RegisterHandler),
        ('/c2dm/unregister', UnregisterHandler),
       ], debug=True)
    wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
    main()

Android /c 2dm/register /c2dm/unregister c2dm . backend sendMessage, Google .

gmail. gmail c2dm , . - , , .

, !

+4

, IDE , ( ) , Google > New > Project

android google C2DM, , Google , , , .

, Android-, Google, chrome , vogella.de

C2DMMessaging.register(this, "example@gmail.com);

, : , , , , , .

  • google.
    , http://code.google.com/android/c2dm/signup.html :
    :
    " Android "" " ()"
    - , C2DMMessaging.register
  • Android,
    Android , :
    AVD (Android Virtual Device), "" > Android SDK AVD Manager > Virtual Devices > New
    API Google (Google Inc.) - API 8 ( , > > Google Inc.)
    ,
    AVD "" > " "" " > > Google > google.
  • Before I can fill out other cases, I should see the other Google classes that you use and the C2DMReceiver service you created.


I can not comment due to the low level of user reputation.

+3
source

All Articles