我使用gcm在发布图像时获得通知,然后下载并处理它:

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        DataUtils.log("In GcmBroadcastReceiver! threadname is " + Thread.currentThread().getName());

        // 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);
    }
}

这是我的gcminentservice的开始:
public class GcmIntentService extends IntentService
{
    public static final int NOTIFICATION_ID = 1;

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


    @Override
    protected void onHandleIntent(Intent intent)
    {

        DataUtils.log("In GcmIntentService onHandleIntent(), threadname is " + Thread.currentThread().getName());

        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))
            {
                DataUtils.log("In GcmIntentService - Send error: " + extras.toString());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType))
            {
                DataUtils.log("In GcmIntentService - Deleted messages on server: " + extras.toString());
            // If it's a regular GCM message, do some work.
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType))
            {

                String notificationType = extras.getString(MyAppApi.GCM_MSG_TYPE_KEY);

                if(DataUtils.isEmpty(notificationType)) {

                    DataUtils.log("In GcmIntentService - notificationType is empty!");

                } else if(notificationType.equalsIgnoreCase(MyAppApi.GCM_IS_NEW_WALLPAPER)) {

                    //We're about to receive a new image!
                    DataUtils.log("In GcmIntentService - Receiving a new image!");
                    processNewWallpaper();

                } else if(notificationType.equalsIgnoreCase(MyAppApi.GCM_IS_FRIEND_NOTIFICATION)) {

                    //We're about to receive a friend notification
                    DataUtils.log("In GcmIntentService - Receiving a friend notification!");
                    processFriendNotification();

                } else {
                    //Unknown
                    DataUtils.log("In GcmIntentService - Receiving unknown message type! " + notificationType);
                }

            } else {

                DataUtils.log("In GcmIntentService - Unknown GCM message: " + extras.toString());
            }
        }

        //Release the wake lock provided by the WakefulBroadcastReceiver.
        GcmBroadcastReceiver.completeWakefulIntent(intent);

    }
}

服务似乎会随机死亡。从日志中:
01-13 20:00:44.436: I/ActivityManager(375): Process com.grakk.android (pid 23227) has died.
01-13 20:00:44.444: W/ActivityManager(375): Scheduling restart of crashed service com.grakk.android/.GcmIntentService in 11426ms

当代码收到gcm消息时,它所做的是下载一个图像,然后向用户显示一个通知(这类似于普通的聊天应用程序)。
一位测试人员告诉我,一旦他收到一个图像,但没有收到通知,这意味着服务本身已经启动,并完成了部分工作,但没有完成。
通知代码与图像的下载和处理一起在processNewWallpaper()中运行。代码如下:
...

if(senderContact == null) {
    sendNotification(null, message, true);
} else {
    sendNotification(senderContact.getName(), message.trim(), false);
}

...

通知方法:
...

// 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.
@SuppressWarnings("deprecation")
@TargetApi(16)
private void sendNotification(String name, String message, boolean isAnonymous)
{
    Context context = GcmIntentService.this;
    NotificationManager mNotificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);

    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, ContactsActivity.class), 0);

    Notification.Builder mBuilder = new Notification.Builder(this)
        .setSmallIcon(R.drawable.ic_launcher)
        .setContentTitle(context.getString(R.string.app_name));

    String textToShow = null;
    if(DataUtils.isEmpty(message))
    {
        if(isAnonymous) {
            textToShow = context.getString(R.string.notification_text_anonymous);
        } else {
            textToShow = String.format(getResources().getString(R.string.notification_text_friend), name);
        }
    } else {
        textToShow = message;
    }

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        mBuilder.setStyle(new Notification.BigTextStyle().bigText(textToShow));
    }

    mBuilder.setContentText(textToShow);
    mBuilder.setAutoCancel(true);

    Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    mBuilder.setSound(alarmSound);
    mBuilder.setContentIntent(contentIntent);

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    } else {
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.getNotification());
    }
}

我可以通过给自己发送一张图片,然后反复按android的back按钮,直到我不在应用程序中,来重现这一点。我可以跟踪显示图像已下载的日志消息,但是在显示通知之前图像会消失。
这种情况并不总是发生。有时显示通知,有时不显示。
我不知道可能的原因是什么,也不知道如何调试。有什么小窍门吗?

最佳答案

你打过OnCreate()班的GcmIntentService吗?
下面是一些示例代码:

public class GcmIntentService extends IntentService {

    String mes;
    private Handler mHandler;

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

    @Override
    public void onCreate() {
        super.onCreate();
        mHandler = new Handler();
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();

        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);

        String messageType = gcm.getMessageType(intent);
        mes = extras.getString("title");
        showToast();
        Log.i("GCM", "Recevied: (" + messageType + ") " + extras.getString("title"));

        GcmReceiver.completeWakefulIntent(intent);
    }

    public void showToast() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(), mes, Toast.LENGTH_LONG).show();
            }
        });
    }
}

编辑:为GCMhere添加有用的youtube教程。

10-07 19:59