我有两个应用程序,A和B,它们使用一个安卓库.B有一个服务A想通过C使用,例如
<service android:name="my.package.in.a.service.ConnectorService"
android:exported="true">
<intent-filter>
<action android:name="my.package.in.a.action.START_A"/>
</intent-filter>
</service>
在我的库中有一个类,它试图将它绑定到服务,例如
Intent intent = new Intent("my.package.in.a.service.ConnectorService");
/** establish a connection with the service. */
boolean result = context.bindService(intent, messenger,
Context.BIND_AUTO_CREATE);
显然,由于安全问题(隐式与显式意图),您不能再这样做了。我尝试使用A中定义的操作初始化意图。我还尝试添加包名称,并尝试设置类名称,例如
Intent intent = new Intent()
intent.setPackage("my.package.in.a.service");
intent.setClassName("my.package.in.a.service",
"my.package.in.a.service.ConnectorService");
我尝试使用包管理器找到服务,例如
Intent intent = new Intent("my.package.in.a.service.ConnectorService");
List<ResolveInfo> resolveInfoList = context.getPackageManager()
.queryIntentServices(intent, Context.BIND_AUTO_CREATE);
if (resolveInfoList.isEmpty()) {
Log.e(TAG, "could not find any service");
}
if (resolveInfoList.size() > 1) {
Log.e(TAG, "multiple services found");
}
我有点疑惑我做错了什么?据我所知,你可以通过简单地指定包/类名,将隐式意图显式化,即使它不是同一个包/应用程序的一部分。然而,这一切似乎都失败了,显然我做错了什么?
答案 0 :(得分:1)
我不认为setPackage()
足够&#34;足够&#34;使其完全明确。为此,你need setComponent()
。
使用PackageManager
的第二种方法是正确的,但除非你刚刚截断了代码清单,否则你错过了调整 - Intent
步骤。
在来自this sample app的this book中,我不仅要检查服务的单个实现,还要检查其签名(以确保我要绑定的应用程序未被黑客入侵)并进行调整Intent
:
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);
}
}