For anyone looking for the compose way to do this as of August 2025:
The code has been adapted from @Pisoj your awesome man
also from https://dev.to/boryanz/webviews-download-listener-on-android-how-it-works-5a01
val context = LocalContext.current
val webView = remember(context) {
WebView(context).apply {
settings.javaScriptEnabled = true
this.webViewClient = object : WebViewClient() {
// you do you
}
this.setDownloadListener { url, userAgent, contentDisposition, mimeType, contentLength ->
val request = DownloadManager.Request(url.toUri())
// Extract filename from contentDisposition or URL
val filename = getFileName(contentDisposition, url)
val cookies = CookieManager.getInstance().getCookie(url.toString());
request.apply {
setTitle(filename)
setDescription("Downloading file...")
addRequestHeader("cookie", cookies)
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename)
setMimeType(mimeType)
}
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE ) as DownloadManager
downloadManager.enqueue(request)
Toast.makeText(context, "Download started", Toast.LENGTH_SHORT).show()
}
}
}
CompositionLocalProvider(LocalContext provides context) {
Box(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
{
AndroidView(
modifier = Modifier,
factory = { webView }, update = {
it.loadUrl("https://yourwebsite.com")
}
)
}
}
Notes:
For you to download files via webview in compose you need the DownloadListener interface.
If your files require cookie authentication please ensure you add cookies in download manager otherwise your file will appear to download but on opening will issue corrupted files.
Cheers