【发布时间】:2014-01-28 19:02:31
【问题描述】:
我有一个 Android 应用程序,它创建一个本地 HTML 文件,然后在浏览器中将其显示给用户。我遇到了 BrowserActivity 无法在不同设备上运行的问题,具体取决于安装的浏览器。我当前的代码执行以下操作 -
public void displayStats()
{
String file = produceStats();
Uri uri = Uri.parse("file://" + file);
// chrome ??
Intent intent1 = new Intent(Intent.ACTION_VIEW);
intent1.setDataAndType(uri, "multipart/related");
// default "Internet" browser
Intent intent2 = new Intent(Intent.ACTION_VIEW, uri);
intent2.setDataAndType(uri, "text/html");
intent2.setClassName("com.android.browser", "com.android.browser.BrowserActivity");
// any other browser (FireFox) ??
Intent intent3 = new Intent(Intent.ACTION_VIEW);
intent3.setDataAndType(uri, "text/html");
intent3.addCategory(Intent.CATEGORY_BROWSABLE);
PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities1 = packageManager.queryIntentActivities(intent1, 0);
List<ResolveInfo> activities2 = packageManager.queryIntentActivities(intent2, 0);
List<ResolveInfo> activities3 = packageManager.queryIntentActivities(intent3, 0);
boolean isIntentSafe1 = activities1.size() > 0;
boolean isIntentSafe2 = activities2.size() > 0;
boolean isIntentSafe3 = activities3.size() > 0;
List<Intent> targetedShareIntents = new ArrayList<Intent>();
if (isIntentSafe1)
{
unpackResolvedIntents(uri, "multipart/related", activities1, targetedShareIntents);
}
if (isIntentSafe2) {
unpackResolvedIntents(uri, "text/html", activities2, targetedShareIntents);
}
if (isIntentSafe3) {
unpackResolvedIntents(uri, "text/html", activities3, targetedShareIntents);
}
if (targetedShareIntents.isEmpty()) {
// go to market to install app ????
Toast.makeText(plink.this, "Please install BROWSER to complete (Chrome)", Toast.LENGTH_LONG).show();
Intent goToMarket = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse("market://details?id=com.android.chrome"));
startActivity(goToMarket);
} else if (targetedShareIntents.size() == 1) {
startActivity(targetedShareIntents.remove(0));
} else {
Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), "Select viewer");
Intent[] extraIntents = new Intent[targetedShareIntents.size()];
for (int i = 0; i < targetedShareIntents.size(); i++) {extraIntents[i] = targetedShareIntents.get(i);}
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
startActivity(chooserIntent);
}
}
produceStats() 调用返回文件的路径,然后这个函数的其余部分处理各种不同的浏览器,如果有多个可用的浏览器,它会为用户提供一个选择器。
我的问题是,一位用户在使用 SILK 浏览器的 Kindle HD 设备上运行该应用程序时报告了该应用程序崩溃。因此,他的堆栈转储是 -
26 Jan 2014 16:26:09 GMT:Uncaught exception in java.lang.Thread:main(Unable to find explicit activity class {com.android.browser/com.android.browser.BrowserActivity}; have you declared this activity in your AndroidManifest.xml?)
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?
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1624)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1418)
我的问题是 - 如何在 Kindle 上启动以在 SILK 中显示文件? 谢谢
【问题讨论】:
-
您不只是将
ACTION_VIEW与Uri和text/html一起用作MIME 类型是否有特殊原因?或者,为什么您不只是在自己的活动中使用WebView?除了很多复杂性之外,您认为您从这段代码的其余部分中获得了什么? -
@CommonsWare 感谢您的回复。如果可能的话,我想使用所有可用的浏览器,我通过反复试验(和在这里搜索)找到了让每个浏览器满意所需的差异。我可以按照您的建议尝试使用 URI 和 Mimetype 的 ACTION_VIEW,我只是担心为什么 Kindle 会在堆栈跟踪中抛出错误并且它会再次这样做吗?谢谢。
-
“我通过反复试验(和在这里搜索)发现了让每个浏览器都满意所需的差异”——旧的 AOSP 浏览器完全能够处理
ACTION_VIEWIntent而无需setClassName()。每次您使用setClassName()(或其等效项)指向您自己以外的某个应用程序时,使用硬编码值,$DEITY会杀死$CUTEBABYANIMAL。 “我只是担心 Kindle 为什么会在堆栈跟踪中抛出错误”——不知何故,PackageManager认为您的硬编码setClassName()很好,而实际上在该设备上并非如此。 -
@CommonsWare - 这就是我的问题“旧的 AOSP 浏览器完全能够处理 ACTION_VIEW Intent” - 有问题的用户正在使用带有 SILK 浏览器的 KINDLE HD,它不能与ACTION_VIEW 意图。我只使用我的 URI 和 Mime 类型集(已删除 setClassName)进行了快速构建,它适用于我的 Android 设备,并在 Kindle HD 上引发相同的异常。这是 Kindle 特有的吗?
-
“在 Kindle HD 上抛出相同的异常”——您上面的异常特别指出它正在尝试启动
com.android.browser/com.android.browser.BrowserActivity,只有在您在 @ 中指定的情况下才会发生 AFAIK 987654336@.