android - 使用 Chrome 自定义标签打开标签 URI "ActivityNotFoundException: No Activity found to handle Intent"

标签 android chrome-custom-tabs

我目前正在为 Android 开发一个简单的 RSS 应用程序,该应用程序的功能之一是使用 chrome 自定义标签打开 url;我已经根据文档中提供的示例实现了 Chrome 自定义标签。

虽然大多数 url 都通过将其解析为 Uri 成功显示,但我传递的其中一个 url 在尝试打开自定义选项卡时导致崩溃,看起来像这样的格式:

tag:github.com,2008:PullRequestReviewCommentEvent/4172209621

我猜我不应该只用 Uri.parse() 方法解析这个字符串 url,但我有点卡住了,想知道在这里做什么。

我也猜这是一个与此类似的问题: Chrome custom tabs not opening other apps

崩溃似乎没有可以处理此 Intent 的可用 Activity :

FATAL EXCEPTION: main
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=tag:github.com,2008:PullRequestReviewCommentEvent/4172209621 (has extras) }
    at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1798)
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1512)
    at android.app.Activity.startActivityForResult(Activity.java:3930)
    at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:48)
    at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:75)
    at android.app.Activity.startActivityForResult(Activity.java:3890)
    at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:871)
    at android.app.Activity.startActivity(Activity.java:4213)
    at android.support.v4.app.ActivityCompatJB.startActivity(ActivityCompatJB.java:27)
    at android.support.v4.app.ActivityCompat.startActivity(ActivityCompat.java:134)
    at android.support.customtabs.CustomTabsIntent.launchUrl(CustomTabsIntent.java:244)
    at butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.java:22)
    at android.view.View.performClick(View.java:5204)
    at android.view.View$PerformClick.run(View.java:21155)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5422)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

以下是我迄今为止编写的关于使用 Chrome 自定义标签打开 URL 的源代码:

public class ArticleFragment extends Fragment {

  @OnClick(R.id.button_see_more) public void onClickSeeMore() {
    launchCustomTabs(article.url());
  }

  private CustomTabsServiceConnection customTabsConnection;
  private CustomTabsClient customTabsClient;
  private CustomTabsSession customTabsSession;

  @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    ...

    bindCustomTabsService();
  }

  @Override public void onDestroy() {
    unbindCustomTabsService();
    super.onDestroy();
  }

  private void bindCustomTabsService() {
    if (customTabsClient != null) {
      return;
    }

    customTabsConnection = new CustomTabsServiceConnection() {
      @Override public void onCustomTabsServiceConnected(ComponentName componentName,
          CustomTabsClient customTabsClient) {
        ArticleSummaryDetailFragment.this.customTabsClient = customTabsClient;
        customTabsSession = customTabsClient.newSession(new CustomTabsCallback() {
          @Override public void onNavigationEvent(int navigationEvent, Bundle extras) {
            Timber.wtf("onNavigationEvent: Code = " + navigationEvent);
          }
        });

        customTabsSession.mayLaunchUrl(Uri.parse(article.originId()), null, null);
        customTabsClient.warmup(0L);
      }

      @Override public void onServiceDisconnected(ComponentName componentName) {
        customTabsClient = null;
      }
    };

    CustomTabsClient.bindCustomTabsService(getActivity(), getActivity().getPackageName(),
        customTabsConnection);
  }

  private void unbindCustomTabsService() {
    if (customTabsConnection == null) {
      return;
    }

    getActivity().unbindService(customTabsConnection);
    customTabsClient = null;
    customTabsSession = null;
  }

  private void launchCustomTabs(String url) {
    CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder(customTabsSession).build();
    customTabsIntent.launchUrl(getActivity(), Uri.parse(url));
  }
}

最佳答案

这是android的一般行为。如果您启动的 URI 无法被任何单独的应用程序解析,那么您需要优雅地处理该错误。在这种情况下您无能为力,因为这取决于用户是否拥有可以实际解释该 URI 的应用。

您需要处理该异常。这不是图书馆的问题。同样作为 chrome 自定义选项卡,他们可能期待网页链接,而不是那种链接。事实上,可能唯一能够解释该 URI 的应用程序就是 github 应用程序。

标准的 Android 行为是当您尝试为任何应用无法处理的 Activity 启动 Intent 时崩溃。

您可以利用 PackageManager API 来检测某人是否可以处理该 Intent 。

关于android - 使用 Chrome 自定义标签打开标签 URI "ActivityNotFoundException: No Activity found to handle Intent",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38989741/

相关文章:

java - android中的layoutinflater nullpointerexception

android - 即使设备关闭,如何保存共享首选项值?

android - 使用phonegap file api遍历SD卡中的每个文件

android - 更改 Chrome 自定义标签中的状态栏颜色

javascript - Phonegap 应用程序文本出现后立即消失。我该如何调试?

android - 无法在覆盖类中使用 putExtra 方法

android - 如何在未登录时将任何 URL 启动到 Chrome 自定义选项卡

postmessage - 在 Chrome 自定义标签 CustomTabsSession 中使用 postMessage

java - 从 RecyclerView 适配器启动 Chrome 自定义选项卡