Android:在某些设备上尝试在浏览器中打开本地HTML文件时,出现活动未找到异常。

10

在Android浏览器中尝试打开本地HTML文件时,我遇到了一个奇怪的错误。发生的错误是“未找到活动异常”:

android.content.ActivityNotFoundException: Unable to find explicit activity class {com.android.browser/com.android.browser.BrowserActivity}; have you declared this activity in your AndroidManifest.xml?

对我来说真的很奇怪的是这个错误并不在所有设备上发生。它只会在以下设备上出现:

  • Samsung Galaxy Nexus I (4.1.1)
  • Samsung Galaxy Nexus II (4.1.1)
  • Sony Tablet S (4.0.3)

我已经在以下设备上成功测试过我的代码:

  • Samsung Galaxy S I (4.1.1)
  • Samsung Galaxy S III
  • HTC One X
  • HTC Desire S
  • Samsung Galaxy S Plus (2.3.3)
  • Samsung Galaxy Tab 10.1N
  • AVDs with Android Versions ranging from 2.3.3 to 4.1.0

最后,这是我用来使用Android浏览器打开HTML文件的代码。我已经尝试过几种此代码的排列方式,去掉了一些行,但它们都具有相同的效果。一旦我设置组件或类就会出现上述异常。

Uri uri = Uri.parse(filePath);
Intent browserIntent = new Intent(Intent.ACTION_VIEW);
browserIntent.setComponent(new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"));
browserIntent.setDataAndType(uri, "text/html");
browserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
context.startActivity(browserIntent);

我也试过了

browserIntent.setClassName("com.android.browser", "com.android.browser.BrowserActivity");

而不是

browserIntent.setComponent(new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"));

但是效果相同...

有人知道为什么会发生这种情况吗? 我已经搜索了几天,但找不到任何解决我的问题的东西...

非常感谢您提前的帮助,谢谢!


我在使用Intent.ACTION_SENDTO时遇到了同样的错误,并尝试在Samsung Galaxy Nexus I (4.1.1)上使用startActivity(Intent.createChooser())创建一个选择器。但是我还没有找到解决方案。 - ThanksMister
5个回答

14

可能是因为这些设备上没有任何活动,例如 com.android.browser.BrowserActivity,它取决于设备制造商如何实现本机浏览器应用程序(Activity名称和包名称)。

因此,可能的解决方案是,

使用PackageMangerIntent可以检查特定意图类别是否可用,例如,如果存在Intent.CATEGORY_BROWSABLE,则将该应用程序设置为ComponentName。

或者,您可以不指定组件名称,例如,

browserIntent.setComponent(new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"));

让用户选择打开这个页面的Activity,

代码如下:

Uri uri = Uri.parse(filePath);
Intent browserIntent = new Intent(Intent.ACTION_VIEW);
browserIntent.setDataAndType(uri, "text/html");
browserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
context.startActivity(browserIntent);

但是com.android.browser.BrowserActivity不是浏览器的标准Activity吗?所以它应该由Google实现...我测试了你的代码,为用户提供选择的功能导致了以下异常:BrowserHelper(13717):启动浏览器Activity时出错:找不到处理Intent的Activity - Henning
设备制造商可以修改浏览器应用程序的源代码,并按照他们的需求实施以添加功能。 BrowserActivity 仅适用于 Google 源代码。 - user370305
@Henning,不一定。Android是一个开源项目。制造商可以选择自己的路。 - Andy Res
我明白你的意思...但Nexus智能手机是谷歌智能手机,不是吗?所以我希望这些设备上的代码可以正常工作... - Henning
您可以通过logcat在设备上启动浏览器应用程序时检查其活动名称,或者使用特定意图类别的包管理器。 - user370305

7
在某些情况下,您可能希望使用本机浏览器而不是让用户选择一个浏览器。以下是我为避免由于不同包名而导致的ActivityNotFoundException所做的方法,希望这能帮到您 :)
Intent browserIntent = new Intent(Intent.ACTION_VIEW);
PackageManager packageManager = currentActivity.getPackageManager();
Uri uri = Uri.parse(url);
browserIntent.setDataAndType(uri, "text/html");
List<ResolveInfo> list = packageManager.queryIntentActivities(browserIntent, 0);
for (ResolveInfo resolveInfo : list) {
    String activityName = resolveInfo.activityInfo.name;
    if (activityName.contains("BrowserActivity")) {
        browserIntent =
                packageManager.getLaunchIntentForPackage(resolveInfo.activityInfo.packageName);
        ComponentName comp =
                new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
        browserIntent.setAction(Intent.ACTION_VIEW);
        browserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
        browserIntent.setComponent(comp);
        browserIntent.setData(uri);
    }
}

如果已知包和类名,从任何现有的移动浏览器中查找并打开URL是一个很好的方法,也可以避免ActivityNotFoundException异常。 - amardeep

4
为什么不让系统决定使用哪个应用程序呢? 如果我已经安装了Chrome并且喜欢使用Chrome,你强制让我使用默认浏览器,我会有点生气。 下面的方法应该行得通:
final Uri uri = Uri.parse(filePath);
Intent browserIntent = new Intent(Intent.ACTION_VIEW, uri);
browserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
context.startActivity(browserIntent);

1
为什么要指定一个组件?将其放在Intent之外,你就没问题了;操作、类别和数据/类型已经足够了。

不指定组件或类通常会导致异常,告诉我系统找不到处理我的意图的活动。 - Henning

0
新设备可能会使用Chrome而不是原生浏览器,因此您应该使用以下代码:

browserIntent.setComponent(new ComponentName("com.android.chrome", "com.google.android.apps.chrome.IntentDispatcher"));


你可以卸载 Chrome,但不要指定特定组件,让系统为你选择。 - fm-sys

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接