Android与H5交互 -- 点击H5跳转到 Android原生 页面 ,webview与h5(js)交互

2023-11-13

Android与H5交互

app开发过程中,利用原生+h5模式来开发是比较常见的
下面案例演示的是:原生调起一个H5页面,然后H5点击跳转到原生

WebViewActivity页面 调用H5 ,点击H5链接 跳转到原生MainActivity页面

注意 别忘了 <!-- 添加网络权限 -->

<uses-permission android:name="android.permission.INTERNET" />
一、清单文件,增加的配置
  • data的数据就是H5 A标签 href=“#”填写的链接地址: android://h5/open
    在这里插入图片描述
二、在你需要跳转的页面,清单文件中加入如下配置:
<activity android:name=".MainActivity" android:exported="true">
            <!-- h5跳转app -->
            <!-- 需要添加下面的intent-filter配置 -->
            <intent-filter>
                <!-- 通过一个应用来显示数据 -->
                <action android:name="android.intent.action.VIEW" />
                <!-- 默认值,没有该默认值则无法响应隐式意图 -->
                <category android:name="android.intent.category.DEFAULT" />
                <!-- 该组件可以通过浏览器打开 -->
                <category android:name="android.intent.category.BROWSABLE" />
                <!-- android:scheme="android"    用来辨别启动的app -->
                <!-- android:host="h5"           可以当成是一个域名,这边建议使用应用的包名 -->
                <!-- android:pathPrefix="/open"  参数路径前缀 -->
                <data
                    android:host="h5"
                    android:pathPrefix="/open"
                    android:scheme="android" /><!-- android://h5/open -->
            </intent-filter>
        </activity>
三、整体结构布局如下 :
四、贴一下html里面的代码吧
  • ceshi.html
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>测试</title>
	</head>
	<body>
		<a href="android://h5/open?type=5&id=2" style="font-size: 55px;">点击事件1</a>
		<br />
		<br />
		<a href="file:///android_asset/cs.html" style="font-size: 55px;">点击事件2</a>
		<br />
		<br />
	</body>
</html>
  • cs.html
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>测试</title>
	</head>
	<body>
		<br />
		<a href="file:///android_asset/ceshi.html" style="font-size: 55px;" >点击事件2</a>
		<br />
	</body>
</html>
五、具体实现如下:
  • activity_web_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".WebViewActivity">
    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</RelativeLayout>
  • WebViewActivity页面的处理

调用的是本地H5(html)路径

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class WebViewActivity extends AppCompatActivity {
    private WebView webView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view);
        initwebView();//初始化webview
    }

    @SuppressLint("JavascriptInterface")
    private void initwebView() {
        webView = (WebView) findViewById(R.id.webView);
        WebSettings webSettings = webView.getSettings();
        webSettings.setDomStorageEnabled(true);
        //设置WebView属性,能够执行Javascript脚本
        webSettings.setJavaScriptEnabled(true);
        //设置可以访问文件
        webSettings.setAllowFileAccess(true);
        //设置Web视图
        webView.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                //返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器
                WebView.HitTestResult hit = view.getHitTestResult();
                //hit.getExtra()为null或者hit.getType() == 0都表示即将加载的URL会发生重定向,需要做拦截处理
                if (TextUtils.isEmpty(hit.getExtra()) || hit.getType() == 0) {
                    //通过判断开头协议就可解决大部分重定向问题了,有另外的需求可以在此判断下操作
                    Log.e("重定向", "重定向: " + hit.getType() + " && EXTRA()" + hit.getExtra() + "------");
                    Log.e("重定向", "GetURL: " + view.getUrl() + "\n" + "getOriginalUrl()" + view.getOriginalUrl());
                    Log.d("重定向", "URL: " + url);
                }
                if (url.startsWith("http://") || url.startsWith("https://")) { //加载的url是http/https协议地址
                    view.loadUrl(url);
                    return false; //返回false表示此url默认由系统处理,url未加载完成,会继续往下走

                } else { //加载的url是自定义协议地址
                    try {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        if (intent.resolveActivity(WebViewActivity.this.getPackageManager())!=null){
                            startActivity(intent);
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return true;
                }
            }
            //开始加载网络
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                Log.e("加载中",url);
            }
            //网页加载完成回调
            @SuppressLint("NewApi")
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                Log.e("加载完成",url);
            }
        });
        // 调用本地H5页面的方法
        webView.loadUrl("file:///android_asset/ceshi.html");
    }
}

以上是运行跳转成功,下面是拿到跳转的参数

  • MainActivity
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = getIntent();
        Log.d("test123",""+intent);
        String action = intent.getAction();
        if (Intent.ACTION_VIEW.equals(action)) { //判断是否是我们指定的 action
            Uri uri = intent.getData(); //将String类型的URL转变为URI
            if (uri != null) {
                String type = uri.getQueryParameter("type"); //获取参数
                String id = uri.getQueryParameter("id");
                Log.d("uri", "" + uri);
                Log.d("type", "" + type);
                Log.d("id", "" + id);
            }
        }
    }
}
  • 跳转第二个页面后,获取的参数打印如下:
    在这里插入图片描述

Android webview调用JS方法

  • Android写一个触发事件(button),调用AndroidJsCall();
    resule是传递的参数
    @SuppressLint("SetJavaScriptEnabled")
    public void AndroidJsCall()
    {
        webView.loadUrl("javascript:toAndroidCall('"+resule+"')");
    }
  • h5(vue)中写一个方法
  • html如下:
 function toAndroidCall(message){
			console.log("Android中调用JS方法成功,做处理---------------"+message);
        }

在这里插入图片描述

  • vue如下:
mounted() {
    //将要给原生调用的方法挂载到 window 上面
    window.callJsFunction = this.callJsFunction
},
methods: {
    callJsFunction(message) {
        console.log("Android中调用JS方法成功,做处理---------------"+message);
    }
}

JS中调用Android webview方法

  • 1、webView进行配置
        //增加JS接口
        webView.addJavascriptInterface(this,"ceshi");
  • 2、Android中实现方法
    //JS调用Android方法
    @JavascriptInterface
    public String jsCallAndroid(){
        Toast.makeText(this,"JS调用Android方法成功",Toast.LENGTH_LONG).show();
        return result;
    }

如果要传参数

    //JS调用Android方法-带参数
    @JavascriptInterface
    public String jsCallAndroid(int type){
        Toast.makeText(this,"JS调用Android方法成功,type----"+type,Toast.LENGTH_LONG).show();
        return result;
    }
  • 3、在JS中新增一个按钮
<button id="button" onclick="toCallAndroid()">JS调用Android方法</button>
  • 4、设置点击事件
        //JS中调用Android方法
        function toCallAndroid()
        {
            ceshi.jsCallAndroid();
        }

在这里插入图片描述

安卓响应前端选择文件照片 input type=“file“

不响应: H5 访问本地文件的时候,使用的 ,WebView 出于安全性的考虑,限制了以上操作。
解决实现:webview 中重写方法响应 WebviewChromeClient 。

  • 4.1以上系统,使用 openFileChooser() ,该方法5.0已经被废弃
  • 5.0以上系统,使用 onShowFileChooser()
	private ValueCallback<Uri[]> uploadMessageAboveL;
	private ValueCallback<Uri[]> uploadMessage;
    //用于保存拍照图片的uri
    private Uri mCameraUri;
    private static final int CAMERA_REQUEST_CODE = 10010;//相机标识符
    private static final int ACTION_CHOOSE_IMAGE = 0x201;//相册标识符


webView.setWebChromeClient(new WebChromeClient(){
			//Android  >= 5.0
            @Override
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
                uploadMessageAboveL = filePathCallback;
                //调用系统相机或者相册
                uploadPicture();
                return true;
            }
            //For Android  >= 4.1
            public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture)
               uploadMessage = filePathCallback;
                //调用系统相机或者相册
                uploadPicture();
            }
        });
  • 我这里是给个弹框选择 拍照 还是 调用系统相册
    在这里插入图片描述
	 private static String[] items = new String[]{
            "拍照",
            "从相册中选择",
            "取消",
    };
    private void uploadPicture() {
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setTitle("请选择图片");
        builder.setItems(items, new DialogInterface.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (which == 0) {
                    checkPermissionAndCamera();
                } else if (which == 2) {
                    if (uploadMessageAboveL != null) {
                        uploadMessageAboveL.onReceiveValue(null);
                        uploadMessageAboveL = null;
                    }
                    if (uploadMessage != null) {
                        uploadMessage .onReceiveValue(null);
                        uploadMessage = null;
                    }
                    builder.create().dismiss();
                } else {
                    Intent intent = new Intent(Intent.ACTION_PICK);
                    intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                    startActivityForResult(intent, ACTION_CHOOSE_IMAGE);
                }
                return;
            }
        });//设置对话框 标题
        builder.create()
                .show();
    }
 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.e("TAG", "resultCode:==="+resultCode);
        if (resultCode != RESULT_OK) {
            //取消拍照或者图片选择时,返回null,否则<input file> 再次点击无效果就是没有反应
            if (uploadMessageAboveL != null) {
                uploadMessageAboveL.onReceiveValue(null);
                uploadMessageAboveL = null;

            }
            if (uploadMessage != null) {
                uploadMessage .onReceiveValue(null);
                uploadMessage = null;
             }
        }
        //相机返回
        if (requestCode == CAMERA_REQUEST_CODE) {
            if (uploadMessageAboveL != null) {
                uploadMessageAboveL.onReceiveValue(new Uri[]{mCameraUri});
                uploadMessageAboveL = null;
            }
            if (uploadMessage != null) {
                uploadMessage.onReceiveValue(mCameraUri);
                uploadMessage = null;
            }
        }
         //相册返回
        if (requestCode == ACTION_CHOOSE_IMAGE) {
            if (data == null || data.getData() == null) {
                if (uploadMessageAboveL != null) {
                    uploadMessageAboveL.onReceiveValue(null);
                    uploadMessageAboveL = null;
                }
           	   if (uploadMessage != null) {
              	  uploadMessage .onReceiveValue(null);
              	  uploadMessage = null;
            	 }
                return;
            }
            if (uploadMessageAboveL != null) {
                uploadMessageAboveL.onReceiveValue(new Uri[]{data.getData()});
                uploadMessageAboveL = null;
            }
            if (uploadMessage!= null) {
                uploadMessage.onReceiveValue(data.getData());
                uploadMessage= null;
            }
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android与H5交互 -- 点击H5跳转到 Android原生 页面 ,webview与h5(js)交互 的相关文章

  • Android进阶之光:Dagger2原理简要分析

    Dagger2注入框架原理简要分析 使用Dagger2需要的依赖 implementation com google dagger dagger android 2 46 implementation com google dagger d
  • Android Studio解决gradle时下载资源过慢问题

    替换镜像下载方式 打开Android Studio项目中的build gradle文件 找到以下位置 修改jcenter地址为 https maven aliyun com repository jcenter 示例 buildscript
  • AndroidStudio链接手机的步骤

    1 设置手机为开发者模式 设置 gt 关于手机 gt 连续点击MIUI版本 开启成功 2 在更多设置中选择开发者选项 在开发者选项中同时勾选USB调试和USB安装的开关 3 数据线与电脑连接 4 打开AndroidStudio 等待程序加载
  • UNI APP---Android端原生插件开发实战(一)

    1 前言 最近一个项目要求我们的产品必须走网络隧道 并且提供了对应的SDK 很明显只能通过原生开发的方式才能实现这个流程 笔者没有做过原生开发 也没有学过java 所以也踩了不少坑啊 花了两天时间总算完成任务 今天系统的总结下步骤 由于是根
  • Android Studio 从安装到第一个Android 应用Demo

    安装Android Studio 安装需要 上网 我这挺顺利的 就是在官网下载安装包 一路 Next 大概连下载总共半个小时 第一个应用 参考官方教程 https developer android com codelabs basic a
  • 安装或更新 Android Studio

    在开始用 Jetpack Compose 来编写软件之前 我们需要 1 一台可以联网的电脑 2 安装或更新到 最新版的 Android Studio 3 选择创建 Empty Compose Activity 4 保持版本更新 尝试使用最新
  • Android进阶宝典 -- 手写RecyclerView分页组件

    在Android应用中 列表有着举足轻重的地位 几乎所有的应用都有列表的身影 但是对于列表的交互体验一直是一个大问题 在性能比较好的设备上 列表滑动几乎看不出任何卡顿 但是放在低端机上 卡顿会比较明显 而且列表中经常会伴随图片的加载 卡顿会
  • Manifest合并失败几种原因以及解决方法

    今天遇到了一个报错 Error Execution failed for task app processDebugManifest gt Manifest merger failed with multiple errors see lo
  • Adroid游戏开发实例讲解(四)-电子白板附源码

    Adroid游戏开发实例讲解 四 电子白板附源码 程序之美 电子白板 在很多Android设备中经常会用到 比如说Android电视 触摸屏用上手写笔 轻松在上面写字 比如视频教学Android设备 有很多培训教学机构 都放有Android
  • Linux下Android Studio的安装步骤及关键点【整理】

    2013年google公司发布了一个新的Android集成开发环境 Android Studio 它为Android开发者提供了更多便利 而google慢慢地已经把重心放到Android Studio的开发上了 所以对于Android工程师
  • 解决报错:Errorjava.lang.NullPointerException(no error message)

    解决报错 Error java lang NullPointerException no error message 一 分析原因 Android Studio经常出现dependencies或者configuing相关错误 这类错误出现的
  • 48、Flutter之widgets LayoutBuilder组件

    LayoutBuilder 通过 LayoutBuilder 我们可以在布局过程中拿到父组件传递的约束信息 然后我们可以根据约束信息动态的构建不同的布局 比如我们实现一个响应式的 Column 组件 ResponsiveColumn 它的功
  • Android studio 模拟器启动黑屏解决办法附图详细

    Android studio 模拟器启动黑屏解决办法附图详细 问题描述 原因分析 android模拟器在创建时 一般默认设置为热启动 所以每次关闭模拟器时 会提示保存当前运行界面状态 若选择取消 则下一次启动会以最近一次保存的状态启动显示
  • AS配置NDK开发环境,附CMake、NDK-build构建工具用法

    注意 Android Studio需要是1 3及以上版本 且版本号小于2 2 见文末说明 步骤1 新建一个项目 打开Project Structure 设置Android NDK Location目录 如果没有提前下载NDK包 可打开SDK
  • 《0基础学安卓逆向》第1集:什么是安卓逆向及环境搭建

    1 安卓逆向是什么 安卓逆向是什么 目前百度知道都没有收录安卓逆向这个词条 大部分能搜索到的资料都是技术人员写的偏技术类的文章 往往充斥着代码和各类工具集合 非技术人员一看就比较懵逼 简单地来说 安卓逆向是对已经打包好的APP进行反编译 源
  • 使用NDK编译C/C++文件生成在安卓中的可执行文件

    使用NDK编译C C 文件生成在安卓中的可执行文件 需求 要编译一个C文件 然后将他运行到安卓手机中 通过这个可执行文件可以获取一些硬件的参数信息 或者对已经有的信息进行修改 从而达到我们想要的效果 相关知识点记录 NDK Native D
  • android sdk自带的fragment标签使用

    项目开发中要用到 下面四个大分类 上面三个小分类的情况 大分类采用viewPage 小分类 使用了sdk自带的
  • Android Studio 中模拟器无法打开,提示Error launching emulator

    一 遇到的问题 运行模拟器时 提示 Error launching emulator 二 解决方法 打开SDK Manager 点击取消Android Emulator 然后重新运行 会提示下载一些文件 按着操作即可 如果没问题就不需要取消
  • 【Android Studio 创建module】

    一 如何创建模型 一个项目里边可以有多个module 每个module对应的都是一个独立的程序 选择File菜单 gt New gt New Module gt 填写Module名称 library 一直next直到finish 给Modu
  • Cannot locate tasks that match ‘:shared:testClasses‘ as task ‘testClasses‘ not found in project

    问题 在使用Gradle构建项目时 遇见了一个奇怪的问题 运行报错如下 Cannot locate tasks that match shared testClasses as task testClasses not found in p

随机推荐

  • Git入门与使用 (二) Git相关命令的介绍与使用

    文章目录 一 前言 二 理解Git的工作区 暂存区 本地仓库和远程仓库 三 Git相关命令的介绍与使用 1 初始化Git仓库 2 设置签名 2 1 设置仓库 项目级别的签名 2 2 设置系统用户级别的签名 3 查看Git仓库的状态 4 向暂
  • [转]Windows下安全权限设置详解

    一 Windows下安全权限设置详解 简 介 随着动网论坛的广泛应用和动网上传漏洞的被发现以及SQL注入式攻击越来越多的被使用 WEBSHELL让防火墙形同虚设 一台即使打了所有微软补丁 只让80端口对外开放的WEB服务器也逃不过被黑的命运
  • 刷脸庞大的交易市场从而也带来新的商机

    现在我们外出买东西付款 已经有了非常便捷的扫码支付功能 这个功能不仅是年轻人喜欢使用 就连中老年人也跟上的时代的步伐 许多超市 便利店已经菜市场 都能够看到二维码的身影 但是随着时代不断地进步 扫码付款这一新兴方式 接二连三地被曝出许多风险
  • Unity自动滚动字幕的实现

    Unity自动滚动字幕的实现 首先按照图片里的进行创建 然后用代码获取Scrollbar 在将Value值一直变为1 using System Collections using System Collections Generic usi
  • Jupyter程序安装和使用指南【操作示例】

    Jupyter Notebook 简称Jupyter 是一个交互式编辑器 它支持运行40多种编程语言 便于创建和共享文档 Jupyter本质上是一个Web应用程序 与其他编辑器相比 它具有小巧 灵活 支持实时代码 方便图表展示等优点 下面分
  • ECCV 2020 Representation Learning on Visual-Symbolic Graphs for Video Understanding

    动机 自然视频中的事件通常产生于演员和目标之间的时空交互 并且涉及多个共同发生的活动和目标类 因此 需要开发能够对时空视觉和语义上下文进行有效建模的算法 捕捉这种上下文的一种方法是使用基于图的建模 它在计算机视觉中有着丰富的历史 传统的基于
  • qt day3

  • java自动装配_Spring中自动装配的4种方式

    Spring容器可以在不使用和元素的情况下自动装配相互协作的bean之间的关系 助于减少编写一个大的基于Spring的应用程序的XML配置的数量使用元素的autowire属性为一个bean定义指定自动装配模式 在Spring中 我们有4种方
  • 计算机网络期末总结复习(全)

    文章目录 第一章 概述 1 1 计算机网络在信息时代的作用 我国互联网发展状况 1 2 因特网概述 1 网络 互连网 互联网 和因特网 2 因特网发展的三个阶段 3 因特网的标准化工作 4 因特网的组成 补充
  • 78页PPT全面揭示互联网与传统行业的融合与碰撞

    正如报告的主题 融合与碰撞 移动互联网和传统行业正在融合与碰撞之间进行行业重塑 纵观教育行业 现阶段已经有四种运营模式逐渐成熟 但仍存在自身问题和很多外部矛盾 找准发展趋势意义重大 一起来看看水深火热的TMT产业发展趋势吧
  • 【前端demo】背景渐变动画

    文章目录 效果 过程 代码 html css 其他demo 效果 效果预览 https codepen io karshey pen OJrXZwQ 过程 注意 直接在body上加height 100 可能也会出现height为0的情况 这
  • docker修改服务器参数怎么办,Docker(32)- 如何修改 docker 容器的启动参数

    如果你还想从头学起 Docker 可以看看这个系列的文章哦 前言 有时候创建容器时忘了添加 restart 参数 导致 Docker 服务重启后 容器不会自动启动 每次都需要手动启动 很不方便 那现在如何针对已创建的容器修改 restart
  • LeetCode——动态规划篇(二)

    刷题顺序及思路来源于代码随想录 网站地址 https programmercarl com 目录 343 整数拆分 力扣 LeetCode 96 不同的二叉搜索树 力扣 LeetCode 416 分割等和子集 力扣 LeetCode 104
  • Java 自定义FTP连接池

    一 引入FTP包和连接池包
  • hadoop: Operation category READ is not supported in state standby

    1 背景 做kylin报错如下 日志内容如下 java io IOException OS command error exit with return code 1 error message Java HotSpot TM 64 Bit
  • Java8新特性之stream流常用操作(简易使用版)

    概念 什么是Stream流 优点一 代码更加简洁 stream操作配合Lambda表达式 加上自身提供了很多方法 操作集合代码更加简洁 优点二 性能方面 for循环是比较底层的操作 所以它的性能明显是比stream流的迭代器更加高的 但是s
  • python可以做回归分析吗_使用python进行回归分析

    一 概述 1 回归 利用样本 已知数据 产生拟合方程 从而对未知数据进行预测 2 分类线性回归 一元线性 多元线性 逻辑回归 实际上预测的是数据X属于分类Y的概率p 逻辑回归公式由 log p 1 p 0 1X 推导求得 非线性回归 3 求
  • SourceInght And Sublime Text 2 Using Skills

    工欲善其事 必先利其器 Sourceinsight 加入时间 http my oschina net xDreamYY blog 228814 Sourceinsight 加入快捷键 http www cnblogs com wangqig
  • 【Matlab启动报错】无法打开桌面:java.lang.NullPointerException

    今天兴致勃勃地准备跑跑simulink的时候发现matlab 打不开了 因为以后的研究方向几乎不用matlab 所以几个月没碰它了 上网查了有可能是兼容性的问题 但是改成了Vista发现并没有什么用 我接着在网上找到了可能是字体等windo
  • Android与H5交互 -- 点击H5跳转到 Android原生 页面 ,webview与h5(js)交互

    目录标题 Android与H5交互 一 清单文件 增加的配置 二 在你需要跳转的页面 清单文件中加入如下配置 三 整体结构布局如下 四 贴一下html里面的代码吧 五 具体实现如下 Android webview调用JS方法 JS中调用An