Android H5+Native开发遇到的问题以及解决方案

1、webView软件盘遮挡输入框问题

/**
 * 用于解决全屏时,Activity设置了adjustSize却不起作用的问题。setContentView之后调用{@link #assistActivity(Activity)}
 */
public class AndroidBug5497Workaround {

    public static void assistActivity(Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;
    private int contentHeight;
    private boolean isfirst = true;
    private Activity activity;
    private int statusBarHeight;

    private AndroidBug5497Workaround(Activity activity) {
        //获取状态栏的高度
        int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
        statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);
        this.activity = activity;
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        //界面出现变动都会调用这个监听事件
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                if (isfirst) {
                    contentHeight = mChildOfContent.getHeight();//兼容华为等机型
                    isfirst = false;
                }
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams)
                mChildOfContent.getLayoutParams();
    }

    //重新调整跟布局的高度
    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        //当前可见高度和上一次可见高度不一致 布局变动
        if (usableHeightNow != usableHeightPrevious) {
            //int usableHeightSansKeyboard2 = mChildOfContent.getHeight();//兼容华为等机型
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard / 4)) {
                // keyboard probably just became visible
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    //frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                    frameLayoutParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;
                } else {
                    frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                }
            } else {
                frameLayoutParams.height = contentHeight;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    /**
     * 计算mChildOfContent可见高度 ** @return
     */
    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    }
}

2、给H5提供打电话功能

 myWebView.setWebViewClient(new WebViewClient(){
           @Override
           public boolean shouldOverrideUrlLoading(WebView webView, String href_url) {
               String tag = "tel:";
               if (href_url.contains(tag)) {
                   Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(href_url));
                   startActivity(intent);
                   return true;
               }else{
                   myWebView.loadUrl(url);
               }
               return super.shouldOverrideUrlLoading(webView, url);
           }
       });

第二种方式是进行JS+原生交互,提供原生方法
3、解决H5无法定位问题

 webSettings.setDomStorageEnabled(true);
 webSettings.setDatabaseEnabled(true);
 webSettings.setGeolocationEnabled(true);
 myWebView.setWebChromeClient(new WebChromeClient(){
           @Override
           public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
               callback.invoke(origin,true,false);
               super.onGeolocationPermissionsShowPrompt(origin, callback);
           }
       });

4、添加webView中图片长按保存功能(base64图片),保存到相册

 myWebView.setOnLongClickListener(new View.OnLongClickListener() {
           @Override
           public boolean onLongClick(View v) {
                WebView.HitTestResult result =((WebView)v).getHitTestResult();
                if(null==result)return false;
                int type = result.getType();
                if(type==WebView.HitTestResult.UNKNOWN_TYPE) return false;
                if(type==WebView.HitTestResult.IMAGE_TYPE||type==WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE){
                    final String imageUrl = result.getExtra();
                    if(imageUrl.contains(",")&&imageUrl.contains("base64")) {
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                saveImageToPhotos(imageUrl);
                            }
                        }).start();
                    }
                }
               return false;
           }
       });
    }
    public void saveImageToPhotos(String data) {
        if (TextUtils.isEmpty(data)) //图像数据为空
            return;
        String[] split = data.split(",");
        OutputStream fos = null;
        try {
            //Base64解码
            byte[] b = Base64.decode(split[1] , Base64.DEFAULT);
            for(int i=0;i<b.length;++i) {
                if(b[i]<0) {//调整异常数据
                    b[i]+=256;
                }
            }

            String path = Environment.getExternalStorageDirectory()
                    + File.separator + Environment.DIRECTORY_DCIM
                    + File.separator + "Camera" + File.separator;
            File currentFile = new File(path, "豫事办健康码.png");
            fos = new FileOutputStream(currentFile);
            fos.write(b);
            fos.flush();
            fos.close();
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    LSToast.getInstance(BaseX5WebViewActivity.this).show("保存成功",Toast.LENGTH_SHORT);
                }
            });

            // 最后通知图库更新
            this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                    Uri.fromFile(currentFile)));
        }catch (Exception e) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    LSToast.getInstance(BaseX5WebViewActivity.this).show("保存失败",Toast.LENGTH_SHORT);
                }
            });
            return ;
        }finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

5、webView跨域Android需支持

try {
            if (Build.VERSION.SDK_INT >= 16) {
                Class<?> clazz = myWebView.getSettings().getClass();
                Method method = clazz.getMethod(
                        "setAllowUniversalAccessFromFileURLs", boolean.class);
                if (method != null) {
                    method.invoke(myWebView.getSettings(), true);
                }
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        try {
            LogUtil.d("Nat: webView.syncCookie.url", url);
            CookieSyncManager.createInstance(this);
            CookieManager cookieManager = CookieManager.getInstance();
            cookieManager.setAcceptCookie(true);
            cookieManager.removeSessionCookie();// 移除
            cookieManager.removeAllCookie();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                cookieManager.setAcceptThirdPartyCookies(myWebView, true);//重要
            }
            String oldCookie = cookieManager.getCookie(url);
            if (oldCookie != null) {
                LogUtil.d("Nat: webView.syncCookieOutter.oldCookie", oldCookie);
            }
            StringBuilder sbCookie = new StringBuilder();
            sbCookie.append(String.format("access" + "=%s", token));
            sbCookie.append(String.format(";domain=%s", getDomainName(url)));
            sbCookie.append(String.format(";path=%s", "/"));
            String cookieValue = sbCookie.toString();
            cookieManager.setCookie(url, cookieValue);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                cookieManager.flush();
            } else {
                CookieSyncManager.getInstance().sync();
            }
            String newCookie = cookieManager.getCookie(url);
            if (newCookie != null) {
                LogUtil.d("Nat: webView.syncCookie.newCookie", newCookie);
            }
        } catch (Exception e) {
            LogUtil.e("Nat: webView.syncCookie failed", e.toString());
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值