致命异常:android.content.ActivityNotFoundException:未找到 Activity 来处理 Intent
Fatal Exception: android.content.ActivityNotFoundException: No Activity found to handle Intent
我在某些设备上打开 url 时遇到以下错误。我的设备上没有任何错误,但很多设备都是。
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)
发生错误的代码非常简单。
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
}
在某些设备(不是旧设备,主要是最新设备)中,会触发异常,但这怎么可能?这意味着设备有 0 个浏览器?如果是这样,我的问题是如何打开 url 即使用户 禁用所有浏览器 ?提前致谢。
注意: 在我升级到 live 版本中的自定义选项卡之前,我使用以下代码打开 url 但我总是得到 ActivityNotFoundException:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(browserIntent);
这是最简单的代码,打开任何 url 但不使用 try/catch 会导致崩溃。使用正常方式或自定义选项卡并不重要,它总是导致 ActivityNotFoundException。我正在寻找一个解决方案,无论发生什么,它都会打开 url。不知道可不可以。
注2: MinApi 是Android 5.0 (Lollipop)
关于这个问题的几点说明:
将非浏览器应用检测为浏览器
他们查询浏览器可以检测非浏览器应用程序,这将在启动自定义选项卡时导致 ActivityNotFoundException
。有关示例,请参阅 this issue。
在查询可以处理浏览器意图的包时,我建议使用以下内容:
Intent browserIntent = new Intent()
.setAction(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
.setData(Uri.fromParts("http", "", null));
这也是Android framework itself detects browsers的方式。
以下应该不是问题,因为自定义选项卡仍然有效,但是 PackageManager.MATCH_DEFAULT_ONLY
的行为在 Android M 上发生了变化,并且只返回默认浏览器 - 我是不确定如果未设置默认浏览器会发生什么,但这可能意味着返回的列表将为空。这意味着当未设置默认浏览器时,用户将获得消歧对话框。从 Android M 及更高版本开始,如果您想让所有浏览器避免消歧对话框,您可能还需要使用 PackageManager.MATCH_ALL
额外查询包管理器。
查看 android-browser-helper
库中的 this snippet 以检测自定义选项卡和受信任的 Web Activity。
准备 Android 11
Android 11 引入了 package visibility,应用程序现在必须声明它们正在查询哪些包。如果您的应用程序未实现此功能,即使安装了浏览器,查询包管理时返回的列表也将为空。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
possibleProviders.addAll(pm.queryIntentActivities(queryBrowsersIntent,
PackageManager.MATCH_ALL));
}
同样,这不应导致 ActivityNotFoundException
,因为它只会导致自定义选项卡在没有设置软件包的情况下启动。
禁用浏览器
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);
用户可以禁用所有浏览器应用程序,但我认为这不会很常见。
另一件需要注意的事情是 Android 电视和 Android 汽车设备没有安装浏览器。如果您的应用程序以这些设备为目标,您将无法打开这些 URL。但这只是一个问题,如果你的应用程序是针对这些平台的。
我根据@andreban 的回答创建了一个方法。我相信它会打开 url %99.99 次。
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);
}
}
我在某些设备上打开 url 时遇到以下错误。我的设备上没有任何错误,但很多设备都是。
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)
发生错误的代码非常简单。
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
}
在某些设备(不是旧设备,主要是最新设备)中,会触发异常,但这怎么可能?这意味着设备有 0 个浏览器?如果是这样,我的问题是如何打开 url 即使用户 禁用所有浏览器 ?提前致谢。
注意: 在我升级到 live 版本中的自定义选项卡之前,我使用以下代码打开 url 但我总是得到 ActivityNotFoundException:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(browserIntent);
这是最简单的代码,打开任何 url 但不使用 try/catch 会导致崩溃。使用正常方式或自定义选项卡并不重要,它总是导致 ActivityNotFoundException。我正在寻找一个解决方案,无论发生什么,它都会打开 url。不知道可不可以。
注2: MinApi 是Android 5.0 (Lollipop)
关于这个问题的几点说明:
将非浏览器应用检测为浏览器
他们查询浏览器可以检测非浏览器应用程序,这将在启动自定义选项卡时导致 ActivityNotFoundException
。有关示例,请参阅 this issue。
在查询可以处理浏览器意图的包时,我建议使用以下内容:
Intent browserIntent = new Intent()
.setAction(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
.setData(Uri.fromParts("http", "", null));
这也是Android framework itself detects browsers的方式。
以下应该不是问题,因为自定义选项卡仍然有效,但是 PackageManager.MATCH_DEFAULT_ONLY
的行为在 Android M 上发生了变化,并且只返回默认浏览器 - 我是不确定如果未设置默认浏览器会发生什么,但这可能意味着返回的列表将为空。这意味着当未设置默认浏览器时,用户将获得消歧对话框。从 Android M 及更高版本开始,如果您想让所有浏览器避免消歧对话框,您可能还需要使用 PackageManager.MATCH_ALL
额外查询包管理器。
查看 android-browser-helper
库中的 this snippet 以检测自定义选项卡和受信任的 Web Activity。
准备 Android 11
Android 11 引入了 package visibility,应用程序现在必须声明它们正在查询哪些包。如果您的应用程序未实现此功能,即使安装了浏览器,查询包管理时返回的列表也将为空。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
possibleProviders.addAll(pm.queryIntentActivities(queryBrowsersIntent,
PackageManager.MATCH_ALL));
}
同样,这不应导致 ActivityNotFoundException
,因为它只会导致自定义选项卡在没有设置软件包的情况下启动。
禁用浏览器
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);
用户可以禁用所有浏览器应用程序,但我认为这不会很常见。
另一件需要注意的事情是 Android 电视和 Android 汽车设备没有安装浏览器。如果您的应用程序以这些设备为目标,您将无法打开这些 URL。但这只是一个问题,如果你的应用程序是针对这些平台的。
我根据@andreban 的回答创建了一个方法。我相信它会打开 url %99.99 次。
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);
}
}