在Android中,有没有办法检查某个服务是否存在?

时间:2016-06-19 13:27:42

标签: java android exception service

调用startActivity时,可以尝试抓住ActivityNotFoundException来了解该活动是否存在。

但是,在调用startService时,没有ServiceNotFoundException。如何检测服务是否存在?

我为什么要这样做

据我所知,对startService的调用将以异步方式处理,因此我想知道是否应该从服务中获得响应(例如回调或广播)。

到目前为止我做了什么

我搜索了一下,找到了一个相关的问题here。似乎内部有一个ClassNotFoundException被提升。

是否可以在某处捕获此异常? Class.forName()方法似乎不对......或者是它?

1 个答案:

答案 0 :(得分:3)

如果是您自己的服务,您就知道您的服务是否存在。如果您尝试使用某些第三方服务,此问题才会发挥作用。在这种情况下,请使用PackageManagerqueryIntentServices()查看是否有符合您Intent的内容。

例如,在此示例应用中,我使用queryIntentServices()来:

  • 确认我的Intent

  • 只有一个匹配项
  • 将其从隐式Intent转换为显式Intent

  • 验证服务的签名密钥,以便我知道某些服务伪装成我想要使用的服务(例如,带有恶意软件的重新打包的应用程序)

大多数情况下,这是在将绑定到服务的客户端片段的onCreate()中处理的:

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setRetainInstance(true);

    appContext=(Application)getActivity().getApplicationContext();

    Intent implicit=new Intent(IDownload.class.getName());
    List<ResolveInfo> matches=getActivity().getPackageManager()
      .queryIntentServices(implicit, 0);

    if (matches.size() == 0) {
      Toast.makeText(getActivity(), "Cannot find a matching service!",
        Toast.LENGTH_LONG).show();
    }
    else if (matches.size() > 1) {
      Toast.makeText(getActivity(), "Found multiple matching services!",
        Toast.LENGTH_LONG).show();
    }
    else {
      ServiceInfo svcInfo=matches.get(0).serviceInfo;

      try {
        String otherHash=SignatureUtils.getSignatureHash(getActivity(),
          svcInfo.applicationInfo.packageName);
        String expected=getActivity().getString(R.string.expected_sig_hash);

        if (expected.equals(otherHash)) {
          Intent explicit=new Intent(implicit);
          ComponentName cn=new ComponentName(svcInfo.applicationInfo.packageName,
            svcInfo.name);

          explicit.setComponent(cn);
          appContext.bindService(explicit, this, Context.BIND_AUTO_CREATE);
        }
        else {
          Toast.makeText(getActivity(), "Unexpected signature found!",
            Toast.LENGTH_LONG).show();
        }
      }
      catch (Exception e) {
        Log.e(getClass().getSimpleName(), "Exception trying to get signature hash", e);
      }
    }
  }