Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Opening Tag URI with Chrome Custom Tabs "ActivityNotFoundException: No Activity found to handle Intent"

I am currently developing a simple RSS app for Android and one of the app's features is opening url with chrome custom tabs; I have implemented Chrome Custom Tabs based on the samples available on the docs.

While most of the urls were successfully shown by parsing it as Uri, one of the url I passed caused crashes when the custom tab tried to open, which looked something like this format:

tag:github.com,2008:PullRequestReviewCommentEvent/4172209621

I am guessing I should not just parse this String url with Uri.parse() method, but I am kind of stuck, seeking to know what to do here.

I am also guessing this is a similar question with this one: Chrome custom tabs not opening other apps

The crash seems like there is no available activity that can handle this intent:

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)

Below is the source code that I have written so far regarding opening an URL with Chrome Custom Tabs:

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));
  }
}
like image 604
shoheikawano Avatar asked Aug 17 '16 06:08

shoheikawano


2 Answers

This is a general behavior of android. If the URI you are launching cannot be parsed by any individual app, then you need to handle that error gracefully. There is nothing you can do in this condition as it depends on whether or not the user has an app that can actually interpret that URI.

You need to handle that Exception. It is not a library problem. Also as chrome custom tabs, they are probably expecting a webpage link, not that kind of link. In fact, probably the only app that would probably be able to interpret that URI would be the github app.

Standard android behavior is to crash when you try to launch an intent for an activity that no app can handle.

You may be able to leverage PackageManager APIs to detect whether or not someone can handle that intent.

like image 143
JoxTraex Avatar answered Nov 08 '22 15:11

JoxTraex


In my case Google Chrome Application was disabled. After enabling, it starts working.

like image 39
Shanki Bansal Avatar answered Nov 08 '22 15:11

Shanki Bansal