AndroidでWebViewインタラクション

16993 ワード

一、前言:
Androidではjsにパラメータを渡します.jsもパラメータを渡します.jsのクリックイベントを取得してappローカル操作を完了することもあります.
WebViewでよく見られるピット:クリックして表示:
1.Activityでの使用:
public class MyAgreementDetailsActivity extends BaseDaggerActivity implements MyAgreementDetailsContract.View {


    @Inject
    MyAgreementDetailsPresenter myAgreementPresenter;
    @BindView(R.id.iv_main_back)
    ImageView ivMainBack;
    @BindView(R.id.tv_main_title)
    TextView tvMainTitle;
    @BindView(R.id.iv_main_clock)
    ImageView ivMainClock;
    @BindView(R.id.rl_title)
    RelativeLayout rlTitle;
    @BindView(R.id.progressBar1)
    ProgressBar progressBar1;
    @BindView(R.id.webview)
    CustWebView webview;


    private String agreementName;
    private String agreementId;
    private String url;
    private int nper;
    private int agrType;
    private int isChange;
    private String token;
    private boolean isFirst = false;


    public static void launch(Context context, String agreement_id, String agreement_name, int nper, String url, int agr_type, int is_change) {

        Intent intent = new Intent(context, MyAgreementDetailsActivity.class);
        intent.putExtra("agreementName", agreement_name);
        intent.putExtra("agreementId", agreement_id);
        intent.putExtra("url", url);
        intent.putExtra("nper", nper);
        intent.putExtra("agrType", agr_type);
        intent.putExtra("isChange", is_change);

        context.startActivity(intent);
    }

    @Override
    public MyAgreementDetailsPresenter createPresent() {
        return myAgreementPresenter;
    }


    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_agreement_view);
        ButterKnife.bind(this);
        initEvent();
        initData();
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @SuppressLint("JavascriptInterface")
    private void initData() {
        token = SPUtils.getInstance(SPConstant.TOKEN).getString(SPConstant.TOKEN);
        agreementName = getIntent().getStringExtra("agreementName");
        //  id
        agreementId = getIntent().getStringExtra("agreementId");
        //  
        nper = getIntent().getIntExtra("nper", 0);
        //    
        url = getIntent().getStringExtra("url");

        agrType = getIntent().getIntExtra("agrType", 0);

        isChange = getIntent().getIntExtra("isChange", 0);

        tvMainTitle.setText(agreementName);

        final WebSettings webSettings = webview.getSettings();
        //  JS
        webSettings.setJavaScriptEnabled(true);

        //        
        webSettings.setSupportZoom(true);
        //  
        webSettings.setBuiltInZoomControls(true);
        webSettings.setDisplayZoomControls(false);
        //   
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setSupportMultipleWindows(true);
        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
        webSettings.setDefaultFontSize(18);

        webSettings.setAllowFileAccess(true);
        webSettings.setAllowFileAccessFromFileURLs(true);

        //    
        webSettings.setAppCacheEnabled(true);
        webSettings.setAllowFileAccess(true);
        //
        webSettings.setDomStorageEnabled(true);
        //      
        webSettings.setBlockNetworkImage(false);
        //       
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }


        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);

 try {
            if (Build.VERSION.SDK_INT >= 16) {
                Class> clazz = webview.getSettings().getClass();
                Method method = clazz.getMethod(
                        "setAllowUniversalAccessFromFileURLs", boolean.class);//             
                if (method != null) {
                    method.invoke(webview.getSettings(), true);//    
                }
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }


        webview.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                // TODO          
                if (newProgress == 100) {
                    progressBar1.setVisibility(View.GONE);//          
                } else {
                    progressBar1.setVisibility(View.VISIBLE);//            
                    progressBar1.setProgress(newProgress);//     
                }


            }
        });


        webview.loadUrl(url);

        // js     java    callAndroid
        webview.addJavascriptInterface(new JsInterface(this), "click");

        //    
        if (BuildConfig.DEBUG){
            WebView.setWebContentsDebuggingEnabled(true);
        }else {
            WebView.setWebContentsDebuggingEnabled(false);
        }


        /**
         * webView                   
         *       webview     
         */
        webview.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return super.shouldOverrideUrlLoading(view, url);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                // webview.loadUrl("javascript:loadingDate('  " + mLoginSMSBean.getToken() + " ' ,'" + mAgreementBean.getAgreement_id() + "' ,'" + "2" + "','" + mAgreementBean.getAgr_type() + "','" + mAgreementBean.getNper() + "'  ,'" + mAgreementBean.getIs_change() + "'     )");

                if (!isFirst) {
                    isFirst = true;
                    webview.loadUrl("javascript:loadingDate('" + token + "','" + agreementId + "','" + "2" + "','" + agrType + "','" + nper + "','" + isChange + "' )");

                   // LogUtils.d("LUO", "===" + token);
                }

            }

        });

        webview.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    //             
                    if (keyCode == KeyEvent.KEYCODE_BACK && webview.canGoBack()) {
                        //  
                        webview.goBack();
                        return true;
                    }
                }
                return false;
            }
        });
    }

    private void initEvent() {
        //  
        ivMainBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });


    }


    @Override
    public void onError(String error) {
        ToastUtils.showShort(error);
    }


    @Override
    public void AgreementDetailsSuccess(BaseHttpResponse data) {

        ToastUtils.showShort("      ");

        finish();

    }


    /**
     * 2.       Web Js   
     */


    public class JsInterface {
        private Context mContext;

        public JsInterface(Context context) {
            this.mContext = context;
        }

        // js   window.AndroidWebView.showInfoFromJs(name),       。
        @JavascriptInterface
        public void clickAction(String json, String flag) {

            if(!TextUtils.isEmpty(json)){
                JsBean jsBean = JSON.parseObject(json, JsBean.class);
                submitData(jsBean);
            }
//            LogUtils.d("LUO", json + "==========" + flag);
//            ToastUtils.showShort("     ");


        }
    }

    private void submitData(JsBean jsBean) {

        HashMap map = new HashMap();
        map.put("agreement_id",agreementId);//   id
        map.put("nickname",jsBean.getNickname());//    
        map.put("id_card_no",jsBean.getId_card_no());//    

        map.put("mobile",jsBean.getMobile());//      
        map.put("province",jsBean.getProvince());//   
        map.put("city",jsBean.getCity());//  
        map.put("country",jsBean.getCountry());//  
        map.put("address",jsBean.getAddress());//    
        map.put("email",jsBean.getEmail());//    
        map.put("title",jsBean.getTitle());//     
        map.put("signed",jsBean.getSigned());
        map.put("signed_time",jsBean.getSigned_time());//    
//        map.put("front_id_card",);//        
//        map.put("back_id_card",);//        
        map.put("agr_type",String.valueOf(agrType));//     1:     2:    
        map.put("nper",String.valueOf(nper));//  
        map.put("nper_upper",jsBean.getNper_upper());//    

        //      
        myAgreementPresenter.getAgreementDetails(map);
    }
}


2. activity_agreement_view.xmlレイアウト:




   


    

    

    


3.カスタムCustWebView:
public class CustWebView extends WebView {
    private OnTouchScreenListener onTouchScreenListener;

    public CustWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

    }

    public CustWebView(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    public CustWebView(Context context) {
        super(context);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (onTouchScreenListener != null)
                onTouchScreenListener.onTouchScreen();
        }
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (onTouchScreenListener != null) {
                onTouchScreenListener.onReleaseScreen();
            }
        }

        return super.onTouchEvent(event);
    }

    public interface OnTouchScreenListener {
        void onTouchScreen();

        void onReleaseScreen();
    }

    public void setOnTouchScreenListener(OnTouchScreenListener onTouchScreenListener) {
        this.onTouchScreenListener = onTouchScreenListener;
    }
}

二、まとめ:
1.WebViewプロパティを設定し、Javascriptスクリプトを実行できる
mWebView.getSettings().setJavaScriptEnabled(true);//jsの使用可能な設定
2.ロード進捗バーの設定
 webview.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                // TODO          
                if (newProgress == 100) {
                    progressBar1.setVisibility(View.GONE);//          
                } else {
                    progressBar1.setVisibility(View.VISIBLE);//            
                    progressBar1.setProgress(newProgress);//     
                }


            }
        });

3.ブラウザ内部ジャンプ:
  /**
         * webView                   
         *       webview     
         */
        webview.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return super.shouldOverrideUrlLoading(view, url);
            }

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

            }

        });

4.webview表示クリック戻りキー:
webview.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    //             
                    if (keyCode == KeyEvent.KEYCODE_BACK && webview.canGoBack()) {
                        //  
                        webview.goBack();
                        return true;
                    }
                }
                return false;
            }
        });

5.webviewでデバッグを許可するかどうか:
 //    
        if (BuildConfig.DEBUG){
            WebView.setWebContentsDebuggingEnabled(true);
        }else {
            WebView.setWebContentsDebuggingEnabled(false);
        }

6.JSからAndroidへの伝達パラメータを受け入れる:
jsでローカルjavaメソッドwebviewを呼び出す.addJavascriptInterface(new JsInterface(this), "click");
  /**
     * 2.       Web Js   
     */

    public class JsInterface {
        private Context mContext;

        public JsInterface(Context context) {
            this.mContext = context;
        }

      // @JavascriptInterface    
        @JavascriptInterface
        public void clickAction(String json, String flag) {
            LogUtils.d("LUO", json + "==========" + flag);
            ToastUtils.showShort("     ");

        }
    }

7.AndroidがJSにパラメータを渡す
mWebView.loadUrl("javascript:javaCall('fasff')");
ページのロードが完了したら、JSにパラメータを渡します.
        /**
         * webView                   
         *       webview     
         */
        webview.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return super.shouldOverrideUrlLoading(view, url);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                // webview.loadUrl("javascript:loadingDate('  " + mLoginSMSBean.getToken() + " ' ,'" + mAgreementBean.getAgreement_id() + "' ,'" + "2" + "','" + mAgreementBean.getAgr_type() + "','" + mAgreementBean.getNper() + "'  ,'" + mAgreementBean.getIs_change() + "'     )");

                if (!isFirst) {
                    isFirst = true;
                    webview.loadUrl("javascript:loadingDate('" + token + "','" + agreementId + "','" + "2" + "','" + agrType + "','" + nper + "','" + isChange + "' )");

                   // LogUtils.d("LUO", "===" + token);
                }

            }

        });

8.ファイルをダウンロードできませんか?
自分で書いたWebViewではファイルを直接ダウンロードすることはできませんが、ダウンロードイベントを自分で傍受してダウンロードの動作を処理する必要があります.
/**
*                     ,           url           。
**/
webView.setDownloadListener(new FileDownLoadListener());

private class FileDownLoadListener implements DownloadListener {
    @Override
    public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
        Uri uri = Uri.parse(url);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
    }
}


作者:cpacmリンク:https://www.jianshu.com/p/fea5e829b30a
参照リンク:https://blog.csdn.net/qq_21267961/article/details/79494829