3

我有一个应用程序,它使用一个IntentService来处理传入的谷歌云消息传递消息。目前,每当我通过该onHandleIntent()功能收到消息时,我都会创建一个通知。该通知会打开一个特定的活动,然后进行一些计算并更新 UI。我正在尝试实现我的实现,如果我已经在通知将打开的 Activity 上,那么服务应该能够更新 UI 而无需发送通知。我假设我可以使用广播接收器来执行此操作,但我不确定如何实现它,以便仅当 Activity 正在运行时它才应该更新 Activity,否则它应该发布通知。

我不确定如何执行以下操作:

  1. 检查特定的 Activity 是否已经在运行。

  2. 如果 Activity 已经在运行,则无需调用即可执行所需的计算和 UI 更新startActivity()

编辑:我对我的代码进行了一些更改,但我没有看到我在 onReceive() 方法中添加的 logcat 消息。

我在 IntentService 类的 onHandle() 函数中添加了以下代码:

Intent in = new Intent("com.example.gcm.DataActivity");
sendBroadcast(in);

“com.example.gcm”是我的包名,DataActivity 是 Activity 的名称。

我已将以下代码添加到我的活动中:

@Override
protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    Log.d(TAG, "start");
      receiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            Log.d(TAG, "notif received");
        }

    };

}

@Override
protected void onStop() {
    // TODO Auto-generated method stub
    super.onStop();
    unregisterReceiver(receiver);
}
4

3 回答 3

1

正如所承诺的简单方法:您基本上同步发送广播,如果有接收器,您将在您的服务类中设置一个静态标志,让服务知道它已经处理:

public class TestService extends IntentService {
    public volatile static boolean isHandled = false;
    public static final String INTENT_ACTION_HANDLEGCM = "com.intentexample.gcm";

    ...

    @Override
    protected void onHandleIntent(Intent intent) {
        ...
        Intent toActivityIntent = new Intent();
        toActivityIntent.setAction(INTENT_ACTION_HANDLEGCM);
        // toActivity: put other stuff into extras, which you need to update your UI
        TestService.isHandled = false;
        LocalBroadcastManager.getInstance(this).sendBroadcastSync(toActivityIntent);
        if (!TestService.isHandled) {
            // post your notification to the notification bar
        }
    }
}

并在您的活动 onResume 和 onPause 中使用 INTENT_ACTION_HANDLEGCM 的意图过滤器注册和取消注册广播接收器(请记住使用 LocalBroadcastManager)

public class MyActivity extends Activity {
    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            TestService.isHandled = true;
            // update the UI
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onResume() {
        super.onResume();
        LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter(TestService.INTENT_ACTION_HANDLEGCM));
    }

    @Override
    protected void onPause() {
        super.onPause();
        LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
    }
}

注意:此代码未经测试,但应该为您提供总体思路。我个人不会这样做,除非:

  • 在时间压力下
  • 该功能是次要功能,不会很快扩展。
于 2013-09-08T06:17:43.487 回答
0

我已经通过使用 SharedPreferences 值在应用程序中管理该活动是否可见:

    @Override
protected void onStart() {
    super.onStart();

    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
    SharedPreferences.Editor editor = preferences.edit();
    editor.putBoolean("RVisibleNow",true);
    editor.commit();
}

    @Override
protected void onStop() {

    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
    SharedPreferences.Editor editor = preferences.edit();
    editor.putBoolean("RVisibleNow",false);
    editor.commit();

    super.onStop();
}

然后,是的,使用广播接收器,例如:

private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String theRow = intent.getStringExtra(GCMIntentService.MESSAGE);
        String theQuery="SELECT * FROM listdata WHERE _id ='" + theRow + "'"; 
        String action = intent.getAction();
        if(action.equals("com.you.yourapp.UpdateList")){
...

哦,在您的 GCM 服务中:

public static final String BROADCAST = "com.you.yourapp.UpdateList";
public static final String MESSAGE = "com.you.yourapp.GCMIntentService.MESSAGE";

... 

    if(RVisibleNow){
                sendBroadcast(context, message, insertOrUpdate);
            }else{
                generateNotification(context, message, insertOrUpdate);
            }

就我而言,由于省略了很多代码,我的 sendBroadcast 看起来像:

private void sendBroadcast(Context context,  String message, String whichFunction){
    String putExtraParam = "something";
    Intent in = new Intent(BROADCAST);
    in.putExtra(MESSAGE, putExtraParam);
    context.sendBroadcast(in);
}

希望这可以帮助!

于 2013-09-08T05:00:52.407 回答
0

我不建议将 IntentService 与 BroadcastReceiver 结合使用。使用这种方法,您的服务可以通知您的活动,但您的服务将无法确定是否已收到广播(这就是广播的想法,发送者只是广播,并不关心是否有接收器与否)。

一个更好的方法,虽然更复杂的是: - 使用可以启动和绑定的服务(覆盖 onStartCommand 和 onBind) - 如果绑定,则在服务和活动之间建立双向通信。- 在处理您的 GCM 消息时,检查是否建立了通信,如果是:您的活动存在,更新它(使用通信),如果没有:继续并发布您的通知。这是我推荐的方式,但是我理解这看起来很复杂(并且是相当多的代码),因此我会给你第二个更简单的代码,尽管代码不是很干净。

于 2013-09-08T05:49:47.977 回答