1. 程式人生 > >關於android webview 的那些坑

關於android webview 的那些坑

近日做專案的時候使用webview 遇到一些麻煩。

第一條:H5頁面選擇圖片時,點選無效。(無法選擇照片)

第二條:當修復完第一條bug時,出現新bug,如果選擇照片時,什麼都不選返回,會出現無法點選的情況。

第三條:如何開啟PDF格式的檔案

首先第一個問題,h5中呼叫攝像頭的程式碼是:

<input accept="image/*" capture="camera" id="imgFile" name="imgFile" type="file">。

在PC端以及手機瀏覽器可以正常點選並且選擇圖片,但是嵌入到APP的webview中,點選沒有任何反應。

解決方案  重寫 WebChromeClient

裡面的方法

mWebView.setWebChromeClient(new WebChromeClient() {

            //配置許可權(同樣在WebChromeClient中實現)
            @Override
            public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
                callback.invoke(origin, true, false);
                super.onGeolocationPermissionsShowPrompt(origin, callback);
            }

            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                
            }

            // For Android < 3.0
            public void openFileChooser(ValueCallback<Uri> uploadMsg) {
                mUploadMessage = uploadMsg;
                showOptions();

            }

            // For Android  > 4.1.1
            public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
                mUploadMessage = uploadMsg;
                showOptions();
            }

            // For Android > 5.0支援多張上傳
            @Override
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> uploadMsg, WebChromeClient.FileChooserParams
                    fileChooserParams) {
                mUploadCallbackAboveL = uploadMsg;
                showOptions();
                return true;
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                tvTitle.setText(title);
            }


        });

第二個問題,是在第一個問題修復完的情況下,我已經可以選擇照片了,但是在選擇的過程中,點選了取消或者返回,無法重複回撥onShowFileChooseropenFileChooser方法,就會有無法選擇圖片的bug。

      logcat 

打印出log:

Attempted to finish an input event but the input event receiver has already been disposed

解決方案:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //圖片上傳
        if ((null == mUploadMessage) && (mUploadCallbackAboveL == null)) {
            return;
        }

        if (requestCode == PHOTO_REQUEST_GALLERY) {
            if (data != null) {
                ArrayList<ImageItem> images = (ArrayList<ImageItem>) data.getSerializableExtra(ImagePicker.EXTRA_RESULT_ITEMS);
                ImageItem imageItem = images.get(0);


//                File file = new File(imageItem.path);
//                //壓縮
//                File newFile = CompressHelper.getDefault(this).compressToFile(file);
//                //壓縮轉為bitmap
//                Bitmap bitmap = BitmapFactory.decodeFile(newFile.toString());

                Uri uri = Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), ImageUtils.ratio(imageItem.path, 950, 1280), null, null));
                if (mUploadCallbackAboveL != null) {
                    Uri[] uris = new Uri[]{uri};
                    mUploadCallbackAboveL.onReceiveValue(uris);
                    mUploadCallbackAboveL = null;
                } else {
                    mUploadMessage.onReceiveValue(uri);
                    mUploadMessage = null;
                }

            }else{

            }

        }


        if (resultCode==RESULT_CANCELED){
            cancelFilePathCallback();
        }

    }

    /**
     *取消mFilePathCallback回撥
     */
    private void cancelFilePathCallback() {
        if (mUploadMessage != null) {
            mUploadMessage.onReceiveValue(null);
            mUploadMessage = null;
        } else if (mUploadCallbackAboveL != null) {
            mUploadCallbackAboveL.onReceiveValue(null);
            mUploadCallbackAboveL = null;
        }
    }
第三個問題 如何開啟PDF 檔案,這個我們的需求是直接用Webview開啟PDF 檔案,或者跳轉到手機瀏覽器下載 ,我的做法是 
重寫 WebViewClient 這個類的方法 
shouldOverrideUrlLoading 
 mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, final String url) {

                Log.e("url","url="+url);

                if (url.contains("tel")) {
                    android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(FlashLoanH5DetailActivity.this);
                    builder.setTitle("溫馨提示").setMessage("是否詢問客服?").setNegativeButton("取消", null).setPositiveButton("確定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
                            //android6.0後可以對許可權判斷

                            if (ActivityCompat.checkSelfPermission(FlashLoanH5DetailActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                                Toast.makeText(FlashLoanH5DetailActivity.this, "請在應用管理中開啟“電話”訪問許可權!", Toast.LENGTH_SHORT).show();
                                ActivityCompat.requestPermissions(FlashLoanH5DetailActivity.this, new String[]{Manifest.permission.CAMERA}, 1);//許可權申請
                                return;
                            }

                            startActivity(intent);
                        }
                    }).show();
                    return true;
                }


                if (url.contains(".pdf")){
                    Intent intent = new Intent();
                    intent.setAction("android.intent.action.VIEW");
                    Uri content_url = Uri.parse(url);
                    intent.setData(content_url);
                    startActivity(intent);
                }

                return super.shouldOverrideUrlLoading(view, url);
            }
        });

以上內容參考文章 

http://www.jianshu.com/p/e4fe8871af78

12.19日更新

昨天在載入一個本地網頁遊戲的時候,遇到了一個bug。顯示不出來遊戲的對話方塊。

解決方案: //不加這句不能用
        webSettings.setDomStorageEnabled(true);//啟用dom儲存(關鍵就是這句),貌似網上twitter顯示有問題也是這個屬性沒有設定的原因