Android 如何使隐含的意图明确化?

Android 如何使隐含的意图明确化?,android,android-intent,Android,Android Intent,我有两个应用程序,A和B,它们使用android库C。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"/>

我有两个应用程序,A和B,它们使用android库C。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>
显然,由于安全问题(隐式和显式意图),您不能再这样做了。我尝试使用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");
    }
Intent Intent=newintent(“my.package.in.a.service.ConnectorService”);
List resolveInfoList=context.getPackageManager()
.querytentservices(intent、Context.BIND\u AUTO\u CREATE);
if(resolveInfoList.isEmpty()){
Log.e(标记“找不到任何服务”);
}
如果(resolveInfoList.size()>1){
Log.e(标签“找到多个服务”);
}

我有点困惑我做错了什么?据我所知,即使隐式意图不是同一个包/应用程序的一部分,也可以通过简单地指定包/类名使其显式化。然而,所有这一切似乎都失败了,显然我做错了什么?

我认为
setPackage()
做得不够“充分”以使其完全明确。为了这个,你

第二种方法是使用
PackageManager
,这是正确的,但除非您刚刚截断了代码列表,否则您将错过调整-
意图的步骤

在from中,我不仅检查服务的单个实现,还检查其签名(以确保我要绑定到的应用程序未被黑客入侵),并调整
意图

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);
  }
}
Intent implicit=newintent(IDownload.class.getName());
列表匹配项=getActivity().getPackageManager()
.QueryInputServices(隐式,0);
如果(匹配.size()==0){
Toast.makeText(getActivity(),“找不到匹配的服务!”,
Toast.LENGTH_LONG).show();
}
else if(匹配.size()>1){
Toast.makeText(getActivity(),“找到多个匹配的服务!”,
Toast.LENGTH_LONG).show();
}
否则{
ServiceInfo svcInfo=matches.get(0).ServiceInfo;
试一试{
字符串otherHash=SignatureUtils.getSignatureHash(getActivity(),
svcInfo.applicationInfo.packageName);
String expected=getActivity().getString(R.String.expected\u sig\u hash);
if(应为.equals(其他哈希)){
意向明确=新意向(隐含);
ComponentName cn=新组件名(svcInfo.applicationInfo.packageName,
svcInfo.name);
explicit.setComponent(cn);
bindService(显式、this、Context.BIND\u自动创建);
}
否则{
Toast.makeText(getActivity(),“发现意外签名!”,
Toast.LENGTH_LONG).show();
}
}
捕获(例外e){
Log.e(getClass().getSimpleName(),“尝试获取签名哈希的异常”,e);
}
}

我在问题的最后一段代码中添加了初始化。然而,它仍然失败。我真的必须像你一样定义aidl吗?@user1729210:“我真的必须像你一样定义aidl吗?”——如果你想在应用程序之间绑定,那绝对是这样。还要注意,修改后的代码段仍然没有调用
setComponent()
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);
  }
}