在Android中,是否可以检查某种服务是否存在? [英] In Android, is there a way to check if a certain service exists?
问题描述
调用 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屋!