Intent.replaceExtras (комплект) службы не работает должным образом - PullRequest
2 голосов
/ 16 июля 2011

У меня есть Служба, которая для этого обсуждения содержит число и строку для представления в Деятельности.Думайте об этом как Сервис-ориентированный буфер копирования.После запуска Сервис запускается (используя startService) примерно так:

Intent srvIntent = new Intent(this, SetManager.class);
Bundle bundle = new Bundle();
bundle.putLong(getString(R.string.intent_key_setnbr), setNbr);
bundle.putString(getString(R.string.intent_key_setmsg), setMsg);
srvIntent.putExtras(bundle);
startService(srvIntent);
return true;

Все работает нормально.Служба запускается, отображает сообщение, идентифицированное setMsg, в уведомлении (например, «MESSAGE1»).

Когда пользователь касается уведомления, запускается действие, и эта активность, среди прочего, обновляетsetNbr и setMsg, и отправляет их обратно в Сервис.Сервис, в свою очередь, обновляет Уведомление новым сообщением, например, «MESSAGE2» (которое также отлично работает).

Но вот в чем проблема: Когда пользователь касается этого Уведомления, Original setMsg («MESSAGE1»)что показывает активность, а не «СООБЩЕНИЕ2».Я поместил в Log.d () материал, чтобы увидеть, где идет процесс, но я его не вижу.Служба прекрасно записывает входящее «MESSAGE2» и выполняет код после replaceExtras ().Фактически, входящие значения должны быть правильными, иначе Уведомление не будет обновлено до «СООБЩЕНИЯ 2».Таким образом, кажется, что пакет дополнений в Notification Intent не обновляется должным образом, так как все остальное работает нормально.Или, что менее вероятно, действие будет работать правильно только с первой попытки?

Поэтому я подвергаю сомнению мой подход к обновлению Уведомления.Я считаю, что это «по книге», но, как относительный новичок андроида, есть много книг, которые я еще не читал.Буду признателен за ваши указатели.Вот код службы:

package yada.yada.boom.Setlines;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.text.ClipboardManager;
import android.util.Log;

public class NoteManager extends Service {

    private NotificationManager mNM = null;
    private Notification notification = null;
    private Context context;
    private final CharSequence contentTitle = "Setlines";
    private CharSequence contentText;
    private Intent notificationIntent;
    private PendingIntent pendingIntent;
    private int notificationId = 0;
    private final String MY_TAG = "SetlinesSvc";

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        long setNbr = 0L;
        String setMsg = null;

        super.onStartCommand(intent, flags, startId);
        context = getApplicationContext();
        if (intent != null) {
            Bundle extras = intent.getExtras();
            if (extras != null) {
                setNbr = extras.getLong(getString(R.string.intent_key_setnbr));
                setMsg = extras
                        .getString(getString(R.string.intent_key_setmsg));
            }
        }
        if ((setNbr == 0L) || (setMsg == null)) {
            Log.d(MY_TAG, "Setting default message.");
            setNbr = 0L;
            setMsg = "Click to view setMsg.";
        } else {
            Log.d(MY_TAG, "Got set number (" + setNbr + ") and string ("
                    + setMsg.substring(0, 10) + "...) from intent.");
        }
        if (notification == null) {
            createNotification(setNbr, setMsg);
        } else {
            updateNotificationText(setNbr, setMsg);
        }
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        // Log.d(MY_TAG, "onDestroy() called");
        mNM.cancel(notificationId);
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    // Create a status bar notification
    void createNotification(long setNbr, String setMsg) {
        CharSequence tickerText = null;
        int icon = 0;

        // Log.d(MY_TAG, "createNotification called");
        mNM = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        icon = R.drawable.ic_notification;
        tickerText = "Setlines";

        // Instantiate the Notification

        long when = System.currentTimeMillis();

        notification = new Notification(icon, tickerText, when);

        context = getApplicationContext();
        contentText = setMsg;
        notificationIntent = new Intent(this, SetServiceMenu.class);
        Bundle bundle = new Bundle();
        bundle.putLong(getString(R.string.intent_key_setnbr), setNbr);
        if (setNbr != 0L) {
            bundle.putString(getString(R.string.intent_key_setmsg), setMsg);
            Log.d(MY_TAG, "Added extras: SetNbr(" + setNbr + ") SetMsg("
                    + setMsg.substring(0, 10) + "...)");
            notificationIntent.putExtras(bundle);
        }
        pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent,
                PendingIntent.FLAG_ONE_SHOT);
        notification.setLatestEventInfo(context, contentTitle, contentText,
                pendingIntent);
        notificationId += 1; // Bump the notification ID number
        // Pass the Notification to the NotificationManager:
        Log.d(MY_TAG, "createNotification() ... passing notification");
        mNM.notify(notificationId, notification);
        startForeground(notificationId, notification);
    }

    void updateNotificationText(long setNbr, String setMsg) {
        contentText = setMsg;
        notificationIntent = new Intent(this, SetServiceMenu.class);
        Bundle bundle = new Bundle();
        bundle.putLong(getString(R.string.intent_key_setnbr), setNbr);
        bundle.putString(getString(R.string.intent_key_setmsg), setMsg);
        // notificationIntent.putExtras(bundle);
        notificationIntent.replaceExtras(bundle);
            Log.d(MY_TAG, "Replaced extras: SetNbr(" + setNbr + ") SetMsg("
                    + setMsg.substring(0, 10) + "...)");
        pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent,
                PendingIntent.FLAG_ONE_SHOT);
        notification.setLatestEventInfo(context, contentTitle, contentText,
                pendingIntent);

        mNM.notify(notificationId, notification);
    }

}

... и вот onCreate из вызываемой операции:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = this.getApplicationContext();
    Bundle extras = getIntent().getExtras();
    String setMsg = "";

    dbAdapter = new SetDbAdapter(context);

    dbAdapter.openReadable();
    if (savedInstanceState != null) {
        setNbr = savedInstanceState.getLong("setNbr");
        // Log.d(MY_TAG, "Retrieved set# (" + setNbr + ") from intent.");
        setMsg = savedInstanceState.getString("setMsg");
        // Log.d(MY_TAG, "Retrieved text (" + setMsg.substring(0, 10)
        // + "...) from intent.");
        setMsg = dbAdapter.getSetById(setNbr);
    } else if (extras != null) {
        setNbr = extras.getLong(getString(R.string.intent_key_setnbr));
        // Log.d(MY_TAG, "Retrieved set# (" + setNbr + ") from extras.");
        setMsg = extras.getString(getString(R.string.intent_key_setline));

        if ((setMsg == null) && (setNbr != 0)) {
            setMsg = dbAdapter.getSetById(setNbr);
        }
    }
    if ((setNbr == 0) || (setMsg == null)) {
        setNbr = nextMessageNbr();
        setMsg = messageText(setNbr);
    }
    dbAdapter.close();
    svcTagNbr = setNbr;
    svcTagline = setMsg;
    d = new myDialog(this);
    d.show();
    notifyService(false);
}

Наконец, вот notifyService ()

private void notifyService(boolean getNew) {

  // Here we get a new setMsg, and notify the server to create
  // notification with it.
  long mySetNbr = svcSetNbr;
  String mySetMsg = svcSetMsg;

  if (getNew) {
    mySetNbr = nextMessageNbr();
    mySetline = messageText(mySetNbr);
  }

  Intent srvIntent = new Intent(context, SetManager.class);
  Bundle bundle = new Bundle();
  bundle.putLong(getString(R.string.intent_key_setnbr), mySetNbr);
  bundle.putString(getString(R.string.intent_key_setmsg), mySetMsg);
  srvIntent.putExtras(bundle);
  startService(srvIntent);
}

Все это усугубляется тем фактом, что я не могу найти способ отладки Сервиса.Любые указатели на Услуги отладки также будут высоко оценены!

1 Ответ

6 голосов
/ 23 июля 2011

Нашли это! Проблема была в пропущенном флаге. Очевидно, что хотя мы используем updateExtras (), Android не обращает внимания, если вы не используете специальный флаг (FLAG_UPDATE_CURRENT) для метода getActivity ().

Из документов на http://developer.android.com/reference/android/app/PendingIntent.html:

... если описанный PendingIntent уже существует, сохраните его, но замените его дополнительные данные тем, что находится в этом новом Намерении. Это может быть использовано, если вы создаете намерения, в которых изменяются только дополнения, и вам не важно, что какие-либо сущности, получившие ваше предыдущее PendingIntent, смогут запустить его с вашими новыми дополнениями, даже если они явно не переданы ему.

Итак, новый код выглядит так:

void updateNotificationText(long setNbr, String setMsg) {
    contentText = setMsg;
    Bundle bundle = new Bundle();
    bundle.putLong(getString(R.string.intent_key_setnbr), setNbr);
    bundle.putString(getString(R.string.intent_key_setmsg), setMsg);
    notificationIntent.replaceExtras(bundle);
    pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent,
          PendingIntent.FLAG_ONE_SHOT
        + PendingIntent.FLAG_UPDATE_CURRENT);
    notification.setLatestEventInfo(context, contentTitle, contentText,
            pendingIntent);
    mNM.notify(notificationId, notification);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...