Newer
Older
SpyWebView / app / src / main / java / me / bello / spywebview / MyWebViewActivity.java
bello on 30 Jul 2020 12 KB init
package me.bello.spywebview;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.ProgressBar;

import java.util.ArrayList;
import java.util.Iterator;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import me.bello.spywebview.util.AppBarUtils;
import me.bello.spywebview.util.DeviceUtils;

/**
 * @Info
 * @Author Bello
 * @Time 20-7-29 下午3:20
 * @Ver
 */
public class MyWebViewActivity extends AppCompatActivity {
    private final String TAG = "MyWebViewActivity";
    private Context mContext;
    private WebView webView;
    private ProgressBar progressBar;
    private String url;
    private FrameLayout fLayout;

    private String elementStr = "";
    private ArrayList<String> urlList = new ArrayList<>();
    private ArrayList<String> resList = new ArrayList<>();
    private ArrayList<String> clrList = new ArrayList<>();

    private PopupWindow popupWindow;
    private Fragment elementFragment = new ElementsFragment();
    private Fragment resourceFragment = new ResourceFragment();


    @SuppressLint({"JavascriptInterface", "SetJavaScriptEnabled", "AddJavascriptInterface"})
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AppBarUtils.hideStatusBarAndShowNavigationBar(this, false);
        setContentView(R.layout.activity_web_view);
        mContext = this;

        url = getIntent().getStringExtra("url");
        Log.e(TAG, url);

        fLayout = findViewById(R.id.web_layout);
        progressBar = findViewById(R.id.progress_bar);
        progressBar.setMax(100);


        webView = new WebView(this);
        WebSettings settings = webView.getSettings();
        settings.setLoadWithOverviewMode(true);
        settings.setDomStorageEnabled(true);
        settings.setDefaultTextEncodingName("UTF-8");
        settings.setAllowContentAccess(true); // 是否可访问Content Provider的资源,默认值 true
        settings.setAllowFileAccess(true);    // 是否可访问本地文件,默认值 true
        // 是否允许通过file url加载的Javascript读取本地文件,默认值 false
        settings.setAllowFileAccessFromFileURLs(false);
        // 是否允许通过file url加载的Javascript读取全部资源(包括文件,http,https),默认值 false
        settings.setAllowUniversalAccessFromFileURLs(false);
        //开启JavaScript支持
        settings.setJavaScriptEnabled(true);
        // 支持缩放
        settings.setSupportZoom(true);
        // 扩大比例的缩放
        settings.setUseWideViewPort(true);

        // 加载WebChromeClient
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                progressBar.setProgress(newProgress);
                if (newProgress >= 100) {
                    progressBar.setVisibility(View.GONE);
                }
                super.onProgressChanged(view, newProgress);
            }

        });

        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Log.e(TAG, "request ========= Loading ========> " + url);
                urlList.clear();
                resList.clear();

                urlList.add(url);
                if (!url.startsWith("http")) {
                    view.stopLoading();
                    return true;
                } else {
                    view.loadUrl(url);
                    return false;
                }
            }

            @Override
            public void onLoadResource(WebView view, String url) {
                super.onLoadResource(view, url);
                // 收集资源数据
                boolean exist = false;
                for (String u : resList) {
                    if (u.equals(url)) {
                        exist = true;
                        break;
                    }
                }
                if (!exist) {
                    resList.add(url);
                }
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                progressBar.setVisibility(View.VISIBLE);
                super.onPageStarted(view, url, favicon);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                progressBar.setVisibility(View.GONE);
                view.loadUrl("javascript:window.local_obj.showSource(''+" + "document.getElementsByTagName('html')[0].innerHTML+'');");
                super.onPageFinished(view, url);
            }

            @SuppressLint("NewApi")
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
                // 屏蔽规则
                try {
                    for (int i = 0; i < clrList.size(); i++) {
                        if (url.contains(clrList.get(i))) {
                            Log.e(TAG, "拦截"+clrList.get(i));
                            WebResourceResponse response = new WebResourceResponse("text/html", "utf-8", null);
                            return response;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return super.shouldInterceptRequest(view, url);
            }
        });

        webView.addJavascriptInterface(new JavaScriptLocalObj(), "local_obj");

        webView.loadUrl(url);

        fLayout.addView(webView);
    }


    class JavaScriptLocalObj {
        @JavascriptInterface
        @SuppressWarnings("unused")
        public void showSource(String html) {
//            Log.d(TAG, "html====> " + html);
            elementStr = html;
            handler.sendEmptyMessage(0);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (popupWindow != null && popupWindow.isShowing()) {
                popupWindow.dismiss();
                return true;
            }
            if (webView.canGoBack()) {
                webView.goBack();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        System.exit(0);
    }

    MyHandler handler = new MyHandler();

    class MyHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    ImageView imageView = new ImageView(mContext);
                    imageView.setImageResource(R.drawable.ic_send);
                    FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(120, 120);
                    lp.gravity = Gravity.RIGHT | Gravity.BOTTOM;
                    lp.setMargins(10, 10, 30, 30);
                    imageView.setLayoutParams(lp);
                    imageView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            showPop();

                            Log.e(TAG, "url => " + urlList.size() + ", res => " + resList.size());

                        }
                    });
                    fLayout.addView(imageView);
                    break;

                // 保存要过滤的host
                case 1:
                    String host = (String) msg.obj;
                    Iterator<String > iterator = clrList.iterator();
                    boolean exist = false;
                    while (iterator.hasNext()){
                        if (iterator.next().equals(host)){
                            iterator.remove();
                            exist = true;
                        }
                    }
                    if (!exist){
                        clrList.add(host);
                    }
                    break;
            }
        }
    }


    /**
     * 资源弹窗
     */
    private void showPop() {
        if (popupWindow == null) {
            popupWindow = new PopupWindow(mContext);
        } else if (popupWindow.isShowing()) {
            popupWindow.dismiss();
            return;
        }

        final View view = LayoutInflater.from(mContext).inflate(R.layout.pop_layout, null);
        popupWindow.setContentView(view);
        popupWindow.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
        popupWindow.setHeight(DeviceUtils.getWidAndHei(mContext)[1] - 100);
        popupWindow.setBackgroundDrawable(new ColorDrawable(0));
        popupWindow.setAnimationStyle(R.style.popAnim);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setTouchable(true);
        popupWindow.setFocusable(true);
        popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
        popupWindow.showAtLocation(fLayout, Gravity.BOTTOM, 0, 0);

        final FrameLayout layout = view.findViewById(R.id.frame_layout);

        // 源码
        view.findViewById(R.id.element_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                layout.removeAllViews();

                EditText editText = new EditText(mContext);
                editText.setBackgroundResource(android.R.color.transparent);
                editText.setText(elementStr);
                editText.setTextSize(9);
                editText.setFocusable(true);
                editText.setFocusableInTouchMode(true);
                editText.setPadding(10, 10, 10, 10);
                editText.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                layout.addView(editText);

            }
        });
        // 资源
        view.findViewById(R.id.resource_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                layout.removeAllViews();

                ListView listView = new ListView(mContext);
                UrlAdapter adapter = new UrlAdapter(resList, clrList, 1, handler);
                listView.setAdapter(adapter);
                listView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                layout.addView(listView);
            }
        });
        // 过滤
        view.findViewById(R.id.filter_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                layout.removeAllViews();

                ListView listView = new ListView(mContext);
                UrlAdapter adapter = new UrlAdapter(clrList, clrList, 0, handler);
                listView.setAdapter(adapter);
                listView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                layout.addView(listView);
            }
        });

        final WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = 0.6f;
        getWindow().setAttributes(lp);
        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                lp.alpha = 1f;
                getWindow().setAttributes(lp);
            }
        });
    }
}