プッシュ通知実装を行っているのですが、サーバからのデータを受け取る段階でクラッシュしてしまいます。 環境はEclipseでgoogle play service libはプロジェクトを作ってimportし、ライブラリとして追加。 suport v4 はandroid toolsからadd support libraryして追加しました。

エラー:

FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to instantiate receiver org.techbooster.gcmsample.GCMBroadcastReceiver: java.lang.ClassNotFoundException: Didn't find class "org.techbooster.gcmsample.GCMBroadcastReceiver" on path: /data/app/org.techbooster.gcmsample-1.apk
    at android.app.ActivityThread.handleReceiver(ActivityThread.java:2371)
    at android.app.ActivityThread.access$1500(ActivityThread.java:149)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1322)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:213)
    at android.app.ActivityThread.main(ActivityThread.java:5092)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.techbooster.gcmsample.GCMBroadcastReceiver" on path: /data/app/org.techbooster.gcmsample-1.apk
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:65)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
    at android.app.ActivityThread.handleReceiver(ActivityThread.java:2366)
    ... 10 more

アクティビティ

package org.techbooster.gcmsample;

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.gcm.GoogleCloudMessaging;

import org.techbooster.gcmsample.CommonUtilities;
import org.techbooster.gcmsample.*;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener{

    private static final String TAG = "TechBoosterSample";

    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 int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;

    GoogleCloudMessaging gcm;
    String regid;
    Context context;

    /**
     * サーバー通信用AsyncTask
     */
    AsyncTask<Void, Void, Void> mRegisterTask;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnRegist = (Button) findViewById(R.id.btn_regist);
        btnRegist.setOnClickListener(this);
        Button btnUnregist = (Button) findViewById(R.id.btn_unregist);
        btnUnregist.setOnClickListener(this);

        context = getApplicationContext();

        // デバイスにPlayサービスAPKが入っているか検証する
        if (checkPlayServices()) {
            gcm = GoogleCloudMessaging.getInstance(context);
            regid = getRegistrationId(context);
        } else {
            Log.i(TAG, "Google Play Services APKが見つかりません");
        }
    }

    /*
     * PlayサービスのAPKチェック
     */
    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.i(TAG, "Playサービスがサポートされていない端末です");
                finish();
            }
            return false;
        }
        return true;
    }

    /*
     * レジストレーションIDの取得
     */   
    private String getRegistrationId(Context context) {
        final SharedPreferences prefs = getGCMPreferences(context);
        String registrationId = prefs.getString(PROPERTY_REG_ID, "");

        if (regid == null) return "";
        // プリファレンスに格納されていない場合は空で返却
        if (regid.equals("")) {
            Log.i(TAG, "レジストレーションIDが見つかりません");
            return "";
        }
        // アプリケーションがバージョンアップされていた場合、レジストレーションIDを必ずクリアしないといけません
        // すでにレジストレーションIDが存在していた場合、再生成は行いません。
        int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
        int currentVersion = getAppVersion(context);
        if (registeredVersion != currentVersion) {
            Log.i(TAG, "アプリケーションバージョンが変更されています");
            return "";
        }
        return registrationId;
    }

    /*
     * アプリケーションバージョン情報を取得する
     */
    private static int getAppVersion(Context context) {
        try {
            PackageInfo packageInfo = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            return packageInfo.versionCode;
        } catch (NameNotFoundException e) {
            throw new RuntimeException("パッケージ名が見つかりません : " + e);
        }
    }

    /*
     * SharedPreferencesを取得
     */
    private SharedPreferences getGCMPreferences(Context context) {
        return getSharedPreferences(MainActivity.class.getSimpleName(),
                Context.MODE_PRIVATE);
    }

    /*
     * レジストレーションIDの保存
     */
    private void storeRegistrationId(Context context, String regId) {
        final SharedPreferences prefs = getGCMPreferences(context);
        int appVersion = getAppVersion(context);
        Log.i(TAG, "レジストレーションIDを登録。登録時のアプリケーションバージョン: " + appVersion);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(PROPERTY_REG_ID, regId);
        editor.putInt(PROPERTY_APP_VERSION, appVersion);
        editor.commit();
    }

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

    @Override
    protected void onDestroy() {
        if (mRegisterTask != null) {
            mRegisterTask.cancel(true);
        }
        gcm.close();
        super.onDestroy();
    }

    @Override
    public void onClick(View v) {
        if(v.getId() == R.id.btn_regist){
            if (regid.equals("")) {
                // GCM登録用AsyncTaskの実行
                mRegisterTask = new AsyncTask<Void, Void, Void>() {
                    @Override
                    protected Void doInBackground(Void... params) {
                        if (gcm == null) {
                            // インスタンスがなければ取得する
                            gcm = GoogleCloudMessaging.getInstance(context);
                        }
                        try {
                            // GCMサーバーへ登録する
                            regid = gcm.register(CommonUtilities.SENDER_ID);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        // レジストレーションIDを自分のサーバーへ送信する
                        // レジストレーションIDをつかえば、アプリケーションにGCMメッセージを送信できるようになります
                        Log.i(TAG,"送信対象のレジストレーションID: " + regid);
                        register(regid);

                        // レジストレーションIDを端末に保存
                        storeRegistrationId(context, regid);
                        return null;
                    }

                    @Override
                    protected void onPostExecute(Void result) {
                        mRegisterTask = null;
                    }
                };
                mRegisterTask.execute(null, null, null);
            }
        }else if(v.getId() == R.id.btn_unregist){
            //GCMサーバーから登録を解除するAsyncTaskの実行
            mRegisterTask = new AsyncTask<Void, Void, Void>() {
                @Override
                protected Void doInBackground(Void... params) {
                    if (gcm == null) {
                        // インスタンスがなければ取得する
                        gcm = GoogleCloudMessaging.getInstance(context);
                    }
                    try {
                        // GCMサーバーの登録を解除する
                        gcm.unregister();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    // レジストレーションIDを自分のサーバーでも削除する
                    unregister(regid);

                    return null;
                }

                @Override
                protected void onPostExecute(Void result) {
                    mRegisterTask = null;
                }

            };
            mRegisterTask.execute(null, null, null);
        }
    }

    /*
     * 
     */
    public static boolean register(String regId) {

        String serverUrl = CommonUtilities.SERVER_URL + "/register";
        Map<String, String> params = new HashMap<String, String>();
        params.put("key", regId);
        try {
            post(serverUrl, params);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static void unregister(String regId) {

        String serverUrl = CommonUtilities.SERVER_URL + "/unregister";
        Map<String, String> params = new HashMap<String, String>();
        params.put("key", regId);
        try {
            post(serverUrl, params);
        } catch (IOException e) {
        }
    }

    public static void post(String endpoint, Map<String, String> params)
            throws IOException {
        URL url;
        try {
            url = new URL(endpoint);
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException("invalid url: " + endpoint);
        }
        StringBuilder bodyBuilder = new StringBuilder();
        Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
        // POSTするパラメータ
        while (iterator.hasNext()) {
            Entry<String, String> param = iterator.next();
            bodyBuilder.append(param.getKey()).append('=')
            .append(param.getValue());
            if (iterator.hasNext()) {
                bodyBuilder.append('&');
            }
        }
        String body = bodyBuilder.toString();
        byte[] bytes = body.getBytes();
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setFixedLengthStreamingMode(bytes.length);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type",
                    "application/x-www-form-urlencoded;charset=UTF-8");
            // ポスト送信
            OutputStream out = conn.getOutputStream();
            out.write(bytes);
            out.close();
            // サーバーレスポンス受信
            int status = conn.getResponseCode();
            if (status != 200) {
                throw new IOException("Post failed with error code " + status);
            }
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }
}

レシーバクラス

package org.techbooster.gcmsample;

import com.google.android.gms.gcm.GoogleCloudMessaging;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
    private static final String TAG = "gcm debug";

    @Override
    public void onReceive(Context context, Intent intent) {
        // 送られてきたデータを受け取る
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
        String messageType = gcm.getMessageType(intent);

        // 送られてきたデータのメッセージ
        Bundle extras = intent.getExtras();
        String mess = extras.toString();

        if (!extras.isEmpty()) {
            // エラー
            if (messageType
                    .equals(GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR)) {
                Log.d(TAG, "MESSAGE_TYPE_SEND_ERROR:" + mess);
            }
            // サーバーでメッセージ削除
            else if (messageType
                    .equals(GoogleCloudMessaging.MESSAGE_TYPE_DELETED)) {
                Log.d(TAG, "MESSAGE_TYPE_DELETED:" + mess);
            }
            // 正常に受信
            else if (messageType
                    .equals(GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE)) {
                Resources res = context.getResources();

                Notification n = new Notification(); // Notificationの生成
                n.icon = R.drawable.ic_launcher; // アイコンの設定

                // 通知されたときに通知バーに表示される文章
                n.tickerText = mess + "(short)"; // メッセージの設定
                n.flags = Notification.FLAG_AUTO_CANCEL; // 通知を選択した時に自動的に通知が消えるための設定

                // 通常の着信音を選択する
                Uri uri = RingtoneManager
                        .getDefaultUri(RingtoneManager.TYPE_ALARM); // アラーム音
                n.sound = uri; // サウンド

                Intent i = new Intent(context, MainActivity.class);
                i.putExtra("MESS", mess);

                PendingIntent pi = PendingIntent.getActivity(context, 0, i,
                        PendingIntent.FLAG_UPDATE_CURRENT);
                // 上から通知バーを下してきたときに表示される文章をセット
                n.setLatestEventInfo(context, res.getString(R.string.app_name),
                        mess + "(long)", pi);

                long[] vibrate_ptn = { 0, 100, 300, 1000 }; // 独自バイブレーションパターン
                n.vibrate = vibrate_ptn; // 独自バイブレーションパターンを設定

                n.defaults |= Notification.DEFAULT_LIGHTS; // デフォルトLED点滅パターンを設定

                // NotificationManagerのインスタンス取得
                NotificationManager nm = (NotificationManager) context
                        .getSystemService(Context.NOTIFICATION_SERVICE);
                nm.notify(1, n); // 設定したNotificationを通知する
            }
        }
    }
}

サービスクラス

package org.techbooster.gcmsample;

import com.google.android.gms.gcm.GoogleCloudMessaging;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

public class GcmIntentService extends IntentService {
    private static final String TAG = "TechBoosterSample";
    public static final int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;

    public GcmIntentService() {
        super("GcmIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        // The getMessageType() intent parameter must be the intent you received
        // in your BroadcastReceiver.
        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty()) {  // has effect of unparcelling Bundle
            /*
             * Filter messages based on message type. Since it is likely that GCM
             * will be extended in the future with new message types, just ignore
             * any message types you're not interested in, or that you don't
             * recognize.
             */
            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.i(TAG, "Working... " + (i+1)
                            + "/5 @ " + SystemClock.elapsedRealtime());
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                    }
                }
                Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
                // Post notification of received message.
                sendNotification("Received: " + extras.toString());
                Log.i(TAG, "Received: " + extras.toString());
            }
        }
        // Release the wake lock provided by the WakefulBroadcastReceiver.
        org.techbooster.gcmsample.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, MainActivity.class), 0);

        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_launcher)
        .setContentTitle("GCM Notification")
        .setStyle(new NotificationCompat.BigTextStyle()
        .bigText(msg))
        .setContentText(msg);

        mBuilder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    }
}   

マニュフェスト

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.techbooster.gcmsample"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <permission
        android:name="org.techbooster.gcmsample.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="org.techbooster.gcmsample.permission.C2D_MESSAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <activity
            android:name="org.techbooster.gcmsample.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver
            android:name="org.techbooster.gcmsample.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="org.techbooster.gcmsample" />
            </intent-filter>
        </receiver>

        <service android:name="org.techbooster.gcmsample.GCMIntentService" />
    </application>

</manifest>