问题 Android 3.x仅限WebView文本选择+ JavaScript


问题域:基于Android WebView的ePub格式阅读器 -

我们需要可以通过JavaScript方法访问的文本高亮显示(例如,启用它们,关闭它们,保存它们给它们发送电子邮件等)

知道的任何人,如果我错了,请纠正我: 在WebView上选择文本期间 -

基本上我们交给一个TextView覆盖(WebTextView),除了可视化之外没有附加到底层html(很好地将它全部排成一行并使其无缝,顺便说一句),我们在其上执行TextSelectionActionMode并提供ClipboardManager结果......为了清楚起见,在此库存过程中,实际上并未实际选择带有WebView的实际HTML,这就是JavaScript无法访问操作结果的原因。

因此,为了使这种行为在3.1+中运行,我有一些可能的计划继续在WebView上实现我自己的选择 - 这是我想知道我是否看不到我的角落的部分:) - -

1)捕获MOTION_DOWN的长按,启动选择模式,覆盖内置的TextSelection ActionMode(以提供客户品牌 - 我发现这样做的方式是如此hackish它伤害)观看拖动,捕获MOTION_UP位置,映射这些co to WebView,并根据coords进行选择(同时将文本与ClipboardManager捕获的文本进行比较)

2)创建我自己的“WebTextView”(整个lotta工作大声笑)并且不那么 - hackishly创建我自己的ActionMode并完成上述所有操作。

3)使用由库存选择过程生成的MotionEvent,并以某种方式覆盖由此触发的库存TextSelection ActionMode。

这些是我看到的选项,希望我的接近和沮丧 有了这个让我变得更加简单(读作内置) 一两个解决方案。

感谢你的宝贵时间。


2869
2017-08-04 21:00


起源



答案:


我的工作在2.2 - 4.0.3。我使用了一个javascript界面​​并将所有触摸传递给它。解决方案似乎工作得很好,我在github上放了一个示例项目。 github项目包括assets文件夹中必需的js以及加载测试页面并实现处理选择所需的所有必要方法的测试页面和Web视图。 github项目的链接是 https://github.com/btate/BTAndroidWebViewSelection。有它。


11
2017-07-06 18:46



很好,由于加载大型HTML页面(特定于我们的应用程序)时速度快,我无法使用各种JS库,所以我最终从头开始编写js。 - Dan
感谢您在GitHub上发帖,btate。 - mikejonesguy
@btate上面的github项目不适用于操作系统版本4.1 +。 - sachin003


答案:


我的工作在2.2 - 4.0.3。我使用了一个javascript界面​​并将所有触摸传递给它。解决方案似乎工作得很好,我在github上放了一个示例项目。 github项目包括assets文件夹中必需的js以及加载测试页面并实现处理选择所需的所有必要方法的测试页面和Web视图。 github项目的链接是 https://github.com/btate/BTAndroidWebViewSelection。有它。


11
2017-07-06 18:46



很好,由于加载大型HTML页面(特定于我们的应用程序)时速度快,我无法使用各种JS库,所以我最终从头开始编写js。 - Dan
感谢您在GitHub上发帖,btate。 - mikejonesguy
@btate上面的github项目不适用于操作系统版本4.1 +。 - sachin003


我不是100%确定哪些方法/属性可以为您提供范围和选择。我在文档中没有看到任何内容。但我能够使用反射以像素为单位获得所选范围。不确定这是否有助于任何人,但认为值得在这里发布。

Region result = null;
try {
     Object[] params = null;

     Method nativeGetSelectionRegion = WebView.class.getDeclaredMethod("nativeGetSelectionRegion");
     nativeGetSelectionRegion.setAccessible(true);     
     result = (Region)nativeGetSelectionRegion.invoke(this, params);


     Log.i(TAG, "res: region " + result.getBounds().toShortString());

 } catch (Exception e) {
     e.printStackTrace();
 }

希望这有助于某人

编辑:这不适用于3.1+


1
2018-04-09 14:57



信任反思是痛苦的,至少可以说...信任javascript同样痛苦(我现在知道,我的解决方案在4.0的WebView中被破解,在我的类型中处理“如何”)在Javascript,document.getSelection( )返回Selection对象,您可以从中收集Document对象中的实际位置 developer.mozilla.org/en/DOM/window.getSelection  (它适用于文档或窗口界面)我不相信任何通过Android世界中的反射派生的东西;很简单,他们会打破它。所有这一切,这是一个很好的备份计划应该javascript失败! - Dan
你是如何触发document.getSelection()的?我们最初尝试过,发现通过loadUrl加载javascript(“javascript:document.getSelection()”);导致选择清除所以没有任何东西。 - smokingoyster
你需要使用javascript在webview中进行繁重的工作,并返回一个(在我的例子中)管道分隔的String,其中包含你所追求的相关数据。即,使用JavaScriptInterface作为javascript中生成的“flattened”选择对象的接收器。此外,根据您对该数据的处理(我使用我的实时选择),请记住,有必要交付到UI线程(因为这很可能不会在UI线程上),所以处理程序模式可以很方便... - Dan
啊,只是重读你的帖子 - 这里有一个链接,可以帮助你理解这个过程: stackoverflow.com/questions/6240139/... - Dan
我们过去曾尝试在javascript中绑定一个鼠标向上事件,该事件将一个范围发送到javascript界面​​。在屏幕上有选择之前,该事件会正常触发。此时,看起来webTextView会立即接管,并且鼠标注册事件永远不会在webView中注册。我们必须支持2.2,所以这可能是原因。 - smokingoyster