0

这更让人怀疑。目前,我的代码运行良好,但我想确保我以正确的方式进行操作。

我有一项服务,它检查活动是否在前台运行。如果是,它会向 Activity 发送广播,因此 Activity 会更新屏幕上的一些内容。

我在IntentFilter服务上创建了一个:

com.harkdev.ServerStatus.SERVER_UPDATED

这里服务需要知道活动是否在前台,所以它使用IsActivityRunning()方法,从ApplicationManager. 这意味着我需要设置GET_TASKS权限。

既然 SERVICE 和 ACTIVITY 都在同一个包中,有没有更好的方法来获取这些信息?也许尝试避免设置GET_TASKS权限?

这是我服务中的代码:

if (IsActivityRunning()) {
    Intent localIntent = new Intent(SERVER_UPDATED);
    SendBroadcast(localIntent, null);
}

IsActivityRunning()方法:

public bool IsActivityRunning() {
    ActivityManager manager = (ActivityManager) GetSystemService(ActivityService);
    IList<ActivityManager.RunningTaskInfo> runningTaskInfo = manager.GetRunningTasks(1); 

    ComponentName componentInfo = runningTaskInfo[0].TopActivity;
    if (componentInfo.PackageName == "com.harkdev.ServerStatus") 
        return true;

    return false;
}

这是我活动中的代码:

protected override void OnCreate (Bundle bundle) {
    base.OnCreate(bundle);
    // Set our view from the "main" layout resource
    SetContentView (Resource.Layout.Main);

    IntentFilter filter = new IntentFilter(ServerStatusCheckService.SERVER_UPDATED);
    _receiver = new ServiceBroadcastReceiver ();
    _receiver.Received += Receiver_Received;

    RegisterReceiver(_receiver, filter);
}
4

1 回答 1

3

首先,您在比较字符串时采用了错误的方法:

if (componentInfo.PackageName == "com.harkdev.ServerStatus")

它应该是:

if ("com.harkdev.ServerStatus".equals(componentInfo.PackageName))

其次,如果服务和活动在您的应用程序中,那么我认为检查“相同包”的要求是没有必要的。

要将信息从服务发送到活动,您可以使用ResultReceiver(在 API 3+ 中可用):

  • 从活动启动服务时,您创建一个ResultReceiver,将其放入启动服务的意图中。
  • 在服务中,提取ResultReceiver并保留它。当您要发送信息时,请使用send().
  • 例如,在活动中,onDestroy()您可以触发一个命令来通知服务ResultReceiver无效并且应该将其删除。

艾迪

例如:

  • 在您的活动中:

    // Global variable.
    private ResultReceiver mResultReceiver = new ResultReceiver() {
    
        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            // Update the UI here...
        }
    }
    

    启动服务时:

    Intent i = new Intent(this, TheService.class);
    // You can use different action names for different commands.
    i.setAction("REGISTER_RECEIVER");
    i.putExtra("ResultReceiver", mResultReceiver);
    i.putExtra("ResultReceiver_ID", hashCode());
    startService(i);
    

    并在onDestroy()

    Intent i = new Intent(this, TheService.class);
    i.setAction("UNREGISTER_RECEIVER");
    i.putExtra("ResultReceiver_ID", hashCode());
    startService(i);
    
  • 在您的服务中:

    import  android.util.SparseArray;
    
    // ...
    
    private SparseArray<ResultReceiver> mReceiverMap = new SparseArray<ResultReceiver>();
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if ("REGISTER_RECEIVER".equals(intent.getAction())) {
            // Extract the ResultReceiver and store it into the map
            ResultReceiver receiver = intent.getParcelableExtra("ResultReceiver");
            int id = intent.getIntExtra("ResultReceiver_ID", 0);
            mReceiverMap.put(id, receiver);
        } else if ("UNREGISTER_RECEIVER".equals(intent.getAction())) {
            // Extract the ResultReceiver ID and remove it from the map
            int id = intent.getIntExtra("ResultReceiver_ID", 0);
            mReceiverMap.remove(id);
        }
    
        // ...
    }
    
于 2013-03-13T02:59:07.430 回答