javaandroidwebviewchrome-custom-tabsandroid-customtabs

Fatal Exception: android.content.ActivityNotFoundException: No Activity found to handle Intent


I'm getting following error on some devices while opening url. I don't get any error on my devices but many devices are.

Fatal Exception: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=https://google.com/... }
   at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2076)
   at android.app.Instrumentation.execStartActivity(Instrumentation.java:1720)
   at android.app.Activity.startActivityForResult(Activity.java:5258)
   at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:574)
   at android.app.Activity.startActivityForResult(Activity.java:5203)
   at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:560)
   at android.app.Activity.startActivity(Activity.java:5587)
   at android.app.Activity.startActivity(Activity.java:5555)

The code where error occurs is pretty straight-forward.

Uri uri = Uri.parse("https://google.com");

try {
     CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
     builder.setShowTitle(true);
     CustomTabsIntent customTabsIntent = builder.build();
     Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://"));

     ResolveInfo resolveInfo = getPackageManager().resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
     if (resolveInfo != null && resolveInfo.activityInfo.packageName.length() > 0) {
         customTabsIntent.intent.setPackage(resolveInfo.activityInfo.packageName);
     }

     customTabsIntent.launchUrl(this, uri);
} catch (ActivityNotFoundException e) {
          // Do nothing
}

In some devices (not old devices, mostly newest device), exception triggered but how can it be possible? This means devices has 0 browser? If so, my question is how can I open url even user disabled all browsers? Thanks in advance.

Note: Before I upgraded to custom-tabs in the live version, I used following code to open url but I always get the ActivityNotFoundException:

Intent browserIntent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(browserIntent);

It is the simplest code the open any url but without usage of try/catch causes crashes. It doesn't matter to use normal way or custom-tabs, it always causes ActivityNotFoundException. I'm looking a solution which opening url whatever happens. I'm not sure whether it is possible or not.

Note2: MinApi is Android 5.0 (Lollipop)

enter image description here


Solution

  • I create a method which based on @andreban's answer. I believe it will open url %99.99 times.

    public static void openURL(Context mContext, Uri uri) {
        CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
        builder.setShowTitle(true);
        CustomTabsIntent customTabsIntent = builder.build();
        Intent browserIntent = new Intent()
                .setAction(Intent.ACTION_VIEW)
                .addCategory(Intent.CATEGORY_BROWSABLE)
                .setType("text/plain")
                .setData(Uri.fromParts("http", "", null));
    
        List<ResolveInfo> possibleBrowsers;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            possibleBrowsers = mContext.getPackageManager().queryIntentActivities(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
            if (possibleBrowsers.size() == 0) {
                possibleBrowsers = mContext.getPackageManager().queryIntentActivities(browserIntent, PackageManager.MATCH_ALL);
            }
        } else {
            possibleBrowsers = mContext.getPackageManager().queryIntentActivities(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
        }
    
        if (possibleBrowsers.size() > 0) {
            customTabsIntent.intent.setPackage(possibleBrowsers.get(0).activityInfo.packageName);
            customTabsIntent.launchUrl(mContext, uri);
        } else {
            Intent browserIntent2 = new Intent(Intent.ACTION_VIEW, uri);
            mContext.startActivity(browserIntent2);
        }
    }