webview支持input標(biāo)簽

webview input說(shuō)明

安卓webview禁用input,網(wǎng)上查看各種方案,都存在弊端。
經(jīng)過(guò)實(shí)踐,完整可用調(diào)研了支持拍照和圖片選擇上傳。

1、webview支持input標(biāo)簽
2、安卓拍照支持適配7.0 takePhoto

1、webview 初始化和銷(xiāo)毀

    //webview初始化
    @SuppressLint("SetJavaScriptEnabled")
    public static void initX5Web(WebView x5Webview) {
        Context context = x5Webview.getContext();
        WebSettings webSetting = x5Webview.getSettings();
        webSetting.setJavaScriptEnabled( true );
        webSetting.setAllowFileAccess( true );
        webSetting.setLayoutAlgorithm( WebSettings.LayoutAlgorithm.NARROW_COLUMNS );
        webSetting.setSupportZoom( false );
        webSetting.setBuiltInZoomControls( false );
        webSetting.setDisplayZoomControls(false);   //不顯示webview縮放按鈕
        webSetting.setUseWideViewPort( true );
        //多窗口問(wèn)題
        webSetting.setSupportMultipleWindows( false );
        webSetting.setJavaScriptCanOpenWindowsAutomatically( true );

        //h5數(shù)據(jù)存儲(chǔ)
        webSetting.setAppCacheEnabled( true );
        webSetting.setDomStorageEnabled( true );
        webSetting.setDatabaseEnabled(true);
        webSetting.setAppCachePath(context.getDir("appcache", 0).getPath());

        webSetting.setGeolocationEnabled( true );
        webSetting.setAppCacheMaxSize( Long.MAX_VALUE );
        webSetting.setDatabasePath(context.getDir("databases", 0).getPath());
        webSetting.setGeolocationDatabasePath(context.getDir("geolocation", 0).getPath());
        webSetting.setPluginState( WebSettings.PluginState.ON_DEMAND );
        webSetting.setRenderPriority( WebSettings.RenderPriority.HIGH );
        webSetting.setCacheMode( WebSettings.LOAD_NO_CACHE );
        //sonic
        x5Webview.removeJavascriptInterface("searchBoxJavaBridge_");
        webSetting.setAllowContentAccess(true);
        webSetting.setSavePassword(false);
        webSetting.setSaveFormData(false);
        webSetting.setLoadWithOverviewMode(true);
        webSetting.setDefaultTextEncodingName("utf-8");
        webSetting.setLoadsImagesAutomatically(true);
    }

    //webview銷(xiāo)毀方法
    public static void onDestroy(WebView mWebView){
        if (mWebView != null) {
            mWebView.clearHistory();
            ((ViewGroup) mWebView.getParent()).removeView(mWebView);
            mWebView.loadUrl("about:blank");
            mWebView.stopLoading();
            mWebView.setWebChromeClient(null);
            mWebView.setWebViewClient(null);
            mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
            mWebView.clearHistory();
            mWebView.destroy();
        }
    }

2、webchrome特別支持

  • 1、 initWebChrome
    //webview input 特別支持幫助類(lèi)
    private WebViewUploadFileHelper helper = new WebViewUploadFileHelper(this);

    private void initWebChrome() {
        webview.setWebChromeClient( new InputFileWebChromeClient() );
    }

public class InputFileWebChromeClient extends WebChromeClient {
    //設(shè)置 進(jìn)度條
    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        super.onProgressChanged( view, newProgress );
    }

    // For Android < 3.0
    public void openFileChooser(ValueCallback<Uri> uploadMsg) {
        helper.setUploadMessage( uploadMsg );
        permission( () -> {
            helper.openImageActivity();
        } );
    }

    // For Android 3.0+
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
        helper.setUploadMessage( uploadMsg );
        permission( () -> {
            helper.openImageActivity( acceptType );
        } );
    }

    // For Android  > 4.1.1
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
        helper.setUploadMessage( uploadMsg );
        permission( () -> {
            helper.openImageActivity( acceptType, capture );
        } );
    }

    // For Android  >= 5.0
    public boolean onShowFileChooser(com.tencent.smtt.sdk.WebView webView,
                                     ValueCallback<Uri[]> filePathCallback,
                                     WebChromeClient.FileChooserParams fileChooserParams) {
        helper.setUploadMessageAboveL( filePathCallback );
        permission( () -> {
            helper.openImageActivity( fileChooserParams.getAcceptTypes(), fileChooserParams.isCaptureEnabled() );
        } );
        return true;
    }

    //==多窗口的問(wèn)題
    @Override
    public boolean onCreateWindow(WebView view, boolean isDialog,
                                  boolean isUserGesture, Message resultMsg) {
        WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
        transport.setWebView( view );
        resultMsg.sendToTarget();
        return true;
    }
}
  • 2 、回調(diào)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       //回調(diào)支持
        super.onActivityResult(requestCode, resultCode, data);
        helper.onActivityResult(requestCode, resultCode, data);
    }
  • 3 、權(quán)限
    @SuppressLint("CheckResult")
    public void permission(CallBack callBack){
       // 權(quán)限支持
        RxPermissions rxPermissions = new RxPermissions( this );
        rxPermissions.request(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
                .subscribe(grant -> {
                    if (grant) {
                        //全部通過(guò)
                        try {
                            if (callBack!=null){
                                callBack.onSucess();
                            }
                        } catch (Throwable throwable) {
                            throwable.printStackTrace();
                        }
                    } else {
                            ToastUtils.show("請(qǐng)同意權(quán)限");
                    }
                });
    }

    public interface CallBack{
        void onSucess();
    }

3、WebViewUploadFileHelper 幫助類(lèi)

將input相關(guān)方法封裝在一個(gè)幫助類(lèi)中,便于多處復(fù)用


public class WebViewUploadFileHelper {

    private ValueCallback<Uri> uploadMessage;
    private ValueCallback<Uri[]> uploadMessageAboveL;
    private final static int FILE_CHOOSER_RESULT_CODE = 10011;//文件選擇
    private Uri imageUri;
    private Activity activity;

    private WebViewUploadFileHelper() {
    }

    public WebViewUploadFileHelper(Activity activity) {
        this.activity = activity;
    }

    public void setUploadMessage(ValueCallback<Uri> uploadMessage) {
        this.uploadMessage = uploadMessage;
    }

    public void setUploadMessageAboveL(ValueCallback<Uri[]> uploadMessageAboveL) {
        this.uploadMessageAboveL = uploadMessageAboveL;
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode != FILE_CHOOSER_RESULT_CODE) return;

        // 經(jīng)過(guò)上邊(1)、(2)兩個(gè)賦值操作,此處即可根據(jù)其值是否為空來(lái)決定采用哪種處理方法
        if (uploadMessage != null) {
            chooseBelow( resultCode, data );
        } else if (uploadMessageAboveL != null) {
            chooseAbove( resultCode, data );
        }

    }

    public void openImageActivity() {
        chooseImage( "image/*" );
    }

    public void openImageActivity(String acceptType) {
        chooseImage( acceptType );
    }

    public void openImageActivity(String acceptType, String capture) {
        if (StringUtils.equals( capture, "camera" )) {
            takePhoto();
        } else {
            chooseImage( acceptType );
        }
    }

    public void openImageActivity(String[] acceptType, boolean isCaptureEnabled) {
        if (isCaptureEnabled) {
            takePhoto();
        } else {
            chooseImage( acceptType );
        }
    }

    private void chooseBelow(int resultCode, Intent data) {

        if (RESULT_OK == resultCode) {
            updatePhotos();

            if (data != null) {
                // 這里是針對(duì)文件路徑處理
                Uri uri = data.getData();
                if (uri != null) {
                    uploadMessage.onReceiveValue( uri );
                } else {
                    uploadMessage.onReceiveValue( null );
                }
            } else {
                // 以指定圖像存儲(chǔ)路徑的方式調(diào)起相機(jī),成功后返回data為空
                uploadMessage.onReceiveValue( imageUri );
            }
        } else {
            uploadMessage.onReceiveValue( null );
        }
        uploadMessage = null;
    }

    private void chooseAbove(int resultCode, Intent data) {
        if (RESULT_OK == resultCode) {
            updatePhotos();

            if (data != null) {
                // 這里是針對(duì)從文件中選圖片的處理
                Uri[] results;
                Uri uriData = data.getData();
                if (uriData != null) {
                    results = new Uri[]{uriData};
                    uploadMessageAboveL.onReceiveValue( results );
                } else {
                    uploadMessageAboveL.onReceiveValue( null );
                }
            } else {
                uploadMessageAboveL.onReceiveValue( new Uri[]{imageUri} );
            }
        } else {
            uploadMessageAboveL.onReceiveValue( null );
        }
        uploadMessageAboveL = null;
    }

    private void updatePhotos() {
        // 該廣播即使多發(fā)(即選取照片成功時(shí)也發(fā)送)也沒(méi)有關(guān)系,只是喚醒系統(tǒng)刷新媒體文件
        Intent intent = new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE );
        intent.setData( imageUri );
        activity.sendBroadcast( intent );
    }

    //調(diào)用相機(jī)
    private void takePhoto() {
        String fileName = "IMG_" + DateFormat.format( "yyyyMMdd_hhmmss", Calendar.getInstance( Locale.CHINA ) ) + ".jpg";
        // 步驟一:創(chuàng)建存儲(chǔ)照片的文件
        String imagePath = activity.getFilesDir() + File.separator + "images" + File.separator + fileName;
        File file = new File( imagePath );
        //創(chuàng)建文件夾
        if (!file.getParentFile().exists())
            file.getParentFile().mkdirs();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //步驟二:Android 7.0及以上獲取文件 Uri
            imageUri = FileProvider.getUriForFile( activity, activity.getPackageName() + ".fileprovider", file );
        } else {
            //步驟三:獲取文件Uri
            imageUri = Uri.fromFile( file );
        }

        Intent intent = new Intent();
        intent.addFlags( Intent.FLAG_GRANT_READ_URI_PERMISSION );
        intent.setAction( MediaStore.ACTION_IMAGE_CAPTURE );//設(shè)置Action為拍照
        intent.putExtra( MediaStore.EXTRA_OUTPUT, imageUri );//將拍取的照片保存到指定URI
        activity.startActivityForResult( intent, FILE_CHOOSER_RESULT_CODE );
    }

    //圖片選擇器
    private void chooseImage(String[] acceptType) {
        Intent i = new Intent( Intent.ACTION_GET_CONTENT );
        i.addCategory( Intent.CATEGORY_OPENABLE );
        i.setType( "*/*" );
        i.putExtra( Intent.EXTRA_MIME_TYPES, acceptType );
        activity.startActivityForResult( i, FILE_CHOOSER_RESULT_CODE );
    }

    //圖片選擇器
    private void chooseImage(String acceptType) {
        Intent i = new Intent( Intent.ACTION_GET_CONTENT );
        i.addCategory( Intent.CATEGORY_OPENABLE );
        if (TextUtils.isEmpty( acceptType )) {
            i.setType( "*/*" );
        } else {
            i.setType( acceptType );
        }
        activity.startActivityForResult( Intent.createChooser( i, "Image Chooser" ), FILE_CHOOSER_RESULT_CODE );
    }

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類(lèi)型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,675評(píng)論 1 32
  • Tips 由于WebView的用法實(shí)在太多,如果您只是想查詢(xún)某個(gè)功能的使用——建議Ctrl+F(Commad+F)...
    BugDev閱讀 7,914評(píng)論 11 109
  • WebView簡(jiǎn)介 String getUrl():獲取當(dāng)前頁(yè)面的URL。 reload():重新reload當(dāng)前...
    QM閱讀 3,315評(píng)論 0 52
  • WebView常用方法 String getUrl():獲取當(dāng)前頁(yè)面的URL。 reload():重新reload...
    JuSong閱讀 7,539評(píng)論 0 3
  • 關(guān)于 android Webview 基本使用 加載html四種方式 簡(jiǎn)單使用 在AndroidManifest....
    小面包屑閱讀 5,638評(píng)論 2 13

友情鏈接更多精彩內(nèi)容