Continuously my downloaded file was corrupting I handled this as:
JavaScriptInterface.kt
package com.hamza.hiwhatsappweb.utils
import android.R
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Environment
import android.os.Handler
import android.util.Base64
import android.util.Log
import android.webkit.JavascriptInterface
import android.widget.Toast
import androidx.core.app.NotificationCompat
import androidx.core.content.FileProvider
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
class JavaScriptInterface(private val context: Context) {
@JavascriptInterface
@Throws(IOException::class)
fun getBase64FromBlobData(base64Data: String) {
Log.e("mimeType", "getBase64FromBlobData: $mimTp")
convertBase64StringToPdfAndStoreIt(base64Data)
}
@Throws(IOException::class)
private fun convertBase64StringToPdfAndStoreIt(base64PDf: String) {
Log.e("BASE 64", base64PDf)
val notificationId = 1
val dwldsPath = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/$fileName")
val pdfAsBytes =
Base64.decode(base64PDf.replaceFirst("^data:$mimTp;base64,".toRegex(), ""), 0)
val os = FileOutputStream(dwldsPath, false)
os.write(pdfAsBytes)
os.flush()
if (dwldsPath.exists()) {
val intent = Intent()
intent.action = Intent.ACTION_VIEW
val apkURI = FileProvider.getUriForFile(context, context.applicationContext.packageName + ".provider", dwldsPath)
intent.setDataAndType(apkURI, mimTp)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
val pendingIntent =
PendingIntent.getActivity(context, 1, intent, PendingIntent.FLAG_CANCEL_CURRENT)
val CHANNEL_ID = "MYCHANNEL"
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel =
NotificationChannel(CHANNEL_ID, "name", NotificationManager.IMPORTANCE_HIGH)
val notification = Notification.Builder(
context, CHANNEL_ID
)
.setContentText(fileName)
.setContentTitle("File downloaded")
.setContentIntent(pendingIntent)
.setChannelId(CHANNEL_ID)
.setSmallIcon(R.drawable.sym_action_chat)
.build()
if (notificationManager != null) {
notificationManager.createNotificationChannel(notificationChannel)
notificationManager.notify(notificationId, notification)
}
} else {
val b = NotificationCompat.Builder(context, CHANNEL_ID)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.sym_action_chat) //.setContentIntent(pendingIntent)
.setContentTitle("MY TITLE")
.setContentText("MY TEXT CONTENT")
if (notificationManager != null) {
notificationManager.notify(notificationId, b.build())
val h = Handler()
val delayInMilliseconds: Long = 1000
h.postDelayed({ notificationManager.cancel(notificationId) }, delayInMilliseconds)
}
}
}
Toast.makeText(context, "PDF FILE DOWNLOADED!", Toast.LENGTH_SHORT).show()
}
companion object {
var mimTp:String = ""
var fileName:String = ""
fun getBase64StringFromBlobUrl(blobUrl: String, mimeType: String,fileName:String): String {
mimTp = mimeType
this.fileName = fileName
return if (blobUrl.startsWith("blob")) {
"javascript: var xhr = new XMLHttpRequest();" +
"xhr.open('GET', '" + blobUrl + "', true);" +
"xhr.setRequestHeader('Content-type','$mimeType');" +
"xhr.responseType = 'blob';" +
"xhr.onload = function(e) {" +
" if (this.status == 200) {" +
" var blobPdf = this.response;" +
" var reader = new FileReader();" +
" reader.readAsDataURL(blobPdf);" +
" reader.onloadend = function() {" +
" base64data = reader.result;" +
" Android.getBase64FromBlobData(base64data);" +
" }" +
" }" +
"};" +
"xhr.send();"
} else "javascript: console.log('It is not a Blob URL');"
}
}
}
Set this property on Webview:
binding?.webView?.addJavascriptInterface(JavaScriptInterface(applicationContext), "Android")
binding?.webView?.settings?.pluginState = WebSettings.PluginState.ON
binding?.webView?.setDownloadListener { url, _, contentDisposition, mimetype, _ ->
// downloadFiles(url, mimetype, contentDisposition)
val pdfUrl: String? = url?.trim()?.replace("blob:", "")
val fileName = URLUtil.guessFileName(pdfUrl, contentDisposition, mimetype)
binding?.webView?.loadUrl(JavaScriptInterface.getBase64StringFromBlobUrl(url,mimetype,fileName))
}
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>
Paste this code under Application in AndroidManifest.xml file
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>