【发布时间】:2012-03-23 16:47:25
【问题描述】:
在我的应用程序中,我使用EPUBLIB 在webview 中显示epub HTML 文件。
我的问题是我想为我的 epub 阅读器使用书签功能。为此,我想从 webview 获取文本,该文本显示我的 epub 的 HTML 文件中的页面,然后在我的书签活动中使用该文本向用户显示他们已添加书签的内容。
我怎样才能做到这一点?
【问题讨论】:
在我的应用程序中,我使用EPUBLIB 在webview 中显示epub HTML 文件。
我的问题是我想为我的 epub 阅读器使用书签功能。为此,我想从 webview 获取文本,该文本显示我的 epub 的 HTML 文件中的页面,然后在我的书签活动中使用该文本向用户显示他们已添加书签的内容。
我怎样才能做到这一点?
【问题讨论】:
从 webview 获取纯文本内容相当困难。基本上,android 类不提供它,但 javascript 提供,并且 Android 提供了一种让 javascript 将信息传递回您的代码的方法。
在我详细介绍之前,请注意,如果您的 html 结构很简单,您最好手动解析数据。
也就是说,这就是你要做的:
为了澄清,我将在下面发布一个工作(但非常粗略)的代码示例。它在顶部显示一个 webview,在底部显示一个带有基于文本的内容的 textview。
package test.android.webview;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;
public class WebviewTest2Activity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
WebView webView = (WebView) findViewById(R.id.webView);
TextView contentView = (TextView) findViewById(R.id.contentView);
/* An instance of this class will be registered as a JavaScript interface */
class MyJavaScriptInterface
{
private TextView contentView;
public MyJavaScriptInterface(TextView aContentView)
{
contentView = aContentView;
}
@SuppressWarnings("unused")
public void processContent(String aContent)
{
final String content = aContent;
contentView.post(new Runnable()
{
public void run()
{
contentView.setText(content);
}
});
}
}
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new MyJavaScriptInterface(contentView), "INTERFACE");
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url)
{
view.loadUrl("javascript:window.INTERFACE.processContent(document.getElementsByTagName('body')[0].innerText);");
}
});
webView.loadUrl("http://shinyhammer.blogspot.com");
}
}
使用以下 main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="0.5" />
<TextView
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="0.5" />
</LinearLayout>
【讨论】:
INTERFACE 的 procesContent() 方法,从 android 代码注册,传递(d)当前显示的页面正文的innerText 属性。 如果您有具体问题,请尽管提问!
Java:
wvbrowser.evaluateJavascript(
"(function() { return ('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>'); })();",
new ValueCallback<String>() {
@Override
public void onReceiveValue(String html) {
Log.d("HTML", html);
// code here
}
});
科特林:
web_browser.evaluateJavascript("(function() { return ('<html>'+document.getElementsByTagName('span')[0].innerText+'</html>'); })();")
{ html ->
Toast.makeText(this@Your_activity, html, Toast.LENGTH_SHORT).show()
// code here
}
【讨论】:
evaluateJavascript 是首选,因为它有一个回调,所以更容易异步(如果你特别需要返回值)...
return () 为我工作。无论如何,它就像一个魅力!
在这种情况下,我唯一想到的就是使用 javascript。快速搜索我找到了android.webkit.WebView.addJavascriptInterface。
你想学习“addJavascriptInterface”,它最终会帮助你解决问题
【讨论】:
上面提供的解决方案使用 innerText 属性提供文本,它将返回 webView 中的所有文本。我在下面提出的解决方案将帮助您从屏幕上 webView 的可见部分提取文本。
第1步:需要javaScript的帮助,因此首先启用javascript。
webView.addJavascriptInterface(new IJavascriptHandler(getActivity().getApplicationContext()), "Android"); //if your class extends a Fragment class
或
view.addJavascriptInterface(new IJavascriptHandler(this), "Android"); //if your class extends Activity.
第 2 步:创建一个 javaInterface 内部类。
final class IJavascriptHandler {
Context mContext;
IJavascriptHandler(Context c) {
mContext = c;
}
//API 17 and higher required you to add @JavascriptInterface as mandatory before your method.
@JavascriptInterface
public void processContent(String aContent)
{
//this method will be called from within the javascript method that you will write.
final String content = aContent;
Log.e("The content of the current page is ",content);
}
}
第 3 步:现在您必须添加 javascript 方法。您将方法编写为字符串,然后加载它。该方法根据提供给它的参数返回文本。所以,你需要2个字符串。一个将加载 javascript 方法,另一个将调用它。
加载javascript方法的方法。
String javaScriptToExtractText = "function getAllTextInColumn(left,top,width,height){"
+ "if(document.caretRangeFromPoint){"
+ "var caretRangeStart = document.caretRangeFromPoint(left, top);"
+ "var caretRangeEnd = document.caretRangeFromPoint(left+width-1, top+height-1);"
+ "} else {"
+ "return null;"
+ "}"
+ "if(caretRangeStart == null || caretRangeEnd == null) return null;"
+ "var range = document.createRange();"
+ "range.setStart(caretRangeStart.startContainer, caretRangeStart.startOffset);"
+ "range.setEnd(caretRangeEnd.endContainer, caretRangeEnd.endOffset);"
+ "return range.toString();};";
调用上述函数的方法。
String javaScriptFunctionCall = "getAllTextInColumn(0,0,100,100)";
//I've provided the parameter here as 0,0 i.e the left and top offset and then 100, 100 as width and height. So, it'll extract the text present in that area.
第 4 步:现在,您需要加载上述 2 个 javascript。
webView.loadUrl("javascript:"+ javaScriptToExtractText);
//this will load the method.
view.loadUrl("javascript:window.Android.processContent("+javaScriptFunctionCall+");");
//this will call the loaded javascript method.
享受吧。
【讨论】:
你为什么不直接从书中获取带有 EPUBLIB 的文本?
您在 EPUBLIB 的帮助下获得了该 html,不是吗?你是怎么把它放在webview中的?我没有看到任何例子。
【讨论】:
的位置。然后从该标签中创建文本的 substring() 。重复直到找到第 n 个标签。现在确定段落的结尾并获得最终的 substring()。
标签中的文本。 .