一旦应用程序启动或从服务器发送推送通知,就会发生以下回溯.
08-31 02:00:14.733: E/AndroidRuntime(30973): java.lang.RuntimeException: Unable to instantiate receiver com.example.smsmining.GcmBroadcastReceiver: java.lang.ClassNotFoundException: Didn't find class "com.example.smsmining.GcmBroadcastReceiver" on path: DexPathList[[zip file "/data/app/com.example.smsmining-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.example.smsmining-1,/vendor/lib,/system/lib]] 08-31 02:00:14.733: E/AndroidRuntime(30973): at android.app.ActivityThread.handleReceiver(ActivityThread.java:2405) 08-31 02:00:14.733: E/AndroidRuntime(30973): at android.app.ActivityThread.access$1500(ActivityThread.java:141) 08-31 02:00:14.733: E/AndroidRuntime(30973): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1332) 08-31 02:00:14.733: E/AndroidRuntime(30973): at android.os.Handler.dispatchMessage(Handler.java:99) 08-31 02:00:14.733: E/AndroidRuntime(30973): at android.os.Looper.loop(Looper.java:137) 08-31 02:00:14.733: E/AndroidRuntime(30973): at android.app.ActivityThread.main(ActivityThread.java:5103) 08-31 02:00:14.733: E/AndroidRuntime(30973): at java.lang.reflect.Method.invokeNative(Native Method) 08-31 02:00:14.733: E/AndroidRuntime(30973): at java.lang.reflect.Method.invoke(Method.java:525) 08-31 02:00:14.733: E/AndroidRuntime(30973): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 08-31 02:00:14.733: E/AndroidRuntime(30973): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 08-31 02:00:14.733: E/AndroidRuntime(30973): at dalvik.system.NativeStart.main(Native Method) 08-31 02:00:14.733: E/AndroidRuntime(30973): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.smsmining.GcmBroadcastReceiver" on path: DexPathList[[zip file "/data/app/com.example.smsmining-1.apk"],/system/lib]] 08-31 02:00:14.733: E/AndroidRuntime(30973): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:53) 08-31 02:00:14.733: E/AndroidRuntime(30973): at java.lang.ClassLoader.loadClass(ClassLoader.java:501) 08-31 02:00:14.733: E/AndroidRuntime(30973): at java.lang.ClassLoader.loadClass(ClassLoader.java:461) 08-31 02:00:14.733: E/AndroidRuntime(30973): at android.app.ActivityThread.handleReceiver(ActivityThread.java:2400) 08-31 02:00:14.733: E/AndroidRuntime(30973): ... 10 more
我的清单文件:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.smsmining" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="16" /> <uses-permission android:name="android.permission.READ_SMS"/> <uses-permission android:name="android.permission.RECEIVE_SMS"/> <uses-permission android:name="android.permission.READ_CONTACTS"/> <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.smsmining.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="com.example.smsmining.permission.C2D_MESSAGE" /> <!-- This app has permission to register and receive data message. --> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".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="com.example.smsmining.SMSBroadcastReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver> <receiver android:name=".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.smsmining" /> </intent-filter> </receiver> <service android:name=".GCMIntentService" /> </application> </manifest>
GcmBroadcastReceiver.java
package com.example.smsmining; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.support.v4.content.WakefulBroadcastReceiver; /** * This {@code WakefulBroadcastReceiver} takes care of creating and managing a * partial wake lock for your app. It passes off the work of processing the GCM * message to an {@code IntentService},while ensuring that the device does not * go back to sleep in the transition. The {@code IntentService} calls * {@code GcmBroadcastReceiver.completeWakefulIntent()} when it is ready to * release the wake lock. */ public class GcmBroadcastReceiver extends WakefulBroadcastReceiver { @Override public void onReceive(Context context,Intent intent) { // Explicitly specify that GcmIntentService will handle the intent. ComponentName comp = new ComponentName(context.getPackageName(),GcmIntentService.class.getName()); // Start the service,keeping the device awake while it is launching. startWakefulService(context,(intent.setComponent(comp))); setResultCode(Activity.RESULT_OK); } }
GcmIntentService.java
public class GcmIntentService extends IntentService { public static final int NOTIFICATION_ID = 1; private NotificationManager mNotificationManager; NotificationCompat.Builder builder; public GcmIntentService() { super("GcmIntentService"); } public static final String TAG = "GCM Demo"; @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(5); } 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. 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,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()); } }