Skip to content Skip to sidebar Skip to footer

In Android, Is There A Way To Check If A Certain Service Exists?

When calling startActivity, one can try to catch an ActivityNotFoundException to know whether the activity exists. When calling startService, however, there is no ServiceNotFoundEx

Solution 1:

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.

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

  • Confirm that there is only one match for my 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)

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

  @Override
  publicvoidonCreate(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();
    }
    elseif (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);
      }
    }
  }

Post a Comment for "In Android, Is There A Way To Check If A Certain Service Exists?"