2

我在从通知启动意图时遇到问题(确切地说是 2 个问题)。

我目前的情况是我有一个 apk 系列,它们都可以使用他们中的第一个启动的远程服务。该服务创建一个通知,并在单击时打开启动该服务的应用程序。这工作正常。

我想改进这一点,所以当安装了来自该系列的多个应用程序时,而不是仅仅去启动该服务的 apk 会出现一个选择器 Intent,并且用户将能够选择要返回的 apk。

我设法做到了。

   ArrayList<String> myApps = Lists.newArrayList(
          "com.myapp1",
          "com.myapp2",
          "com.myapp3",
          "com.myapp4"
   );

   List<Intent> targetedIntents = new ArrayList<Intent>();

   Intent baseIntent = new Intent(Intent.ACTION_MAIN, null);
   baseIntent.addCategory("android.intent.category.LAUNCHER");

   final PackageManager packageManager = getApplicationContext().getPackageManager();
   List<ResolveInfo> list = packageManager.queryIntentActivities(baseIntent, 0);

   for (ResolveInfo resolveInfo : list) {
          String packageName  = resolveInfo.activityInfo.packageName;
          if (packageName != null && myApps.contains(packageName)) {

                 Intent targetedIntent = new Intent();
                 targetedIntent.setPackage(packageName);
                 targetedIntent.setClassName(packageName, resolveInfo.activityInfo.name);
                 targetedIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

                 targetedIntents.add(targetedIntent);
          }
   }

   Intent intent = Intent.createChooser(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=whatever")), "Select app to return to");
   intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));

   PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, intent.getFlags());
   notification.setLatestEventInfo(this, notificationTitle, notificationMessage, contentIntent);

这主要是应该的。选择器出现,所选选项启动所需的 apk。

但是我遇到了两个问题:

I. 当我只使用我感兴趣的意图创建意图选择器时,选择器为空并显示消息“没有应用程序可以执行此操作”

     intent = Intent.createChooser(targetedIntents.get(0), "Select app to return to");
     intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));

但是,如果我首先将现有的 apk 放在那里(例如 google play),那么一切正常,并且我的选项与 google play 选项一起显示。

     intent = Intent.createChooser(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=whatever")), "Select app to return to");
     intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));

这是我可以忍受的东西,但如果只有适当的 apk 在那里会更好。

二、当我从列表中单击 apk 时,它不会从后台返回(如果 apk 已经在那里运行)它会重新启动它。我设置了正确的标志。

    Intent targetedIntent = new Intent();
    targetedIntent.setPackage(packageName);
    targetedIntent.setClassName(packageName, resolveInfo.activityInfo.name);
    targetedIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

在使用选择器之前,我只启动了一个意图,它正常恢复了后台 apk。

    intent = new Intent(this, MainActivity.class);
    intent.setAction("android.intent.action.MAIN");
    intent.addCategory("android.intent.category.LAUNCHER");

不知道我在这里做错了什么,apk重新启动而不是恢复。

4

1 回答 1

2

对于第一个问题(选择器问题),您收到错误“没有应用程序可以执行此操作”的原因是因为Intent您传递给的getChooser()没有 ACTION,Android 可以使用它来搜索可以处理的应用程序Intent. _ getChooser将使用 ACTION、CATEGORY 和 DATAIntent寻找合适的应用程序。然后它将使用包和组件名称来过滤此列表。在您的情况下,因为您只提供了包和组件名称(但没有指定 ACTION),Android 找不到任何合适的应用程序。我不确定有没有办法解决这个问题,因为你想用不同的包构建一个列表。您可能只需要创建自己的选择器对话框(无论如何,这可能是正确的做法,因为使用 Android 选择器并没有真正获得任何优势,因为您已经决定了列表应包含的内容)。


对于第二个问题(如果应用程序在后台,它会重新启动),您需要使用以下标志:

targetedIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

指定Intent.FLAG_ACTIVITY_NEW_TASK何时启动任务的根活动会将已经存在的任务带到前台。

注意:如果您只想将现有任务置于前台(无论处于何种状态),则只需使用Intent.FLAG_ACTIVITY_NEW_TASK并删除其他 2 个标志。

于 2013-10-18T13:20:52.760 回答