我想从Android的网页中提取一些内容 . 我知道有解析HTML的库,但我想也许我可以作弊 .
这就是我在做什么..
-
使用应用程序上下文以编程方式创建WebView,因此不必在UI中显示 .
-
加载网页
-
附加JS接口
-
注入一些Javascript以与主机应用程序进行交互
这是一些代码......
public void getLatestVersion(){
Log.e("Testing", "getLatestVersion called...");
WebView webview = new WebView(context.getApplicationContext());
webview.loadUrl("https://example.com");
webview.addJavascriptInterface(new jsInterface(), "Droid");
webview.loadUrl("javascript: window.onload=function(){ Droid.showToast('testing!'); }");
}
class jsInterface{
@JavascriptInterface
public void showToast(String message){
Log.e("Testing", message);
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
}
由于WebView在UI中不可见,因此很难分辨哪个部分正在破坏 . 我所知道的是调用了第一个调用的Log,但是JavascriptInterface中的Log和Toast从未显示过 .
我正在努力做甚么可能吗?如果是这样,我做错了什么?如果没有,为什么不呢?
EDIT
将视图保留在UI中进行测试,显然第二次调用loadUrl不起作用 . 无论我尝试注入什么Javascript,它都不起作用 .
EDIT 2
忘记启用Javascript我感到愚蠢,但它仍然没有工作..我添加了以下行...
WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);
webview.loadUrl("javascript: alert('farts0');");
webview.loadUrl("https://example.com");
setContentView(webview);
String js = "document.body.innerHTML = '<p>test<p>';";
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webview.evaluateJavascript(js, null);
}else{
webview.loadUrl("javascript: "+js);
}
EDIT 3
感谢大家的建议,你一直很有帮助,但到目前为止它还没有工作,所以除非有人在下一个小时提供工作代码,否则Nainal将得到一半的赏金 . 如果是这样,我不确定我是否会被允许再给它一个赏金,因为问题仍然没有得到解决 .
到目前为止,这是我的完整代码,考虑了此页面上的建议,并尝试了我不太了解的手册中的几个设置 .
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = new WebView(getApplicationContext());
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
webView.getSettings().setAllowFileAccessFromFileURLs(true);
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setJavaScriptEnabled(true);
try {
webView.setWebContentsDebuggingEnabled(true);
}catch(Exception e){}
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
webView.setVisibility(View.GONE);
}
@Override
public void onPageFinished(final WebView view, String url) {
Log.e("checking", "MYmsg");
Log.e("content-url", webView.getSettings().getAllowContentAccess()?"y":"n");
webView.loadUrl("javascript: void window.CallToAnAndroidFunction.setVisible(document.getElementsByTagName('body')[0].innerHTML);");
}
});
webView.setVisibility(View.INVISIBLE);
webView.addJavascriptInterface(new myJavaScriptInterface(), "CallToAnAndroidFunction");
webView.loadUrl("http://example.com");
}
public class myJavaScriptInterface {
@JavascriptInterface
public void setVisible(final String aThing) {
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
webView.setVisibility(View.VISIBLE);
Toast.makeText(MainActivity.this, "Reached JS: "+aThing, Toast.LENGTH_LONG).show();
}
});
}
};handler.postDelayed(runnable,2000);
}}
}
Edit 4
开始新的赏金并将奖励增加到100分 . 奈纳尔获得了最有益的最后奖励,而不是解决问题 .
5 回答
这是一个清理版本,最大限度地减少了不需要的代码 . 这适用于API级别18和23仿真器(以及我的6.0.1手机) . WebView永远不会添加到视图层次结构中 . 吐司显示从网站上拉出的HTML . 使用Java 8针对API 25进行编译 .
这是布局 .
最后清单 .
请尝试这个,它调用javascript函数并显示toast消息 .
它不会在UI中显示webView,因为webview未在xml布局中定义 .
突然出现在我身上的一些事情 .
在加载任何URL之前,应附加JavaScript接口 .
可能在加载原始URL之后分配第二个loadURL
window.onload
. 调用setWebViewClient()
并从onPageFinished
方法中调用Droid.showToast('testing!');
会更有意义 .@JavascriptInterface
不在主UI线程上运行,这将阻止您的toast运行 .第二个编辑的
innerHTML
代码无法正常工作的问题与第2点有关 . 您在同步单个块中进行调用,而应该在页面dom加载后进行调用AKAonPageFinished()
webview.addJavascriptInterface(new jsInterface(), "Droid");
必须在webview.loadUrl("https://example.com");
之前来然后使用Webview Listener . onFinish()方法..然后在onFinish方法中注入
webview.loadUrl("javascript: window.onload=function(){ Droid.showToast('testing!'); }");
我已经做了大量的webview注入修改web ..我认为它应该工作..
编辑
使用
chrome://inspect/#devices
在加载webview时检查您的应用如何在
WebChromeClient
中使用onProgressChanged()
?我已经将
Edit 3
中的一些代码更改为这样,更改是您在
progress==100
而不是onPageFinished()
时调用javascript