在 WebView 中注入 Javascript 桥

2024-05-23

我想从 Android 网页中提取一些内容。我知道有一些库可以解析 HTML,但我想也许我可以稍微作弊一下。

这就是我正在做的..

  1. 使用应用程序上下文以编程方式创建 WebView,因此不必在 UI 中显示它。
  2. 加载网页
  3. 附上JS接口
  4. 注入一些 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点。奈纳尔获得最后的赏金是因为他提供了最大的帮助,而不是因为解决了问题。


请尝试一下,它正在调用 javascript 函数并显示 toast 消息。

public class Main3Activity extends AppCompatActivity {
     WebView webView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        webView = new WebView(getApplicationContext());
        webView.getSettings().setJavaScriptEnabled(true);

        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");
                webView.loadUrl("javascript:(function() { " +
                        "document.body.innerHTML = '<p>test<p>';" + "})()");
                webView.loadUrl("javascript: window.CallToAnAndroidFunction.setVisible()");



            }
        });
        webView.setVisibility(View.INVISIBLE);
        webView.addJavascriptInterface(new myJavaScriptInterface(), "CallToAnAndroidFunction");
        webView.loadUrl("https://example.com");
    }
    public class myJavaScriptInterface {
        @JavascriptInterface
        public void setVisible() {

            Handler handler = new Handler();
            Runnable runnable = new Runnable() {
                @Override
                public void run() {

                    Main3Activity.this.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            webView.setVisibility(View.VISIBLE);
                            Log.e("Testing", "no");
                            Toast.makeText(Main3Activity.this, "Reached JS", Toast.LENGTH_LONG).show();

                        }
                    });


                }
            };handler.postDelayed(runnable,2000);

        }}
}

它不会在 UI 中显示 webView,因为 webview 未在 xml 布局中定义。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 WebView 中注入 Javascript 桥 的相关文章

  • JavaScript:预期的赋值或函数调用,却看到了一个表达式

    我正在使用 JSHint 来确保我的 JavaScript 是 严格的 但我收到以下错误 预期是赋值或函数调用 但看到的是表达式 关于以下代码 var str A B C D var data var strArr str split fo
  • 无法在渲染器进程中使用 Node.js API

    无法在 Electron 中使用任何与 Electron 或节点相关的操作 未定义获取错误过程 我检查了他们指导添加节点支持的各个地方 但这已经完成了 所以卡在这里 我的主要应用程序代码是 const electron require el
  • 如何使用云打印打印Android活动显示

    我正在尝试将 Google 云打印实现到应用程序中 遵循集成指南 https developers google com cloud print docs android 我试图通过打印 google com 来保持基本 单击我创建的打印按
  • 如何将当前元素传递给 Knockout.js 绑定中的 Javascript 函数?

    因此 我尝试根据是否选中子复选框 使用 Knockout js 将类添加到元素 为此 我试图通过this作为我的函数的参数 目前 我的精简 DOM 结构如下 tr td td tr
  • 如何在NavigationView的菜单项中设置椭圆形?

    我想在 NavigationView 的菜单项中设置 android ellipsize end 在我当前的实现中 当菜单项中的文本太长时 它只是在末尾被剪切 这是我到目前为止所尝试过的
  • 从相机视图中拖动锁定在一定距离/半径处的对象

    我在场景中心有一个相机 距离相机 z 400 处有 1 个球体 其父级位于中心 我想从视图中向上 向下 向左 向右拖动球体 但同时不改变它相对于中心的 z 位置 我最终使用了另一个球体并使其不可见 添加side THREE DoubleSi
  • QML MouseArea 将事件传播到按钮

    我正在开发一个应用程序 其菜单类似于 Android 版 Gmail 收件箱应用程序菜单 基本上 当您按下按钮打开菜单时 它就会滑入视图 用户可以将其滑开或按菜单上的按钮 对于滑动我使用了代码SwipeArea from kovrov ht
  • HTML 和 JavaScript - 将滚动操作从一个元素传递到另一个元素

    假设我有两个 div div div div A scrollable list div 我想让它当光标停在里面时 control并且鼠标滚轮滚动 view将会滚动 无论如何要实现这一目标 好的 快速修复对我有用 即使固定 div 不可滚动
  • (0, eval) () 的作用是什么? [复制]

    这个问题在这里已经有答案了 以下内容来自这个问题 https stackoverflow com questions 14119988 return this 0 evalthis 14120023 14120023 function q
  • PhantomJS 网页内存消耗?

    是否有一种编程方式 因为我想在运行时自动执行 方式来查看网页在通过 PhantomJs 运行时使用了多少内存 我也在使用 casperjs 如果这有帮助的话 我已经搜索了很多但没有找到任何方法 PhantomJs 使用 QtWebKit 因
  • 从命令行运行 Maven 插件的语法是什么。

    我看到这里已经有人问过这个问题 如何从命令行执行maven插件 https stackoverflow com questions 12930656 how to execute maven plugin from command line
  • Google Cloud Messaging - 立即收到或长时间延迟收到的消息

    我在大学最后一年的项目中使用谷歌云消息传递 一切正常 但我在使用 GCM 时遇到了一些麻烦 通常 消息要么几乎立即传递 要么有很大的延迟 我读过这篇文章 但我真的认为它不适用于这种情况 GCM 通常会在消息发送后立即传送消息 然而 这并不总
  • Javascript:更改输入值时设置光标位置

    当您输入公式时 我试图在我的应用程序中重现类似于 Microsoft Excel Google Sheets 的用户体验 并且您可以使用不同的公式和变量来自动完成下拉菜单 为此 在验证自动完成功能后 我希望能够控制光标的位置 例如 如果我输
  • 如何使用 Jest 测试对象键和值的相等性?

    我有一个mapModule我在其中导入组件并导出它们 import ComponentName from components ComponentName export default name ComponentName 我该如何测试ma
  • 方法签名中带或不带synchronized关键字的方法具有相同的字节码

    对于以下 2 个类 获得相同的 Java 字节码 java版本 java 版本 1 8 0 181 Java TM SE 运行时环境 构建 1 8 0 181 b13 Java HotSpot TM 64 位服务器 VM 内部版本 25 1
  • JavaScript 中最长的通用前缀

    我正在尝试解决 Leet Code 挑战14 最长公共前缀 https leetcode com problems longest common prefix 编写一个函数来查找字符串数组中最长的公共前缀字符串 如果没有公共前缀 则返回空字
  • 数字和小数的输入掩码

    在测试我的程序后 我发现了以下错误 我在 sqlserver 中的表包含 价格数字 6 2 我的程序的用户输入价格 555 00 就很好了 但是当他输入 555555 时 这是错误的 所以我需要指定掩码 其中尾数是可选的 0 到 999 小
  • 如何从spark中的hbase表中获取所有数据

    我在 hbase 中有一个大表 名称为 UserAction 它具有三个列族 歌曲 专辑 歌手 我需要从 歌曲 列族中获取所有数据作为 JavaRDD 对象 我尝试了这段代码 但效率不高 有更好的解决方案来做到这一点吗 static Spa
  • Angular 2访问组件内的ng-内容

    我怎样才能访问 content 来自组件类本身的组件 我想做这样的事情
  • 如何检测用户是否禁用 GPS(Android - Play 服务)

    我使用 gms location LocationListener Google Play 服务 来获取用户的位置 它工作正常 但我想检测用户何时禁用或启用他 她的 GPS 就像这张照片一样 当我打开 关闭位置时 不会调用任何方法 当我切换

随机推荐

  • 如何查看 Realm ObjectId 是否等于 String (JavaScript)

    我正在使用 MongoDB 的 Realm 并尝试查看 ObjectId 是否等于具有相同字符的字符串 我尝试将 ObjectId 转换为字符串 反之亦然 但无论我尝试什么 它都不会将它们视为相等 即使这些值完全相同并且当我记录它们时它们看
  • 如何从 Tkinter 文本框中获取索引

    我希望能够从 Tkinter 文本框中突出显示的文本中获取索引 如 1 1 有什么想法吗 所选文本具有标签 sel 所选文本的开始和结束范围定义为 sel first and sel last 如果你想获取文本 可以直接使用它们 如下所示
  • Zurb Foundation 5 揭示模态不起作用

    我正在尝试使用 zurb Foundation 5 Reveal 模式 但当我单击按钮时它不起作用并且无法打开 我正在使用这个 html 代码
  • 在SQLAlchemy中获取相关模型

    我有各种模型链接在SQL炼金术 http en wikipedia org wiki SQLAlchemy 有很多 属于 等等 有没有办法找到给定实例的相关模型 就像是 usersModelInstance getRelatedTables
  • 在 SQL 中如何获得整数的最大值?

    我试图从 MySQL 数据库中找出整数 有符号或无符号 的最大值 有没有办法从数据库本身提取这些信息 是否有我可以使用的内置常量或函数 标准 SQL 或 MySQL 特定的 At http dev mysql com doc refman
  • 使用 linq 获取分组的逗号分隔值

    我想要第三列 项目 其中包含分组的值 var dic new Dictionary
  • 禁用 Angular 2 中的按钮

    我想如果输入 合同类型 为空 则 保存 按钮不可点击 保存按钮 div class col md 4 div
  • 没有生成缩略图

    我在我的项目中使用 Sonata Media Bundle 和 Symfony2 3 当我覆盖 YouTube 提供商时奏鸣曲 media provider youtube 一切工作正常 没有错误或任何其他内容 但在 Web uploads
  • Winforms——多选下拉列表

    我正在寻找一个允许我选择多个项目的下拉列表控件 类似于 CheckedListbox 但采用下拉列表形式 我不希望它占据屏幕的很大一部分 此时我非常确信 NET 中不存在这样的内置控件 请注意 这是 Winforms 而不是 ASP NET
  • 如何为 WIX 中的目录分配路径值?

    在我的 WIX 项目中 我有一个类似这样的目录结构
  • SQL Azure 和 READ_COMMITTED_SNAPSHOT

    我想在 SQL Azure 数据库上将 READ COMMITTED SNAPSHOT 设置为 ON 但 Azure 不支持以下适用于其他版本的 SQL Server 的代码 ALTER DATABASE database name SET
  • 放大 Google 地图数据层

    我在集中和缩放数据层中的信息时遇到问题 我尝试使用这里建议的方法 stackoverflow 问题 在 Google Maps API v3 中缩放至 geojson 多边形边界 https stackoverflow com questi
  • 获取给定日期时间集的每月第一个星期一

    我需要什么 我有一个特定的日期时间列表 我想获取每个日期时间的第一个星期一 例如 假设给定的日期时间是 2013 07 05 2013 08 05 2013 09 13 etc 我想获得所有这些日期时间的第一个星期一 以便输出结果 2013
  • Scala:为什么 Actor 是轻量级的?

    是什么让演员如此轻盈 我什至不确定它们是如何工作的 它们不是单独的线程吗 当他们说轻量级时 他们的意思是每个参与者都没有映射到单个线程 JVM 提供共享内存线程 锁作为主要形式 并发抽象 但分享了 内存线程是相当重量级的 并招致严重的绩效处
  • 如何加速 svm.predict?

    我正在编写一个滑动窗口来提取特征并将其输入到 CvSVM 的预测函数中 然而 我偶然发现 svm predict 函数相对较慢 基本上 窗口以固定的步幅长度在图像比例上滑动穿过图像 遍历图像加上提取每个图像特征的速度 窗口大约需要 1000
  • 从哪里开始使用适用于 Retina 显示屏的 OpenGL 绘制程序

    我知道由于这里提到的错误 我无法将 GLPainter 示例从苹果适应到视网膜 在 Retina iPad 上显示全屏 CAEAGLLayer 时出现问题 https stackoverflow com questions 9757052
  • Swift 结构类型集

    说我有一个struct 可以是任何东西 struct Cube var x Int var y Int var z Int var width Int 然后我该如何创建一个Set这些点中 是否存在两个具有相同属性的对象 let points
  • iOS SecItemCopyMatching RSA 公钥格式?

    我正在尝试从已生成的密钥对 两个SecKeyRefs 以便通过线路发送 我所需要的只是一个简单的 modulus exponent 对 它应该正好占用 131 个字节 模数为 128 指数为 3 但是 当我获取关键信息时NSData对象 我
  • 如何在 htaccess 中创建永久链接

    我想将链接重定向到 Linux 主机中具有 htaccess 文件的另一个链接 你能帮助我吗 from http example com examp to http example com examp php 还有我的另一个网站的另一个 f
  • 在 WebView 中注入 Javascript 桥

    我想从 Android 网页中提取一些内容 我知道有一些库可以解析 HTML 但我想也许我可以稍微作弊一下 这就是我正在做的 使用应用程序上下文以编程方式创建 WebView 因此不必在 UI 中显示它 加载网页 附上JS接口 注入一些 J