如何使隐式意图明确?

时间:2016-03-06 13:55:39

标签: android android-intent

我有两个应用程序,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");
    }

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

1 个答案:

答案 0 :(得分:1)

我不认为setPackage()足够&#34;足够&#34;使其完全明确。为此,你need setComponent()

使用PackageManager的第二种方法是正确的,但除非你刚刚截断了代码清单,否则你错过了调整 - Intent步骤。

在来自this sample appthis 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);
  }
}