Java 选择WebView中的元素并获取详细信息

Java 选择WebView中的元素并获取详细信息,java,android,android-studio,Java,Android,Android Studio,我在android应用程序中实现了一个webview,并试图在用户单击布局时突出显示或标记元素 webview的初始化如下所示: myWebView.getSettings().setJavaScriptEnabled(true); //myWebView.getSettings().setGeolocationEnabled(true); //myWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); myWe

我在android应用程序中实现了一个webview,并试图在用户单击布局时突出显示或标记元素

webview的初始化如下所示:

myWebView.getSettings().setJavaScriptEnabled(true);
//myWebView.getSettings().setGeolocationEnabled(true);
//myWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
myWebView.getSettings().setBuiltInZoomControls(true);
myWebView.getSettings().setDomStorageEnabled(true);
myWebView.setWebViewClient(new WebViewController());
尝试标记用户单击的元素,例如此屏幕截图中的元素:

点选

我通过jsoup获取所有页面div:

doc = Jsoup.connect(url).get();
final Elements alldivs = doc.select("div");
ArrayList<String> list = new ArrayList<String>();
for (org.jsoup.nodes.Element e : alldivs) {
if (!e.id().equals(""))
list.add(e.id());
}
doc=Jsoup.connect(url.get();
最终元素alldivs=文件选择(“div”);
ArrayList=新建ArrayList();
for(org.jsoup.nodes.Element e:alldivs){
如果(!e.id().equals(“”)
添加(e.id());
}
但是如何将选择标记为上面的照片,然后从divid中选择标记的内容

你怎么能做出这样的东西

我在webview中使用这个javascript来高亮显示选择,但是如何以编程方式获取单击的元素,比如:所选div的id或其他值

public class MyWebViewClient extends WebViewClient {
    @Override
    public void onPageFinished(WebView view, String url) {
        view.loadUrl("javascript: "
                + "Object.prototype.each = function (fn, bind) {\n" +
                "                console.log(bind);\n" +
                "                for (var i = 0; i < this.length; i++) {\n" +
                "                    if (i in this) {\n" +
                "                        fn.call(bind, this[i], i, this);\n" +
                "                    }\n" +
                "                }\n" +
                "            };\n" +
                "\n" +
                "            var _addListener = document.addEventListener || document.attachEvent,\n" +
                "                _eventClick = window.addEventListener ? 'click' : 'onclick';\n" +
                "\n" +
                "            var elements = document.getElementsByTagName(\"div\");\n" +
                "\n" +
                "            elements.each(function (el) {\n" +
                "                _addListener.call(el, _eventClick, function () {\n" +
                                 // todo process the clicked div element
                "                    el.style.cssText = \"border-color:  black;border-style:  dashed;\"\n" +
                "                }, false);\n" +
                "            })");
    }
}
公共类MyWebViewClient扩展了WebViewClient{
@凌驾
公共void onPageFinished(WebView视图,字符串url){
view.loadUrl(“javascript:”
+Object.prototype.each=函数(fn,bind){\n+
“console.log(绑定);\n”+
“对于(var i=0;i
将web视图视为网页视图。您需要配置该web视图中的元素以发送请求,该请求将在您的android应用程序中激发意图,这是可能的,但除非您知道该web视图中的用户并对用户进行身份验证,否则它将不适用于多个用户。。。关键是,如果你想将请求从web发送到应用程序的逻辑部分,这是非常复杂的。即使你能做到这一点,也不是最优的,我不鼓励这样做

另一方面,如果坚持使用web视图,您可以做的是完成web视图上的其余逻辑操作。不要从web视图返回到应用程序java逻辑

通常,web视图用于显示某些内容,而不是在应用程序上执行操作。(该操作可能在同一web视图上使用)


我希望您能理解,我已经尽可能多地解释了。

如果我理解正确,您希望从HTML组件获取一些信息,并将其转换为本机端

根据,不可能将任意对象传递给Java,但至少可以传递单击节点的HTML代码,然后对其进行本机解析

这段基于你的代码正是这样做的

MainActivity.java:我想这是不言自明的。我所做的唯一不同之处就是从一个单独的文件中获取Javascript代码,这样更易于维护

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final WebView myWebView = findViewById(R.id.webView);
        final WebSettings settings = myWebView.getSettings();

        settings.setJavaScriptEnabled(true);
        myWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                final String injectedJs = "javascript:(function(){" + injectedJs() + "})()";
                myWebView.loadUrl(injectedJs);
            }
        });

        myWebView.addJavascriptInterface(
                new Object() {
                    @JavascriptInterface
                    public void onClick(String param) {
                        Toast.makeText(MainActivity.this, param, Toast.LENGTH_LONG).show();
                    }
                },
                "appHost"
        );
        myWebView.loadUrl("https://google.com");
    }

    // Javascript code to inject on the Web page
    private String injectedJs() {
        BufferedReader stream = null;
        StringBuilder jsBuilder = new StringBuilder();
        try {
            stream = new BufferedReader(new InputStreamReader(getAssets().open("js.js")));
            String line;
            while ((line = stream.readLine()) != null) {
                jsBuilder.append(line.trim());
            }
            return jsBuilder.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "";
    }
}

js.js:这部分的基础是您的代码。请记住,由于
injectedJs()
删除了所有行标记,因此每个语句都需要完成,包括注释,因此使用
/*…*/
而不是
/

/* Keep track of the last clicked element so we can un-highlight it */
var lastSelectedItem = null;

var showHighlighted = function(/* HTML element */view, /*boolean */highlighted) {
    if (view) {
        view.style.cssText = highlighted? 'border-color: black;border-style: dashed;' : '';
    }
};

/* This new method, _addEventListener and _eventClick are the same as yours */
Object.prototype.each = function (fn, bind) {
                for (var i = 0; i < this.length; i++) {
                    if (i in this) {
                        fn.call(bind, this[i], i, this);
                    }
                }
            };

var _addListener = document.addEventListener || document.attachEvent,
    _eventClick = window.addEventListener ? 'click' : 'onclick';

/* I changed the element selection criteria, but you can change it back easily.
   I am adding event listeners all the leaf elements in the DOM. */
var elements = document.body.getElementsByTagName('*');
elements.each(function (el) {
    if (el.children.length == 0) {
        _addListener.call(el, _eventClick, function () {
            /* First, deal with the previously selected item*/
            showHighlighted(lastSelectedItem, false);
            if (lastSelectedItem !== null) {
                appHost.onClick(lastSelectedItem.outerHTML);                
            }

            /* Update the selected item reference */
            lastSelectedItem = el;


            /* Finally, deal with the previously selected item*/
            showHighlighted(lastSelectedItem, true);
            appHost.onClick(el.outerHTML);
        }, false);
    }
});
/*跟踪上次单击的元素,以便取消高亮显示它*/
var lastSelectedItem=null;
var showHighlighted=函数(/*HTML元素*/view,/*boolean*/highlighted){
if(视图){
view.style.cssText=高亮显示?'边框颜色:黑色;边框样式:虚线;':'';
}
};
/*这个新方法_addEventListener和_eventClick与您的方法相同*/
Object.prototype.each=函数(fn,bind){
for(var i=0;i
是的,我理解您的意思,谢谢您的解释。事实上,我正在与webview、javascript进行交互。所以我的问题是如何从javascript中获取一些信息,我用它在选中后标记特定的DIV。你可以像标记网页的普通DIV一样标记它,但它不会