2

I have an app in production and some users get a weird ActivityNotFoundException about a VIEW https intent. I cannot reproduce it locally on my physical device or emulator. I also assume that every Android has a browser to open URLs by default, am I wrong? (None of the devices that encounter the bug is rooted). Could the problem be because the phone doesn't have chrome?

I use CustomTabsIntent to open the URLs:

public static void openUrl(final Uri url, final Activity activity) {
        CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
        builder.setToolbarColor(ContextCompat.getColor(activity, R.color.denis_red));
        builder.setCloseButtonIcon(
                BitmapFactory.decodeResource(activity.getResources(),
                        R.drawable.ic_arrow_back_white_24dp));
        builder.setStartAnimations(activity, R.anim.activity_slide_in_right,
                R.anim.activity_slide_out_left);
        builder.setExitAnimations(activity, R.anim.activity_slide_in_left,
                R.anim.activity_slide_out_right);
        builder.build().launchUrl(activity, url);
    }

I add some of the stack traces if it can help. Thanks!

1:

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=https://redirect.denis.de/... (has extras) }
    at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2031)
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1686)
    at android.app.Activity.startActivityForResult(Activity.java:4506)
    at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
    at android.app.Activity.startActivity(Activity.java:4825)
    at android.support.v4.content.ContextCompat.startActivity(ContextCompat.java:248)
    at android.support.customtabs.CustomTabsIntent.launchUrl(CustomTabsIntent.java:263)
    at de.boxine.denisapp.util.web.ChromeTabUtil.openUrl(ChromeTabUtil.java:26)
    at de.boxine.denisapp.denis.list.DenisListActivity.onOptionsItemSelected(DenisListActivity.java:82)
    at android.app.Activity.onMenuItemSelected(Activity.java:3469)
    at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:436)
    at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:196)
    at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)
    at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)
    at android.support.v7.app.ToolbarActionBar$2.onMenuItemClick(ToolbarActionBar.java:64)
    at android.support.v7.widget.Toolbar$1.onMenuItemClick(Toolbar.java:204)
    at android.support.v7.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:781)
    at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:840)
    at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
    at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:991)
    at android.support.v7.view.menu.MenuPopup.onItemClick(MenuPopup.java:128)
    at android.widget.AdapterView.performItemClick(AdapterView.java:318)
    at android.widget.AbsListView.performItemClick(AbsListView.java:1158)
    at android.widget.AbsListView$PerformClick.run(AbsListView.java:3153)
    at android.widget.AbsListView$3.run(AbsListView.java:4068)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6626)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)

2:

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=https://redirect.denis.de/... (has extras) }
    at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1981)
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1636)
    at android.app.Activity.startActivityForResult(Activity.java:4762)
    at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
    at android.app.Activity.startActivity(Activity.java:5119)
    at android.support.v4.content.ContextCompat.startActivity(ContextCompat.java:248)
    at android.support.customtabs.CustomTabsIntent.launchUrl(CustomTabsIntent.java:263)
    at de.boxine.denisapp.util.web.ChromeTabUtil.openUrl(ChromeTabUtil.java:26)
    at de.boxine.denisapp.login.LoginActivity.openUrl(LoginActivity.java:205)
    at de.boxine.denisapp.login.LoginPresenter.onPasswordForgetLinkClicked(LoginPresenter.java:93)
    at de.boxine.denisapp.login.LoginActivity.lambda$onCreate$2$LoginActivity(LoginActivity.java:153)
    at de.boxine.denisapp.login.-$$Lambda$LoginActivity$HDjhvwi_2M2aWu9LndZHRP-ar9Q.onClick
    at android.view.View.performClick(View.java:6291)
    at android.view.View$PerformClick.run(View.java:24931)
    at android.os.Handler.handleCallback(Handler.java:808)
    at android.os.Handler.dispatchMessage(Handler.java:101)
    at android.os.Looper.loop(Looper.java:166)
    at android.app.ActivityThread.main(ActivityThread.java:7529)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
Burkely91
  • 902
  • 9
  • 28
Denis Pinna
  • 151
  • 1
  • 11

3 Answers3

4

I found the solution for my own problem, before using CustomTabsIntent you should check if there is an app to handle it. If there is not you can then use a simple VIEW intent with the URL.

Here is the method to check if CustomTabsIntent is supported :

public static boolean isCustomTabSupported(Context context, Uri url) {
    return getCustomTabsPackages(context, url).size() > 0;
}

/**
 * Returns a list of packages that support Custom Tabs.
 */
public static ArrayList getCustomTabsPackages(Context context, Uri url) {
    PackageManager pm = context.getPackageManager();
    // Get default VIEW intent handler.
    Intent activityIntent = new Intent(Intent.ACTION_VIEW, url);

    // Get all apps that can handle VIEW intents.
    List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(activityIntent, 0);
    ArrayList packagesSupportingCustomTabs = new ArrayList<>();
    for (ResolveInfo info : resolvedActivityList) {
        Intent serviceIntent = new Intent();
        serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION);
        serviceIntent.setPackage(info.activityInfo.packageName);
        // Check if this package also resolves the Custom Tabs service.
        if (pm.resolveService(serviceIntent, 0) != null) {
            packagesSupportingCustomTabs.add(info);
        }
    }
    return packagesSupportingCustomTabs;
}

(src: https://developer.chrome.com/multidevice/android/customtabs#bestpractices)

Denis Pinna
  • 151
  • 1
  • 11
-1

It seems that feature is NOT supported by all browsers on Android. Perhaps this is what is causing the issue.

From the Chrome developer docs (https://developer.chrome.com/docs/android/custom-tabs/): Custom Tabs is a browser feature, introduced by Chrome, that is now supported by most major browsers on Android.

So you need to first check if there is a browser app available to you that supports CustomTabsIntent. This question has several answers that show you how to do that. How can I check whether Chrome supports Chrome custom tabs?

Burkely91
  • 902
  • 9
  • 28
-2
String myUrl = "google.com";

if (!myUrl .startsWith("http://") && !myUrl .startsWith("https://")){
myUrl = "http://" + myUrl ;
}

Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(myUrl ));
startActivity(browserIntent);

make sure the url you are trying to open starts with http or https

  • Please explain your answers and code as clearly as you can. The above doesn't explain why you are using the code you are using or how it solves the question asked. Check out this post on how to write a good answer stackoverflow.com/help/how-to-answer and keep practicing! :) – Burkely91 Feb 08 '22 at 21:39