Ini merupakan catatanku setelah beberapa jam mencari cara untuk upload file di Webview menggunakan kotlin akhirnya bisa juga. Kode yang aku share di sini hanya untuk handling pemilihan file saja. Tidak termasuk kodingan untuk upload di sisi server. Untuk kodingan upload file di sisi server mungkin bisa melihat tutorial Cara Upload Gambar Menggunakan Ajax dan PHP.
Permasalahan
Ketika kita menggunakan WebView di sebuah aplikasi android untuk menampilkan form yang di dalamnya terdapat input type file maka kita tidak bisa memilih file yang akan diupload. Aku tidak tahu apakah itu merupakah bug dari WebView atau memang disengaja dibuat seperti itu dengan alasan keamanan.
Solusi
Kita harus membuat handling khusus menggunakan WebChromeClient() agar Webview yang kita gunakan bisa digunakan untuk memilih file yang akan diupload. Setelah file tersebut dipilih, selanjutnya diparse kedalam WebView lagi melalui onActivityResult() .
Membuat Handling Pemilihan File
Kode di bawah ini digunakan untuk mengahdel pemilihan file pada webview.
//deklarasikan ini sebagai variabel global
var uploadMessage:ValueCallback<Array<Uri>>? = null
private val FILECHOOSER_RESULTCODE = 1
val REQUEST_SELECT_FILE = 100
//setup webChromeClient()
mWebView?.webChromeClient = object:WebChromeClient() {
override fun onJsAlert(view: WebView, url: String, message: String, result: JsResult): Boolean {
Log.d("alert", message)
val dialogBuilder = AlertDialog.Builder(requireContext())
dialogBuilder.setMessage(message)
.setCancelable(false)
.setPositiveButton("OK") { _, _ ->
result.confirm()
}
val alert = dialogBuilder.create()
alert.show()
return true
}
// For 3.0+ Devices (Start)
// onActivityResult attached before constructor
fun openFileChooser(uploadMsg : ValueCallback<Uri>, acceptType:String) {
mUploadMessage = uploadMsg
val i = Intent(Intent.ACTION_GET_CONTENT)
i.addCategory(Intent.CATEGORY_OPENABLE)
i.type = "*/*"
startActivityForResult(Intent.createChooser(i, "File Browser"), FILECHOOSER_RESULTCODE)
}
// For Lollipop 5.0+ Devices
override fun onShowFileChooser(mWebView:WebView, filePathCallback:ValueCallback<Array<Uri>>, fileChooserParams:WebChromeClient.FileChooserParams):Boolean {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
if (uploadMessage != null) {
uploadMessage?.onReceiveValue(null)
uploadMessage = null
}
uploadMessage = filePathCallback
val intent = fileChooserParams.createIntent()
try {
startActivityForResult(intent, REQUEST_SELECT_FILE)
} catch (e: ActivityNotFoundException) {
uploadMessage = null
Toast.makeText(requireContext(), "Cannot Open File Chooser", Toast.LENGTH_LONG).show()
return false
}
return true
}else{
return false
}
}
//For Android 4.1 only
fun openFileChooser(uploadMsg:ValueCallback<Uri>, acceptType:String, capture:String) {
mUploadMessage = uploadMsg
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "*/*"
startActivityForResult(Intent.createChooser(intent, "File Browser"), FILECHOOSER_RESULTCODE)
}
fun openFileChooser(uploadMsg:ValueCallback<Uri>) {
//filePermission()
mUploadMessage = uploadMsg
val i = Intent(Intent.ACTION_GET_CONTENT)
i.addCategory(Intent.CATEGORY_OPENABLE)
i.type = "*/*"
startActivityForResult(Intent.createChooser(i, "File Browser"), FILECHOOSER_RESULTCODE)
}
}Parse Hasil Pemilihan File Kedalam WebView
Kode untuk memarse hasil pemilihan file kedalam Webview adalah sebagai berikut:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
if(requestCode == REQUEST_SELECT_FILE){
if(uploadMessage != null){
uploadMessage?.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode,data))
uploadMessage = null
}
}
}else if(requestCode == FILECHOOSER_RESULTCODE){
if(mUploadMessage!=null){
var result = data?.data
mUploadMessage?.onReceiveValue(result)
mUploadMessage = null
}
}else{
Toast.makeText(requireContext(),"Failed to open file uploader, please check app permissions.",Toast.LENGTH_LONG).show()
super.onActivityResult(requestCode, resultCode, data)
}
}




