在Android中,是否可以检查某种服务是否存在? [英] In Android, is there a way to check if a certain service exists?

查看:614
本文介绍了在Android中,是否可以检查某种服务是否存在?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When calling startActivity, one can try to catch an ActivityNotFoundException to know whether the activity exists.

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

When calling startService, however, there is no ServiceNotFoundException. How can I detect if the service exists?

我为什么要这样做

据我了解,对 startService 的调用将被异步处理,因此我想知道是否应该期待响应(例如回调或广播)

As I have learnt, a call to startService will be processed asynchronously, hence I would like to know whether I should expect a response (e.g. a callback, or a broadcast) from the service or not.

到目前为止我做了什么

我搜索了一下,并在此处找到了一个相关问题。似乎在内部提出了 ClassNotFoundException

I searched a bit and find a related question here. It seems that internally there is a ClassNotFoundException raised.

是否有可能在某个地方捕获此异常? Class.forName()方法似乎不正确……还是这样?

Is it possible to catch this exception somewhere? The Class.forName() method doesn't seem right ... or is it?

推荐答案

如果这是您自己的服务,则您知道您的服务是否存在。仅当您尝试使用某些第三方服务时,此问题才起作用。在这种情况下,请使用 PackageManager queryIntentServices()来查看是否有与您的 Intent 。

If it is your own service, you know whether your service exists. This issue only comes into play if you are trying to work with some third-party service. In that case, use PackageManager and queryIntentServices() to see if there is something that matches your Intent.

例如,在此示例应用程序中,我使用 queryIntentServices()至:

For example, in this sample app, I use queryIntentServices() to:


  • 确认我的意向只有一个匹配项

将其从隐式 Intent 转换为显式 Intent

Convert it from an implicit Intent to an explicit Intent

验证服务的签名密钥,这样我就知道不是某些服务伪装成我想要的服务(例如,使用恶意软件重新打包的应用程序)

Validate the signing key of the service, so that I know that it is not some service that is masquerading as the one I want to work with (e.g., repackaged app with malware)

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

Mostly, that is handled in onCreate() of the client fragment that will bind to the service:

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

这篇关于在Android中,是否可以检查某种服务是否存在?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆