java.lang.RuntimeException: Unable to instantiate service .GCMIntentService

13,366

Solution 1

You should have GCMIntentService in the client code and you should define it in the AndroidManifest.xml file as follows.

<service android:name="package_name.GCMIntentService" />

Note that name of the intent service should be exactly same as GCMIntentService if you use GCMBroadcastReceiver. You can create your intent service if you implement your broadcast receiver.

Solution 2

I had the same problem. And this problem was solved because you're using GCMIntentService class name as android required. But if you want to rename or put this class to another package, problems come back :) Here the the solution link and source code.

Solution :

We should create receiver and set the name of our custom service to overrided method getGCMIntentServiceClassName.

public class GCMReceiver extends GCMBroadcastReceiver { 
@Override
protected String getGCMIntentServiceClassName(Context context) { 
    return "PCAKAGE_NAME.GCMService"; 
}
}

Where PCKAGE_NAME is another package name in case of GCMIntentService is in another package.

And don’t forget change receiver name in AndroidManifest.xml too.

Share:
13,366
Matteo Cardellini
Author by

Matteo Cardellini

Developer of HTML,CSS,PHP,JQuery,MYSQL and Android. Creator of MyList and VipQuiz for Android

Updated on July 12, 2022

Comments

  • Matteo Cardellini
    Matteo Cardellini almost 2 years

    I'm trying to learn how to set a client receiver using the google cloud messaging system and i'm following this Google's tutorial: http://developer.android.com/guide/google/gcm/gs.html#android-app

    I have done everything that the tutorial asks but when I run my application it works for a moment and then it crashes and this is the LogCat:

    08-07 17:04:40.726: E/AndroidRuntime(8155): FATAL EXCEPTION: main
    08-07 17:04:40.726: E/AndroidRuntime(8155): java.lang.RuntimeException: Unable to instantiate service com.example.google.cloud.messaging.GCMIntentService: java.lang.ClassNotFoundException: com.example.google.cloud.messaging.GCMIntentService in loader dalvik.system.PathClassLoader[/data/app/com.example.google.cloud.messaging-1.apk]
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:1933)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at android.app.ActivityThread.access$2500(ActivityThread.java:117)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:989)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at android.os.Handler.dispatchMessage(Handler.java:99)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at android.os.Looper.loop(Looper.java:130)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at android.app.ActivityThread.main(ActivityThread.java:3687)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at java.lang.reflect.Method.invokeNative(Native Method)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at java.lang.reflect.Method.invoke(Method.java:507)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at dalvik.system.NativeStart.main(Native Method)
    08-07 17:04:40.726: E/AndroidRuntime(8155): Caused by: java.lang.ClassNotFoundException: com.example.google.cloud.messaging.GCMIntentService in loader dalvik.system.PathClassLoader[/data/app/com.example.google.cloud.messaging-1.apk]
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:240)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at java.lang.ClassLoader.loadClass(ClassLoader.java:551)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
    08-07 17:04:40.726: E/AndroidRuntime(8155):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:1930)
    

    This is my code

    public class MainActivity extends Activity {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            GCMRegistrar.checkDevice(this);
            GCMRegistrar.checkManifest(this);
            final String regId = GCMRegistrar.getRegistrationId(this);
            if (regId.equals("")) {
              GCMRegistrar.register(this, "962129210868");
              Log.i("Registrando","");
            } else {
              Log.i("Test", "Already registered");
            }
        }
    }
    

    And this is my Manifest

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.google.cloud.messaging"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="16" />
    
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.GET_ACCOUNTS" />
        <uses-permission android:name="android.permission.WAKE_LOCK" />
    
        <permission
            android:name="com.example.google.cloud.messaging.permission.C2D_MESSAGE"
            android:protectionLevel="signature" />
    
        <uses-permission android:name="com.example.google.cloud.messaging.permission.C2D_MESSAGE" />
        <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    
        <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
    
            <activity
                android:name=".MainActivity"
                android:label="@string/title_activity_main" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
            <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.example.google.cloud.messaging" />
                </intent-filter>
            </receiver>
    
            <service android:name="com.example.google.cloud.messaging.GCMIntentService"  android:enabled="true"/>
        </application>
    
    </manifest>
    

    FIXED

    I have create a new class called GCMIntentService:

    public class GCMIntentService extends GCMBaseIntentService {
    
        @SuppressWarnings("hiding")
        private static final String TAG = "GCMIntentService";
    
        public GCMIntentService() {
            super("Test");
        }
    
        @Override
        protected void onRegistered(Context context, String registrationId) {
            Log.i(TAG, "Device registered: regId = " + registrationId);
        }
    
        @Override
        protected void onUnregistered(Context context, String registrationId) {
            Log.i(TAG, "Device unregistered");
        }
    
        @Override
        protected void onMessage(Context arg0, Intent arg1) {
          Log.d("GCM", "RECIEVED A MESSAGE");
          generateNotification(arg0, arg1.getStringExtra("message"));
           }
    
        @Override
        protected void onDeletedMessages(Context context, int total) {
            Log.i(TAG, "Received deleted messages notification");
        }
    
        @Override
        public void onError(Context context, String errorId) {
            Log.i(TAG, "Received error: " + errorId);
        }
    
        @Override
        protected boolean onRecoverableError(Context context, String errorId) {
            // log message
            Log.i(TAG, "Received recoverable error: " + errorId);
            return super.onRecoverableError(context, errorId);
        }
    
        /**
         * Issues a notification to inform the user that server has sent a message.
         */
        private static void generateNotification(Context context, String message) {
            int icon = R.drawable.ic_action_search;
            long when = System.currentTimeMillis();
            NotificationManager notificationManager = (NotificationManager)
                    context.getSystemService(Context.NOTIFICATION_SERVICE);
            Notification notification = new Notification(icon, message, when);
            String title = context.getString(R.string.app_name);
            Intent notificationIntent = new Intent(context, GCMIntentService.class);
            // set intent so it does not start a new activity
            notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
                    Intent.FLAG_ACTIVITY_SINGLE_TOP);
            PendingIntent intent =
                    PendingIntent.getActivity(context, 0, notificationIntent, 0);
            notification.setLatestEventInfo(context, title, message, intent);
            notification.flags |= Notification.FLAG_AUTO_CANCEL;
            notificationManager.notify(0, notification);
        }
    
    }