Android H5调起微信支付宝支付

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><queries><package android:name="com.tencent.mm"/><package android:name="com.eg.android.AlipayGphone"/></queries><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><applicationandroid:name=".MyApplication"android:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:networkSecurityConfig="@xml/network_security_config"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"android:usesCleartextTraffic="true"tools:targetApi="31"><meta-dataandroid:name="UMENG_CHANNEL"android:value="${UMENG_CHANNEL_VALUE}" /><activityandroid:name=".SplashActivity"android:label="智商测试趣测MBTI"android:exported="true"android:theme="@style/Theme.AppCompat.Light.NoActionBar"android:launchMode="singleTask"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activity android:name=".MainActivity" /><activity android:name=".splash.PrivacyWebActivity"/></application></manifest>

添加的是

    <queries><package android:name="com.tencent.mm"/><package android:name="com.eg.android.AlipayGphone"/></queries>

webview如下

package com.zs.test.fragment;import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
//import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
//import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;import com.just.agentweb.AgentWeb;
import com.just.agentweb.WebChromeClient;
import com.just.agentweb.WebViewClient;
import com.zs.test.R;
import com.zs.test.util.DeviceUtil;
import com.zs.test.util.PackageUtil;
import com.zs.test.util.SharedPreferencesUtils;import org.json.JSONException;
import org.json.JSONObject;import java.util.HashMap;
import java.util.Map;public class WebViewFragment2 extends Fragment {private WebView myWebView;private TextView statusBarText;private ImageButton btnBack;private String channel;private String packageName;private String osVersion;private String osType = "Android";private String brand;private String model;private String appVersion;private String appName = "cstest";private String deviceToken;private String deviceId;private String url;public static WebViewFragment2 newInstance(String url, String title, boolean showBack) {WebViewFragment2 fragment = new WebViewFragment2();Bundle args = new Bundle();args.putString("url", url);args.putString("title", title);args.putBoolean("showBack", showBack);fragment.setArguments(args);return fragment;}private WebChromeClient mWebChromeClient  = new WebChromeClient() {/*override fun onProgressChanged(view: WebView?, newProgress: Int) {}*/};private WebViewClient mWebViewClient = new  WebViewClient() {@Overridepublic void onPageStarted(WebView view, String url, Bitmap favicon) {super.onPageStarted(view, url, favicon);}@Overridepublic void onPageFinished(WebView view, String url) {super.onPageFinished(view, url);}@Nullable@Overridepublic WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {return super.shouldInterceptRequest(view, request);}@Overridepublic boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {Uri uri = request.getUrl();String scheme = uri.getScheme();// 检查自定义协议if (!scheme.equals("http") && !scheme.equals("https")) {try {Intent intent = new Intent(Intent.ACTION_VIEW, uri);if (intent.resolveActivity(getContext().getPackageManager()) != null) {startActivity(intent);} else {Log.e("WebViewFragment", "无法处理的自定义协议: " + scheme);}} catch (Exception e) {Log.e("WebViewFragment", "处理自定义协议时发生错误: " + e.getMessage());}return true; // 拦截自定义协议,不交给 WebView 处理}return false; // 对于普通 HTTP 或 HTTPS 链接,让 WebView 自行加载}@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {// 对于旧版 Android (API < 21),应该使用这个重载方法Uri uri = Uri.parse(url);String scheme = uri.getScheme();// 如果是 HTTP 或 HTTPS 协议,WebView 继续加载if (scheme.equals("http") || scheme.equals("https")) {return false;}// 处理自定义协议(如 weixin://)try {Intent intent = new Intent(Intent.ACTION_VIEW, uri);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);// 通过 Intent 打开相应的 App(微信等)if (intent.resolveActivity(getContext().getPackageManager()) != null) {startActivity(intent);} else {Log.e("WebView", "无法处理的自定义协议: " + scheme);}} catch (Exception e) {e.printStackTrace();Log.e("WebView", "处理自定义协议时发生错误: " + e.getMessage());}return true; // 拦截这个 URL,不让 WebView 继续加载}/*override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {//showLoadingDialog()}override fun onPageFinished(view: WebView?, url: String?) {super.onPageFinished(view, url)//hideLoadingDialog()if(view==null) returnif(view==null) returnif(mTitle.isBlank() && !url.isNullOrBlank()){mHbvTitle.setTitle(view!!.title?:"")}}override fun shouldInterceptRequest(view: WebView?,request: WebResourceRequest?): WebResourceResponse? {if(request!=null){}return super.shouldInterceptRequest(view, request)}override fun shouldOverrideUrlLoading(view: WebView?,request: WebResourceRequest?): Boolean {return super.shouldOverrideUrlLoading(view, request)}*/};@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {View rootView = inflater.inflate(R.layout.fragment_webview, container, false);statusBarText = rootView.findViewById(R.id.statusBarText);btnBack = rootView.findViewById(R.id.btnBack);//myWebView = rootView.findViewById(R.id.webview);FrameLayout fl = (FrameLayout) rootView.findViewById(R.id.fl);AgentWeb mAgentWeb = AgentWeb.with(this).setAgentWebParent(fl, new LinearLayout.LayoutParams(-1, -1)).closeIndicator().setWebChromeClient(mWebChromeClient).setWebViewClient(mWebViewClient).createAgentWeb().ready().go(url);myWebView = mAgentWeb.getWebCreator().getWebView();WebSettings setting = myWebView.getSettings();setting.setJavaScriptEnabled(true);setting.setJavaScriptCanOpenWindowsAutomatically(true);if (getArguments() != null) {url = getArguments().getString("url");Log.d("urlds",url);String title = getArguments().getString("title");statusBarText.setText(title);boolean showBack = getArguments().getBoolean("showBack");if (showBack) {getActivity().runOnUiThread(() -> btnBack.setVisibility(View.VISIBLE));}}// 设置返回按钮的点击事件btnBack.setOnClickListener(v -> {if (myWebView.canGoBack()) {myWebView.goBack(); // 如果 WebView 可以返回,执行 WebView 的返回操作} else {getActivity().onBackPressed(); // 否则执行默认的返回操作}});// 设置沉浸式状态栏if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {getActivity().getWindow().setStatusBarColor(Color.TRANSPARENT);getActivity().getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);}// 初始化SharedPreferencesUtils,用于获取设备TokenSharedPreferencesUtils prefs = SharedPreferencesUtils.getInstance(getContext());deviceToken = prefs.getString(SharedPreferencesUtils.DEVICE_TOKEN, "");// 获取应用相关信息packageName = getActivity().getPackageName();osVersion = Build.VERSION.RELEASE;brand = Build.BRAND;model = Build.MODEL;appVersion = DeviceUtil.getAppVersion(getContext());deviceId = DeviceUtil.getDeviceUniqueId(getContext());// 获取渠道信息channel = PackageUtil.getUmengChannelName(getContext());// 启用 JavaScriptmyWebView.getSettings().setJavaScriptEnabled(true);// 设置支持弹出新窗口myWebView.getSettings().setSupportMultipleWindows(true);// 加载拼接后的URLmyWebView.loadUrl(url);// 设置 WebViewClient,处理页面加载过程中的事件
//        myWebView.setWebViewClient(new WebViewClient() {
//            @Override
//            public void onPageStarted(WebView view, String url, android.graphics.Bitmap favicon) {
//                super.onPageStarted(view, url, favicon);
//            }
//
//            @Override
//            public void onPageFinished(WebView view, String url) {
//                super.onPageFinished(view, url);
//            }
//
//            @Override
//            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
//                return super.shouldOverrideUrlLoading(view, request);
//            }
//        });// 设置 WebChromeClient,处理进度条等操作myWebView.setWebChromeClient(new WebChromeClient() {@Overridepublic void onProgressChanged(WebView view, int newProgress) {super.onProgressChanged(view, newProgress);}});// 请求头设置Map<String, String> headers = new HashMap<>();
//        headers.put("channel", channel);
//        headers.put("packagename", packageName);
//        headers.put("device-system", osVersion);
//        headers.put("device-platform", osType);
//        headers.put("device-brand", brand);
//        headers.put("device-model", model);
//        headers.put("host-version", appVersion);
//        headers.put("host-app-name", appName);
//        headers.put("device-id", deviceId);
//        headers.put("device-Token", deviceToken);//        // 拼接URL并打印
//        StringBuilder urlWithParams = new StringBuilder(url);
//        urlWithParams.append("?deviceSystem=").append(osVersion)
//                .append("&devicePlatform=").append(osType)
//                .append("&deviceBrand=").append(brand)
//                .append("&deviceModel=").append(model)
//                .append("&version=").append(appVersion)
//                .append("&loginInfoRet=").append("arg");//        Log.d("FinalUrl", "Final URL: " + urlWithParams.toString());myWebView.addJavascriptInterface(new Object() {@JavascriptInterfacepublic void showHeaderBarBackIcon(boolean show) {if (show) {getActivity().runOnUiThread(() -> btnBack.setVisibility(View.VISIBLE));} else {getActivity().runOnUiThread(() -> btnBack.setVisibility(View.GONE));}}@JavascriptInterfacepublic void setHeaderBarBackGroundColor(String color) {Log.d("js回调", "状态栏颜色" + color);getActivity().runOnUiThread(() -> getView().findViewById(R.id.statusBar).setBackgroundColor(Color.parseColor(color)));}@JavascriptInterfacepublic void setHeaderBarStyle(boolean isBlack) {Log.d("js回调", "字体颜色" + isBlack);getActivity().runOnUiThread(() -> {if (isBlack) {statusBarText.setTextColor(Color.BLACK);btnBack.setImageResource(R.drawable.ic_back_black);} else {statusBarText.setTextColor(Color.WHITE);btnBack.setImageResource(R.drawable.ic_back_white);}});}@JavascriptInterfacepublic void getLoginInfo() {Log.d("js回调", "开始调登陆");loginInfoRet(channel);}@JavascriptInterfacepublic void openLink(String uriStr) {try {Uri uri = Uri.parse(uriStr);Intent intent = new Intent(Intent.ACTION_VIEW, uri);startActivity(intent);} catch (Exception e) {e.printStackTrace();}}private void loginInfoRet(String channel) {runOnMainThread(() -> {try {JSONObject jsonObject = new JSONObject();jsonObject.put("packageName", packageName);jsonObject.put("channel", channel);jsonObject.put("version", appVersion);jsonObject.put("token", deviceToken);jsonObject.put("devicePlatform", "android");jsonObject.put("deviceSystem", Build.VERSION.RELEASE);jsonObject.put("deviceBrand", Build.BRAND);jsonObject.put("deviceModel", Build.MODEL);jsonObject.put("deviceId", deviceId);String str = jsonObject.toString();String jsCode = "javascript:loginInfoRet(" + str + ");";Log.d("JS Code", "Executing: " + jsCode);if (myWebView != null) {myWebView.evaluateJavascript("javascript:loginInfoRet" + str + ");", new ValueCallback<String>() {@Overridepublic void onReceiveValue(String value) {Log.d("JS Result", "Result from JS: " + value);}});}} catch (JSONException e) {e.printStackTrace();}});}}, "Android");return rootView;}@Overridepublic void onDetach() {super.onDetach();if (myWebView != null) {myWebView.destroy();}}public void runOnMainThread(Runnable block) {new Handler(Looper.getMainLooper()).post(block);}
}

MainActivity

package com.zs.test;import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentTransaction;import com.zs.test.common.Global;
import com.zs.test.fragment.WebViewFragment;
import com.zs.test.fragment.WebViewFragment2;
import com.zs.test.util.SharedPreferencesUtils;public class MainActivity extends AppCompatActivity {private boolean isBackPressedOnce = false; // 标志用户是否已经按过一次返回键private final Handler handler = new Handler(Looper.getMainLooper()); // 用于延时清除标志@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);SharedPreferencesUtils preferencesUtils = SharedPreferencesUtils.getInstance(this);String mainWebUrl = preferencesUtils.getString(SharedPreferencesUtils.MAIN_WEB_URL,"");// 启动 WebViewFragmentif (savedInstanceState == null) {WebViewFragment2 webViewFragment = WebViewFragment2.newInstance(mainWebUrl, "智商测试",false);FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();transaction.replace(R.id.fragment_container, webViewFragment);transaction.commit();}}@Overridepublic void onBackPressed() {if (isBackPressedOnce) {// 第二次按返回键,退出应用super.onBackPressed();finishAffinity(); // 结束所有活动,退出应用System.exit(0); // 彻底退出进程} else {// 第一次按返回键,提示用户isBackPressedOnce = true;Toast.makeText(this, "再按一次返回键退出程序", Toast.LENGTH_SHORT).show();// 延时2秒后重置标志handler.postDelayed(() -> isBackPressedOnce = false, 2000);}}@Overrideprotected void onDestroy() {super.onDestroy();// 清除所有回调,避免内存泄漏handler.removeCallbacksAndMessages(null);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/36375.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【C语言】C语言的变量和声明系统性讲解

声明和定义的概念 在C语言中&#xff0c;**声明&#xff08;Declaration&#xff09;和定义&#xff08;Definition&#xff09;**是两个重要的基础概念&#xff0c;它们都涉及到变量、函数、结构体等的使用&#xff0c;但功能和作用存在明显区别&#xff1a; 声明&#xff1a…

【Linux】文件的内核级缓冲区、重定向、用户级缓冲区(详解)

一.文件内核级缓冲区 在一个struct file内部还要有一个数据结构-----文件的内核级缓冲区 打开文件&#xff0c;为我们创建struct file&#xff0c;与该文件的所对应的操作表函数指针集合&#xff0c;还要提供一个文件的内核级缓冲区 1.write写入具体操作 当我们去对一个文件写…

MCU、ARM体系结构,单片机基础,单片机操作

计算机基础 计算机的组成 输入设备、输出设备、存储器、运算器、控制器 输入设备&#xff1a;将其他信号转换为计算机可以识别的信号&#xff08;电信号&#xff09;。输出设备&#xff1a;将电信号&#xff08;&#xff10;、&#xff11;&#xff09;转为人或其他设备能理解的…

JDK8新特性之Stream流01

Stream 流介绍 目标 了解集合的处理数据的弊端 理解Stream流的思想和作用 集合处理数据的弊端 当我们需要对集合中的元素进行操作的时候&#xff0c;除了必须的添加&#xff0c;删除&#xff0c;获取外&#xff0c;最典型的就是遍历集合。我们来体验集合操作的弊端&#xff…

【C++】—— map 与 multimap

【C】—— map 与 multimap 1 map1.1 map 和 multimap 参考文档1.2 map 类的介绍1.3 pair 类型介绍1.4 map的构造1.5 map的插入1.5.1 map 的插入方法1.5.2 验证1.5.3 再探pair1.5.4 make_pair 1.6 operator[]1.6.1 样例1.6.2 认识operator[]1.6.3 operator[] 的功能 1.7 map 的…

VTK知识学习(20)- 数据的存储与表达

1、数据的存储 1)、vtkDataArray VTK中的内存分配采用连续内存&#xff0c;可以快速地创建、删除和遍历&#xff0c;称之为数据数组(DataArray)&#xff0c;用类 vtkDataArray 实现。数组数据的访问是基于索引的&#xff0c;从零开始计数。 以 vtkFloatArray 类来说明如何在 …

HCIP-以太网交换安全

端口隔离&#xff1a;实现同一VLAN下的不同用户在二层不能互通&#xff08;可以实现在三层互通&#xff09;&#xff0c;同一个隔离组内是相互隔离的&#xff0c; MAC地址表功能&#xff1a;动态MAC地址表项&#xff0c;接口通告报文中的源MAC地址学习获得&#xff0c;表项可老…

电机功率、电压与电流的换算方法

在电气工程和相关行业中&#xff0c;电机的功率、电压和电流是三个重要的基本参数。它们之间有着密切的关系&#xff0c;而理解这些关系对于电机的选型、设计和应用至关重要。本文将详细阐述这三者之间的换算关系&#xff0c;以及相关公式的应用。 一、电机功率的定义 电机功…

【CKS最新模拟真题】获取多个集群的上下文名称并保存到指定文件中

文章目录 前言一、TASK二、解题过程1、问题一解题2、问题二解题 前言 月底考CKS,这是最新版的CKS模拟题 环境k8s版本ubuntu1.31 一、TASK 题目要求 Solve this question on: ssh cks3477 You have access to multiple clusters from your main terminal through contexts. …

智能合约的离线签名(EIP712协议)解决方案

一、解决核心问题 项目方不支付gas费&#xff0c;由用户自己发起交易&#xff0c;用户支付gas费。用户的数据保存在链下服务器中&#xff0c;token合约在链上&#xff0c;交易是由用户通过网页的DAPP发起。 后台服务、token合约、dapp如何配合工作是本方案的重点 二、总架构…

php:完整部署Grid++Report到php项目,并实现模板打印

一、下载Grid++Report软件 路径:开发者安装包下载 - 锐浪报表工具 二、 安装软件 1、对下载的压缩包运行内部的exe文件 2、选择语言 3、 完成安装引导 下一步即可 4、接收许可协议 点击“我接受” 5、选择安装路径 “浏览”选择安装路径,点击"安装" 6、完成…

SpringMvc完整知识点一

SpringMVC概述 定义 SpringMVC是一种基于Java实现MVC设计模型的轻量级Web框架 MVC设计模型&#xff1a;即将应用程序分为三个主要组件&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器&#xff08;Controller&#xff09;。这种分离…

SpringBoot暴露Prometheus指标数据

一、Prometheus Prometheus是一个开源的服务监控系统和时序数据库&#xff0c;提供了通用的数据模型和快捷数据采集、存储和查询接口。其核心组件Prometheus server会定期从静态配置的监控目标或者基于服务发现自动配置的目标中拉取数据&#xff0c;当新拉取到的数据大于配置的…

Hadoop生态圈框架部署 伪集群版(七)- Hive部署

文章目录 前言一、Hive部署&#xff08;手动部署&#xff09;1. 下载Hive2. 解压Hive安装包2.1 解压2.2 重命名2.3 解决冲突2.3.1 解决guava冲突2.3.2 解决SLF4J冲突 3. 配置Hive3.1 配置Hive环境变量3.2 修改 hive-site.xml 配置文件3.3 配置MySQL驱动包 4. 初始化MySQL上的存…

C++析构函数和构造函数

一、构造函数 1.构造函数的基本概念 1.对构造函数的理解&#xff1a; 构造函数是类的一种特殊成员函数&#xff0c;其主要功能是在创建对象时进行初始化操作。它的名字与类名相同&#xff0c;并且没有返回值类型&#xff08;不能是void&#xff09;。例如&#xff0c;对于一个…

Cherno C++学习笔记 P32 字符串

这篇文章我们来讲字符串。字符串可以说是最重要的变量类型了&#xff0c;因为对字符串的读写极大地影响到我们的程序和用户之间的交互。甚至很多很庞大的程序就只是在处理字符串。 对于字符串&#xff0c;我们同时需要有关于数组和指针的关系&#xff0c;字符串的实现与数组是…

linuxCNC(五)HAL驱动的指令介绍

HAL驱动的构成 指令举例详解 从终端进入到HAL命令行&#xff0c;执行halrun&#xff0c;即可进入halcmd命令行 # halrun指令描述oadrt加载comoonent&#xff0c;loadrt threads name1 period1创建新线程loadusr halmeter加载万用表UI界面loadusr halscope加载示波器UI界面sho…

在做题中学习(78):数组中第K个最大元素

解法&#xff1a;快速选择算法 说明&#xff1a;堆排序也是经典解决topK问题的算法&#xff0c;但时间复杂度为&#xff1a;O(NlogN) 而将要介绍的快速选择算法的时间复杂度为: O(N) 先看我的前两篇文章&#xff0c;分别学习&#xff1a;数组分三块&#xff0c;随机选择基准…

分布式事务的前世今生-纯理论

一个可用的复杂的系统总是从可用的简单系统进化而来。反过来这句话也正确: 从零开始设计的复杂的系统从来都用不了&#xff0c;也没办法让它变的可用。 --John Gal 《系统学》 1975 1. 事务的概念 百科&#xff1a; 事务&#xff08;Transaction&#xff09;&#xff0c;一般是…

MySQL 服务无法启动

常见原因: 检查端口占用&#xff1a; 使用命令行工具&#xff08;如netstat&#xff09;来检查3306端口是否已被其他程序占用,输入netstat -ano&#xff08;Windows&#xff09;或netstat -tulnp | grep 3306&#xff08;Linux/Mac&#xff09;来查找3306端口的占用情况。如果…