2013-02-17 3 views
0

Я создаю приложение чата, которое использует GCM для ввода сообщений и уведомлений.Передача данных из службы в текущую деятельность

В приложении у меня есть активность, в которой перечислены темы беседы (ConversationListActivity) и активность, которая показывает разговор внутри потока (ConversationActivity).

Я собираю новые сообщения в методе onMessage GCMIntentService. Уведомление работает, и сообщение записывается, как ожидалось.

public class GCMIntentService extends GCMBaseIntentService { 
    @Override 
    protected void onMessage(Context context, Intent intent) { 
    Bundle extras = intent.getExtras(); 
    String sender = extras.getString("sender"); 
    String message = extras.getString("message"); 

    ConversationModel model = new ConversationModel(context); 
    model.open(); 
    model.createMessage(sender, message.trim(), true, true, ConversationMessage.STATUS_SENT); 
    model.close(); 

    this.createMessageNotification(context, sender, message); 
    } 
} 

Проблема заключается в том, если GCM толкает новое сообщение, а ConversationActivity активен, я не хочу, чтобы генерировать уведомления. Вместо этого я хочу, чтобы разговор обновлялся напрямую.

Как сообщить активному ConversationActivity обновить список сообщений каждый раз, когда появляется новое сообщение от GCM?

+0

Вы сохраняете диалог сообщений в БД? – Sean

+0

Да, 'ConversationModel' - это класс модели, который управляет sqlite DB. – drowneath

ответ

5

Я нашел решение самостоятельно. Я уверен, что это не лучший способ сделать это, но, по крайней мере, это работает для меня.

Создайте одноэлементный класс, который выводит Handler для хранения активных ConversationActivity. В методе handleMessage обработайте сообщение, которое будет отправлено из службы, которая сообщает обработчику, чтобы сообщить активности, чтобы обновить разговор.

public class ActiveMessageHandler extends Handler { 

    private static ActiveMessageHandler _instance = new ActiveMessageHandler(); 
    private Activity _activity = null; 

    @Override 
    public void handleMessage(Message message) { 
    if(message.obj.toString().equals("gcmNewMessage") && _activity != null) 
     ((ConversationActivity)_activity).repopulateList(); 

    super.handleMessage(message); 
    } 

    public static ActiveMessageHandler instance() { 
    return _instance; 
    } 

    public void setActivity(Activity activity) { 
    _activity = activity; 
    } 

    public Activity getActivity() { 
    return _activity; 
    } 

} 

Затем в ConversationActivity, установите атрибут активности в обработчике.

public class ConversationActivity extends Activity { 
    @Override 
    public void onStart() { 
    super.onStart(); 
    ActiveMessageHandler.instance().setActivity(this); 
    } 

    @Override 
    public void onStop() { 
    super.onStop(); 
    ActiveMessageHandler.instance().setActivity(null); 
    } 
} 

Наконец, в службе, проверьте активность в обработчике не равно нулю и отправить сообщение обработчику, чтобы обновить разговор.

public class GCMIntentService extends GCMBaseIntentService { 
    @Override 
    protected void onMessage(Context context, Intent intent) { 
     Bundle extras = intent.getExtras(); 
     String sender = extras.getString("sender"); 
     String message = extras.getString("message"); 

     ConversationModel model = new ConversationModel(context); 
     model.open(); 
     model.createMessage(sender, message.trim(), true, true, ConversationMessage.STATUS_SENT); 
     model.close(); 

     // if ConversationActivity is active, send a message to handler to refresh the conversation 
     if(ActiveMessageHandler.instance().getActivity() != null) 
     { 
      Message msg = Message.obtain(ActiveMessageHandler.instance()); 
      msg.obj = "gcmNewMessage"; 
      ActiveMessageHandler.instance().sendMessage(msg); 

      // Optionally, play a notification sound 
      Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 
      Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification); 
      r.play(); 
     } 
     else 
      createMessageNotification(context, sender, message); 
    } 
} 
+0

Спасибо @ drowneath.I не знаю, насколько это эффективно, но определенно это помогло мне. Как вы сказали: «Я уверен, что это не лучший способ это сделать». Если вы найдете что-то лучше этого, пожалуйста, обновите свой ответ. – Joyson

+0

Таким образом, вы сохраняете ссылку на активность в статическом поле. Это приводит к утечке памяти в долгосрочной перспективе – JensV

Смежные вопросы