Android H5调起微信支付宝支付

c 复制代码
<?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" />

    <application
        android: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-data
            android:name="UMENG_CHANNEL"
            android:value="${UMENG_CHANNEL_VALUE}" />

        <activity
            android: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>

添加的是

c 复制代码
    <queries>
        <package android:name="com.tencent.mm"/>
        <package android:name="com.eg.android.AlipayGphone"/>
    </queries>

webview如下

c 复制代码
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() {
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
        }

        @Nullable
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
            return super.shouldInterceptRequest(view, request);
        }

        @Override
        public 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 自行加载
        }

        @Override
        public 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) return
            if(view==null) return
            if(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
    @Override
    public 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,用于获取设备Token
        SharedPreferencesUtils 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());

        // 启用 JavaScript
        myWebView.getSettings().setJavaScriptEnabled(true);
        // 设置支持弹出新窗口
        myWebView.getSettings().setSupportMultipleWindows(true);

        // 加载拼接后的URL
        myWebView.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() {
            @Override
            public 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() {
            @JavascriptInterface
            public void showHeaderBarBackIcon(boolean show) {
                if (show) {
                    getActivity().runOnUiThread(() -> btnBack.setVisibility(View.VISIBLE));
                } else {
                    getActivity().runOnUiThread(() -> btnBack.setVisibility(View.GONE));
                }
            }

            @JavascriptInterface
            public void setHeaderBarBackGroundColor(String color) {
                Log.d("js回调", "状态栏颜色" + color);
                getActivity().runOnUiThread(() -> getView().findViewById(R.id.statusBar).setBackgroundColor(Color.parseColor(color)));
            }

            @JavascriptInterface
            public 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);

                    }
                });
            }

            @JavascriptInterface
            public void getLoginInfo() {
                Log.d("js回调", "开始调登陆");
                loginInfoRet(channel);
            }

            @JavascriptInterface
            public 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>() {
                                @Override
                                public void onReceiveValue(String value) {
                                    Log.d("JS Result", "Result from JS: " + value);
                                }
                            });
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                });
            }
        }, "Android");



        return rootView;
    }

    @Override
    public void onDetach() {
        super.onDetach();
        if (myWebView != null) {
            myWebView.destroy();
        }
    }

    public void runOnMainThread(Runnable block) {
        new Handler(Looper.getMainLooper()).post(block);
    }
}

MainActivity

c 复制代码
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()); // 用于延时清除标志

    @Override
    protected 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,"");

        // 启动 WebViewFragment
        if (savedInstanceState == null) {
            WebViewFragment2 webViewFragment = WebViewFragment2.newInstance(mainWebUrl, "智商测试",false);
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.fragment_container, webViewFragment);
            transaction.commit();
        }

    }

    @Override
    public 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);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 清除所有回调,避免内存泄漏
        handler.removeCallbacksAndMessages(null);
    }
}
相关推荐
事业运财运爆棚几秒前
http 502 和 504 的区别
android
峥嵘life1 小时前
Android Studio新版本的一个资源id无法找到的bug解决
android·bug·android studio
编程乐学1 小时前
网络资源模板--Android Studio 实现绿豆通讯录
android·前端·毕业设计·android studio·大作业·安卓课设·绿豆通讯录
程序员入门进阶3 小时前
基于微信的追星小程序+ssm
微信·小程序
编织幻境的妖4 小时前
使用html 和javascript 实现微信界面功能1
javascript·微信·html
朴拙数科5 小时前
mysql报错解决 `1525 - Incorrect DATETIME value: ‘0000-00-00 00:00:00‘`
android·数据库·mysql
1登峰造极7 小时前
scroll-view 实现滑动显示,确保超出正常显示,小程序app,h5兼容
android·小程序
刘争Stanley7 小时前
Android 15(V)新功能适配,雕琢移动细节之美
android·kotlin·android 15·android v
小狗爱世界7 小时前
深入解析Binder源码
android·binder
qq_214670357 小时前
android 聊天界面键盘、表情切换丝滑
android·gitee