3

画像が投稿されたときに通知を受け取るために 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);
    }
}

これは私の GcmIntentService の始まりです:

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 の [戻る] ボタンをアプリから離れるまで繰り返し押すことで、これを再現できます。イメージがダウンロードされたことを示すログ メッセージをたどることはできますが、通知が表示される前に終了します。

これは常に起こるわけではありません。通知が表示される場合と表示されない場合があります。

考えられる原因は何か、これをデバッグする方法もわかりません。任意のヒント?

4

3 に答える 3

0

回答を使用して申し訳ありません(まだコメントできません)。

sendNotification の呼び出しを processNewWallpaper から processNewWallpaper() の直後に抽出してみます。それでもうまくいかない場合は、コードを processNewWallpaper() に投稿する必要があります。私の推測では、場合によってはコードが processNewWallpaper 内でクラッシュし、sendNotification をスキップしますが、処理されているため何もスローされません。

また、アプリがバックグラウンドで開いている場合と完全に閉じている場合では、アプリの動作が異なることに気付きました (実行中のアプリ キーを使用し、そこでアプリを閉じます)。問題を一貫して再現できれば、解決が容易になります。

于 2015-01-23T01:23:35.667 に答える