国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

項目筆記——安卓WebView加載H5頁面問題處理

這篇具有很好參考價值的文章主要介紹了項目筆記——安卓WebView加載H5頁面問題處理。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

項目為Android應(yīng)用,使用WebView加載H5頁面。

此文僅記錄項目開發(fā)中遇到的問題及解決方法。

目錄

一,下拉刷新

二,H5喚起支付寶

三,H5本地文件選擇

四,加載圖片失敗

五,輸入框被軟鍵盤遮擋


一,下拉刷新

頁面Reload需要下拉刷新功能,所以使用了SwipeRefreshLayout包裹WebView。但使用時不管頁面處在哪個位置只要下拉,都會觸發(fā)刷新。

于是通過對WebView的位置進行判斷,來決定是否允許SwipeRefreshLayout刷新功能生效。

現(xiàn)在H5頁面大多都不再是頁面本身滾動,反映到日志就是WebView的getScrollY() 得到的值一直是0,無法用于判斷,于是采用迂回的方式。

首先自定義WebView的子類控件OverScrollWebView,重寫過度滾動監(jiān)聽overScrollBy,當(dāng)其被觸發(fā)的時候,允許下拉刷新。注意:向上過度滑動也會觸發(fā)這個回調(diào),但SwipeRefreshLayout的刷新僅會被下拉觸發(fā),所以這里沒有考慮方向問題。

    private boolean isOverScroll = false;

    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        if (!isOverScroll) {
            isOverScroll = true;
        }
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }
   
    public boolean isOverScroll() {
        return isOverScroll;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_UP:
                //在用戶開始或結(jié)束觸屏?xí)r復(fù)位
                isOverScroll = false;
                break;
        }
        return super.onTouchEvent(event);
    }

?同時,在頁面中設(shè)置允許WebView過度滾動,并重寫觸屏事件監(jiān)聽,根據(jù)頁面是否已處在頂部來設(shè)置是否允許SwipeRefreshLayout下拉刷新。

    //允許webView過度滾動
    webView.setOverScrollMode(View.OVER_SCROLL_ALWAYS);
    if (webView instanceof OverScrollWebView) {
         webView.setOnTouchListener((v, event) -> {
            swipeRefreshLayout.setEnabled(((OverScrollWebView) webView).isOverScroll());
            return false;
         });
    }

二,H5喚起支付寶

項目支付功能由H5頁面調(diào)用支付寶接口,但無法正確喚起支付寶App,僅生成了吱口令。

因為安卓原生的谷歌瀏覽器自從 chrome25 版本開始,URL Scheme 就無法啟動Android應(yīng)用了。

所以,需要重寫攔截邏輯,手動喚起App。

webView.setWebViewClient(new WebViewClient() {
        
        @Override
        public boolean shouldOverrideUrlLoading (WebView view, String url){
            JCLog.i(TAG, " shouldOverrideUrlLoading url: " + url);
            if (url.startsWith("http:") || url.startsWith("https:")) {
                //正常的頁面,不攔截不處理
                return false;
            }
            try {
                //將H5喚起App,變?yōu)锳pp間互相喚起
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(intent);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return true;

        }
    });

這里是籠統(tǒng)的處理,也可以根據(jù)頁面需求進行精準處理。

參考:android中WebView調(diào)用H5頁面的支付寶、微信支付失敗錯誤返回ERR_UNKNOWN_URL_SCHEME_webview打開支付寶付款沒反應(yīng)_呂氏春秋i的博客-CSDN博客

三,H5本地文件選擇

?這個就比較簡單了,就是重寫WebChromeClient的onShowFileChooser方法,將H5的文件選擇請求轉(zhuǎn)換成安卓原聲的文件選取。

需要注意幾點:

1,項目需要選擇多類型文件,所以我在注冊回調(diào)時用的是OpenMultipleDocuments,如果是單文件、僅圖片等要根據(jù)具體情況選擇。

2,mFilePathCallback的onReceiveValue方法一定要調(diào)用,就算沒有內(nèi)容,也要像我這樣傳一個空數(shù)組new Uri[0]給它調(diào)用,這個方法如果不調(diào)用,onShowFileChooser就不會再工作了,就是說你沒法再次進行文件選擇了。

3,數(shù)組fileChooserParams.getAcceptTypes()是H5提供的要選擇文件類型,部分控件給的是文件后綴,但安卓需要的必須是MimeType,所以我代碼里有一部分是專門用于轉(zhuǎn)換參數(shù)的。

    private ValueCallback<Uri[]> mFilePathCallback;

    ActivityResultLauncher<String[]> chooseFileLauncher = registerResultCallback(new ActivityResultContracts.OpenMultipleDocuments(), result -> {
        JCLog.i(TAG, "onActivityResult result:" + result);
        Uri[] uris;
        if (null == result || result.isEmpty()) {
            uris = new Uri[0];
        } else {
            uris = new Uri[result.size()];
            for (int i = 0; i < result.size(); i++) {
                uris[i] = result.get(i);
            }
        }
        JCLog.i(TAG, "onActivityResult uris: " + Arrays.toString(uris));
        if (null != mFilePathCallback) {
            mFilePathCallback.onReceiveValue(uris);
            mFilePathCallback = null;
        }
    });

    webView.setWebChromeClient(new WebChromeClient() {
        
        @Override
        public boolean onShowFileChooser (WebView webView, ValueCallback < Uri[]>
        filePathCallback, WebChromeClient.FileChooserParams
        fileChooserParams){
            JCLog.i(TAG, "onShowFileChooser: " + Arrays.toString(fileChooserParams.getAcceptTypes()));
            if (null != chooseFileLauncher) {
                mFilePathCallback = filePathCallback;
                String[] types = fileChooserParams.getAcceptTypes();
                if (null != types && types.length > 0) {
                    for (int i = 0; i < types.length; i++) {
                        String type = types[i];
                        if (TextUtils.isEmpty(type) || !type.startsWith(".")) {
                            continue;
                        }
                        type = type.replaceFirst(".", "");
                        String newType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(type);
                        if (!TextUtils.isEmpty(newType)) {
                            types[i] = newType;
                        }
                    }
                }
                JCLog.i(TAG, "onShowFileChooser before launch: " + Arrays.toString(types));
                chooseFileLauncher.launch(types);
                return true;
            }
            return super.onShowFileChooser(webView, filePathCallback, fileChooserParams);
        }
    });

四,加載圖片失敗

測試時發(fā)現(xiàn)某些圖片加載失敗,與H5開發(fā)人員確認,圖片使用的scheme是http。

WebView在安卓5以后,則需要增加設(shè)置:

    WebSettings webSettings = webView.getSettings();
    ……
    webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);

這樣就能正常顯示http的圖片了。

五,輸入框被軟鍵盤遮擋

H5頁面中有輸入框,點擊后,安卓彈出的軟鍵盤遮擋了輸入框,使用網(wǎng)上找到的AndroidBug5497Workaround解決問題,結(jié)果發(fā)現(xiàn)手機底部虛擬按鍵會遮擋頁面,于是再次尋找解決辦法,最后找到了通過修改AndroidBug5497Workaround完美解決這兩個問題的辦法。特此記錄。因項目開發(fā)工作比較忙,此次更新時間間隔較久,所以無法找到代碼引用的原文了,見諒。文章來源地址http://www.zghlxwxcb.cn/news/detail-787783.html

public class AndroidBug5497Workaround {
    private final Activity activity;

    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
    public static void assistActivity(Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;
    private int statusBarHeight;

    //狀態(tài)欄高度
    private AndroidBug5497Workaround(final Activity activity) {
        this.activity = activity;
        if (checkDeviceHasNavigationBar(activity)) {
            //獲取狀態(tài)欄的高度
            int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
            statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);
        }

        //1?找到Activity的最外層布局控件,它其實是一個DecorView,它所用的控件就是FrameLayout
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        //2?獲取到setContentView放進去的View
        mChildOfContent = content.getChildAt(0);
        //3?給Activity的xml布局設(shè)置View樹監(jiān)聽,當(dāng)布局有變化,如鍵盤彈出或收起時,都會回調(diào)此監(jiān)聽
        mChildOfContent.getViewTreeObserver().
                addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    //4?軟鍵盤彈起會使GlobalLayout發(fā)生變化
                    public void onGlobalLayout() {
                        //5?當(dāng)前布局發(fā)生變化時,對Activity的xml布局進行重繪
                        possiblyResizeChildOfContent(checkDeviceHasNavigationBar(activity));
                    }
                });
        //6?獲取到Activity的xml布局的放置參數(shù)
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }

    /*** 重新調(diào)整布局高度
     * 獲取界面可用高度,如果軟鍵盤彈起后,Activity的xml布局可用高度需要減去鍵盤高度
     ** @param hasNav*/
    private void possiblyResizeChildOfContent(boolean hasNav) {
        //1?獲取當(dāng)前界面可用高度,鍵盤彈起后,當(dāng)前界面可用布局會減少鍵盤的高度
        int usableHeightNow = computeUsableHeight(hasNav);
        //2?如果當(dāng)前可用高度和原始值不一樣
        if (usableHeightNow != usableHeightPrevious) {
            //3?獲取Activity中xml中布局在當(dāng)前界面顯示的高度
            int usableHeightSansKeyboard;
            if (hasNav) usableHeightSansKeyboard = mChildOfContent.getHeight();//兼容華為等機型
            else {
                usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();//這個判斷是為了解決19之前的版本不支持沉浸式狀態(tài)欄導(dǎo)致布局顯示不完全的問題
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                    Rect frame = new Rect();
                    activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
                    int statusBarHeight = frame.top;
                    usableHeightSansKeyboard -= statusBarHeight;
                }
            }
            //4?Activity中xml布局的高度-當(dāng)前可用高度
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            //5?高度差大于屏幕1/4時,說明鍵盤彈出
            if (heightDifference > (usableHeightSansKeyboard / 4)) {
                // keyboard probably just became visible
                // 6?鍵盤彈出了,Activity的xml布局高度應(yīng)當(dāng)減去鍵盤高度
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && hasNav) {
                    frameLayoutParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;
                } else {
                    frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                }
            } else {
                if (hasNav) frameLayoutParams.height = usableHeightNow + statusBarHeight;
                else frameLayoutParams.height = usableHeightSansKeyboard;
            }
            //7? 重繪Activity的xml布局
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    /**
     * 計算mChildOfContent可見高度
     * * @return
     */
    private int computeUsableHeight(boolean hasNav) {
        if (hasNav) {
            Rect r = new Rect();
            mChildOfContent.getWindowVisibleDisplayFrame(r);
            // 全屏模式下:直接返回r.bottom,r.top其實是狀態(tài)欄的高度
            if (r.top < statusBarHeight)
                return r.bottom - statusBarHeight;
            else return r.bottom - r.top;
        } else {
            Rect frame = new Rect();
            activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
            int statusBarHeight = frame.top;
            Rect r = new Rect();
            mChildOfContent.getWindowVisibleDisplayFrame(r);
            //這個判斷是為了解決19之后的版本在彈出軟鍵盤時,鍵盤和推上去的布局(adjustResize)之間有黑色區(qū)域的問題
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                return (r.bottom - r.top) + statusBarHeight;
            }
            return (r.bottom - r.top);
        }
    }

    /*** 通過"qemu.hw.mainkeys"判斷是否存在NavigationBar
     ** @return 是否有NavigationBar
     */
    private static boolean checkDeviceHasNavigationBar(Activity activity) {
        boolean hasNavigationBar = false;
        Resources rs = activity.getResources();
        int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
        if (id > 0) {
            hasNavigationBar = rs.getBoolean(id);
        }
        try {
            Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
            Method m = systemPropertiesClass.getMethod("get", String.class);
            String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
            if ("1".equals(navBarOverride)) {
                hasNavigationBar = false;
            } else if ("0".equals(navBarOverride)) {
                hasNavigationBar = true;
            } else {
                hasNavigationBar = hasNavBar(activity);
            }
        } catch (Exception e) {

        }
        return hasNavigationBar;
    }

    /***
     * 根據(jù)屏幕真實寬高-可用寬高>0來判斷是否存在NavigationBar
     ** @param activity 上下文* @return 是否有NavigationBar
     */
    private static boolean hasNavBar(Activity activity) {
        WindowManager windowManager = activity.getWindowManager();
        Display d = windowManager.getDefaultDisplay();
        DisplayMetrics realDisplayMetrics = new DisplayMetrics();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            d.getRealMetrics(realDisplayMetrics);
        }
        int realHeight = realDisplayMetrics.heightPixels;
        int realWidth = realDisplayMetrics.widthPixels;
        DisplayMetrics displayMetrics = new DisplayMetrics();
        d.getMetrics(displayMetrics);
        int displayHeight = displayMetrics.heightPixels;
        int displayWidth = displayMetrics.widthPixels;
        return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
    }
}

到了這里,關(guān)于項目筆記——安卓WebView加載H5頁面問題處理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Android WebView加載h5打開麥克風(fēng)與攝像頭的權(quán)限問題

    Android webview h5 麥克風(fēng)權(quán)限,攝像頭(相機)權(quán)限實現(xiàn)與填坑。 app 必須先具備如下權(quán)限(本文只討論錄音與相機) AndroidManifest中添加: 注意:前面兩項需要app動態(tài)申請 懶人快速做法(可直接copy代碼) 默許授權(quán)(不再確認) 當(dāng)h5向app申請的時候,重寫 WebChromeClient 的onPermis

    2024年02月11日
    瀏覽(103)
  • 利用webview 內(nèi)嵌實現(xiàn)小程序,h5 ,app 頁面跳轉(zhuǎn)和數(shù)據(jù)通訊,附帶實現(xiàn)pdf文件的預(yù)覽(兼容ios和安卓)

    利用webview 內(nèi)嵌實現(xiàn)小程序,h5 ,app 頁面跳轉(zhuǎn)和數(shù)據(jù)通訊,附帶實現(xiàn)pdf文件的預(yù)覽(兼容ios和安卓)

    承載網(wǎng)頁的容器。會自動鋪滿整個小程序頁面, 個人類型的小程序暫不支持使用。 客戶端 6.7.2 版本開始,navigationStyle: custom?對?web-view?組件無效 相關(guān)的屬性說明:開放能力 / web-view (qq.com) 2.bindmessage 可以實現(xiàn)網(wǎng)頁端和小程序之間通訊, 但只在特定時機觸發(fā) 網(wǎng)頁端向小程序

    2024年02月02日
    瀏覽(36)
  • 微信小程序webview嵌入H5頁面,返回 UniAppJSBridgeReady,不觸發(fā)問題

    公司的一個項目,要求用微信小程序?qū)崿F(xiàn)對pdf文件,預(yù)覽簽字,用的uniapp開發(fā) pdf預(yù)覽這部分,用的pdf.js插件實現(xiàn)。 由于微信小程序中webview展示頁面不能放在項目本地,要求遠端請求網(wǎng)頁。而且webview會鋪滿整個頁面,導(dǎo)致我的簽字按鈕只能放在遠端的H5頁面實現(xiàn),當(dāng)時因為偷

    2024年02月15日
    瀏覽(25)
  • react-native-webview使用postMessage后H5不能監(jiān)聽問題(iOS和安卓的兼容問題)

    react-native-webview使用postMessage后H5不能監(jiān)聽問題(iOS和安卓的兼容問題)

    ?chatgpt: https://chat.xutongbao.top/ 參考鏈接: https://blog.csdn.net/liuxingyuzaixian/article/details/125199131 https://chat.xutongbao.top/

    2024年02月12日
    瀏覽(26)
  • 微信小程序使用webview內(nèi)嵌h5頁面 wx.miniProgram.getEnv失效問題

    背景 最近接到一個h5需求,和普通的h5不一樣,這個h5頁面是嵌入到小程序中使用的,需求簡單來說就是展示一個跳轉(zhuǎn)按鈕,判斷如果是小程序環(huán)境下就進行跳轉(zhuǎn)到其他小程序頁面。 實現(xiàn)思路 核心邏輯其實就是判斷小程序環(huán)境這一塊,我們可以直接使用wxsdk來進行判斷小程序

    2024年02月09日
    瀏覽(168)
  • 安卓部分手機使用webview加載鏈接后白屏(Android低版本會出現(xiàn)的問題)

    安卓部分手機使用webview加載鏈接后白屏(Android低版本會出現(xiàn)的問題)

    大爺:小伙我這手機怎么打開你們呢這個是白屏什么都不顯示。 大娘:小伙我這也是打開你們呢這功能,就是一個白屏什么也沒有,你們呢的應(yīng)用不會有病毒吧。 小伙:我的手機也正常; 同事:我的也正常可以顯示; 小伙:你們都是什么手機型號; 大爺:我的Android7.1.1

    2024年04月15日
    瀏覽(22)
  • react項目做的h5頁面加載緩慢優(yōu)化(3s優(yōu)化到0.6s)

    打包到生產(chǎn)環(huán)境時去掉SOURCEMAP 禁用生成 Source Map 是一種權(quán)衡,可以根據(jù)項目的實際需求和優(yōu)化目標來決定是否禁用。如果您對調(diào)試需求不是特別強烈,可以考慮在生產(chǎn)構(gòu)建中禁用 Source Map 以獲取更好的性能。但如果需要保留調(diào)試能力,可以在生產(chǎn)構(gòu)建中保留生成 Source Map “

    2024年02月13日
    瀏覽(23)
  • 安卓WebView(H5)調(diào)用原生相機及相冊

    安卓WebView(H5)調(diào)用原生相機及相冊

    在開始敘述正文之前筆者先聲明一下應(yīng)用場景:例如在網(wǎng)頁上的即時通訊需要能拍照或者從圖庫選擇圖片來進行上傳,此場景下就可以用到這篇文章的內(nèi)容 正文 首先,如果你已經(jīng)把相機以及訪問文件夾的權(quán)限都加上了并且WebView的基礎(chǔ)操作都做完了,就差上傳圖片了的話那就參

    2024年02月11日
    瀏覽(27)
  • 小程序通過webView打開H5頁面并傳參(包含webView業(yè)務(wù)域名配置)、H5頁面實現(xiàn)返回小程序并實現(xiàn)傳參

    小程序通過webView打開H5頁面并傳參(包含webView業(yè)務(wù)域名配置)、H5頁面實現(xiàn)返回小程序并實現(xiàn)傳參

    小程序內(nèi)嵌webview實現(xiàn)跳轉(zhuǎn)、傳參 1、小程序通過webView打開H5頁面并傳參 2、H5接收小程序傳參,H5返回小程序并實現(xiàn)傳參,小程序接收H5傳參 一、小程序通過webView打開H5頁面并傳參 在小程序中一般通過webview打開H5頁面 常見問題: 1、小程序通過webview打開H5頁面,需要配置業(yè)務(wù)域

    2024年02月12日
    瀏覽(31)
  • uniapp WebView與H5頁面通信

    uniapp WebView與H5頁面通信

    1、參數(shù)拼在url里 在h5頁面里用window對象獲取拼接的url ? 2、H5環(huán)境中 用window.postMessage傳遞數(shù)據(jù) ? ?用window.addEventListener(\\\"message\\\", receiveMessage, false); ? 3、APP環(huán)境與微信小程序中 可以通過 uni.postMessage 在 HTML 中向應(yīng)用發(fā)送消息 H5端 uni.postMessage參數(shù)格式,傳遞的消息信息必須在 d

    2024年02月11日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包