2011-07-16 12 views
2

私はこの議論のために、アクティビティに提示する数字と文字列を保持しているサービスを持っています。サービス指向のコピーバッファーのように考えてください。開始時に、サービスは(startServiceを使用して)開始されます。サービスのIntent.replaceExtras(バンドル)が期待通りに機能しない

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; 

すべて正常です。サービスが開始され、通知(たとえば、「メッセージ1」)にsetMsgによって識別されるメッセージが表示されます。

ユーザーが通知をタッチすると、アクティビティが開始され、そのアクティビティ、とりわけsetNbrとsetMsgが更新され、これらのアクティビティがサービスに返されます。サービスは、新しいメッセージで通知を更新する。 "MESSAGE2"(これもうまくいきます)。

しかし、ここで擦れます:ユーザーがこの通知に触れると、元のsetMsg( "MESSAGE1")は、 "MESSAGE2"ではなくActivityが表示するものです。私はプロセスが間違っている場所を見るためにLog.d()のものを入れましたが、私はそれを見ません。サービスは着信 "MESSAGE2"を正常に記録し、replaceExtras()の後にコードをヒットします。実際には、受信した値は正しいものでなければなりません。そうでなければ、通知は「MESSAGE2」に更新されません。そのため、通知インテントのエキストラバンドルは正しく更新されていないようです。他のすべてのラウンドトリップはうまく動作します。あるいは、アクティビティが最初の試行で正しく動作する可能性は低いですか?

私は通知を更新する私のアプローチに質問します。私はそれが「本によって」と信じていますが、相対的なアンドロイドの初心者はまだ読んでいない本がたくさんあります。あなたの指針に感謝します。

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が呼び出されるActivityからである:ここでサービスコードです

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

これがすべてです私はサービスをデバッグする方法を見つけることができないという事実が複合化されています。デバッグサービス上のあらゆるポインタも非常に高く評価されます!

答えて

6

見つけました!問題はフラグがありませんでした。明らかにupdateExtras()を使用していても、getActivity()メソッドで特別なフラグ(FLAG_UPDATE_CURRENT)を使用しない限り、Androidは注意を払っていません。

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); 
} 
+0

おかげ@Dennis、これがうまく私の問題をソート - 受け入れたとして、あなたはあなた自身の答えをマークすることができますか? – danmux

関連する問題