作者簡介 原創(chuàng)微信公眾號郭霖 WeChat ID: guolin_blog
又到了周五啦,提前祝大家周末愉快!
本篇來自釗林的投稿,分享了一個解決WebView文件上傳無法重復(fù)選擇問題的方案,希望能夠幫助到大家。
釗林的博客地址:
http://teachcourse.cn
正文
Android?開發(fā)使用WebView控件加載包含表單的 H5 網(wǎng)頁,點擊上傳文件按鈕,彈出對話框,選擇從相冊獲取照片、拍照或打開手機文件管理器,從 Android 手機選取一張圖片或一個文件,然后通過ValueCallback接口傳遞,在 WebView 加載的 H5網(wǎng)頁 顯示。
這里有一個問題,點擊“取消”或返回按鈕,無法重復(fù)回調(diào)onShowFileChooser或openFileChooser方法,控制臺打印:
Attempted to finish an input event but the input event receiver has already been disposed
一、深入理解onShowFileChooser或openFileChooser
WebChromeClient各個方法這里不再贅述,特殊說明關(guān)于 WebChromeClient,它既不是接口也不是抽象類,但聲明的方法很多方法體都是空的,這是讓釗林感到疑惑之一。查看 WebView 源碼,setWebChromeClient()傳入WebChromeClient對象,然后使用傳入的對象,調(diào)用 WebChromeClient 聲明的方法,再將一些參數(shù)傳遞返回 WebChromeClient 空方法體。在 WebView 源碼里面代碼也很簡單,詳細(xì)的處理處理邏輯看不到,這是讓釗林感到疑惑之二,感覺像一個黑箱子。
然后就一直想,那么重寫 WebChromeClient 的方法有什么作用呢?先看一下onShowFileChooser,如下:
該方法的作用,告訴當(dāng)前APP,打開一個文件選擇器,比如:打開相冊、啟動拍照或打開本地文件管理器,實際上更好的理解,WebView加載包含上傳文件的表單按鈕,HTML 定義了 input 標(biāo)簽,同時 input 的 type 類型為 file,手指點擊該按鈕,回調(diào)onShowFileChooser這個方法,在這個重寫的方法里面打開相冊、啟動照片或打開本地文件管理器,甚至做其他任何的邏輯處理,點擊一次回調(diào)一次的前提是請求被取消,而取消該請求回調(diào)的方法:給ValueCallback接口的onReceiveValue抽象方法傳入null,同時 onShowFileChooser 方法返回true;
ValueCallback的抽象方法被回調(diào)onShowFileChooser方法返回true;反之返回false;再來看一下 openFileChooser 的源碼,如下:
在所有發(fā)布的SDK版本中,openFileChooser是一個隱藏的方法,使用onShowFileChooser代替,但是最好同時重寫showFileChooser和openFileChooser方法,Android 4.4.X以上的系統(tǒng)回調(diào)onShowFileChooser方法,低于或等于 Android 4.4.X的系統(tǒng)回調(diào)openFileChooser方法,只重寫onShowFileChooser或openFileChooser造成在有的系統(tǒng)可以正常回調(diào),在有的系統(tǒng)點擊沒有反應(yīng)。
仔細(xì)分析onShowFileChooser和openFileChooser回調(diào)方法,這兩個方法之間的區(qū)別:
第一個區(qū)別:前者ValueCallback接口回傳一個Uri數(shù)組,后者回傳一個Uri對象,在onActivityResult回調(diào)方法中調(diào)用ValueCallback接口方法onReceiveValue傳入?yún)?shù)特別注意。
第二個區(qū)別:前者 將 后者的 acceptType、capture 封裝成 FileChooserParams 抽象類
二、實例展示onShowFileChooser或openFileChooser處理過程
這是實例運行的效果圖,H5表單寫入兩個上傳文件的按鈕,點擊其中一個從底部彈出對話框,選擇相冊文件或拍照,點擊“取消”按鈕,再次點擊“上傳文件”按鈕能夠再次回調(diào)onShowFileChooser或openFileChooser方法。
在之前的理解中,誤解onShowFileChooser或openFileChooser只能打開相冊或啟動相機拍照,其實不僅僅是這樣,onShowFileChooser或openFileChooser既然是一個回調(diào)的方法,可以重復(fù)執(zhí)行各種邏輯代碼,比如:啟動另一個Activity、彈窗對話框、錄制視頻或錄音等
在上面的例子中,執(zhí)行彈窗操作,將彈窗的處理代碼放置onShowFileChooser或openFileChooser方法體,如下:
點擊彈窗取消按鈕、點擊打開相冊取消操作或取消拍照,可能無法再次回調(diào)onShowFileChooser或openFileChooser方法,如果你沒有在點擊彈窗取消方法中或onActivityResult回調(diào)方法resultCode==RESULT_CANCELED處理,再次點擊上傳按鈕,打印出 log:
Attempted to finish an input event but the input event receiver has already been disposed
同時,點擊沒有效果。解決方案:
在不期待回調(diào) mFilePathCallback 的 onReceiveValue 方法時,調(diào)用?cancelFilePathCallback(),解決點擊上傳按鈕無法重復(fù)回調(diào)的問題。
完。。。。。。。。。。。。。。。。。。。。。
文章原創(chuàng)作者GuoLin 書籍推薦
郭林大神原創(chuàng)android 書籍:《第一行代碼 android》