//使用dexmaker生成动态代理代理PrintDocumentAdapter.WriteResultCallback和PrintDocumentAdapter.LayoutResultCallback方法依赖 implementation 'org.droidparts.dexmaker:dexmaker-mockito:1.5' // web - pdf private lateinit var file : File private var dexCacheFile: File? = null // 获取需要打印的webview适配器 private var printAdapter: PrintDocumentAdapter? = null private var ranges: Array<PageRange>? = null private var descriptor: ParcelFileDescriptor? = null /** * 将webView中的内容生成到PDF格式 * @param webView 需要打印的webView * */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) private fun printPDFFile(webView: WebView) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { /** * android 5.0之后,出于对动态注入字节码安全性德考虑,已经不允许随意指定字节码的保存路径了,需要放在应用自己的包名文件夹下。 */ //新的创建DexMaker缓存目录的方式,直接通过context获取路径 dexCacheFile = getDir("dex", 0) if (!dexCacheFile!!.exists()) { dexCacheFile?.mkdir() } try { //创建待写入的PDF文件,PDFPATH为自行指定的PDF文件路径 file = File(PDFPATH) if (file.exists()){ file.delete() } file.createNewFile() descriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE) // 设置打印参数 val attributes = PrintAttributes.Builder() .setMediaSize(PrintAttributes.MediaSize.ISO_A4) .setResolution(PrintAttributes.Resolution("id", Context.PRINT_SERVICE, 300, 300)) .setColorMode(PrintAttributes.COLOR_MODE_COLOR) .setMinMargins(PrintAttributes.Margins.NO_MARGINS) .build() //打印所有界面 ranges = arrayOf(PageRange.ALL_PAGES) printAdapter = webView.createPrintDocumentAdapter("test") // 开始打印 printAdapter!!.onStart() printAdapter!!.onLayout(attributes, attributes, CancellationSignal(), getLayoutResultCallback(InvocationHandler { proxy, method, args -> if (method.name == "onLayoutFinished") { // 监听到内部调用了onLayoutFinished()方法,即打印成功 onLayoutSuccess() } else { // 监听到打印失败或者取消了打印 } null }, dexCacheFile!!.absoluteFile), Bundle()) } catch (e: IOException) { e.printStackTrace() } } } /** * @throws IOException */ @Throws(IOException::class) private fun onLayoutSuccess() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { val callback = getWriteResultCallback(InvocationHandler { o, method, objects -> if (method.name == "onWriteFinished") { //ToastUtils.showShort("导出成功") // PDF文件写入本地完成,导出成功 Log.e("onLayoutSuccess", "onLayoutSuccess") } else { //ToastUtils.showShort("导出失败") Log.e("onLayoutFailure", "onLayoutFailure") } null }, dexCacheFile!!.absoluteFile) //写入文件到本地 try { printAdapter!!.onWrite(ranges, descriptor, CancellationSignal(), callback) }catch (e:IllegalStateException){ e.printStackTrace() } } else { ToastUtils.showShort("当前系统不支持该功能") } } companion object { @SuppressLint("NewApi") @Throws(IOException::class) fun getLayoutResultCallback(invocationHandler: InvocationHandler, dexCacheDir: File): PrintDocumentAdapter.LayoutResultCallback { return ProxyBuilder.forClass(PrintDocumentAdapter.LayoutResultCallback::class.java) .dexCache(dexCacheDir) .handler(invocationHandler) .build() } @SuppressLint("NewApi") @Throws(IOException::class) fun getWriteResultCallback(invocationHandler: InvocationHandler, dexCacheDir: File): PrintDocumentAdapter.WriteResultCallback { return ProxyBuilder.forClass(PrintDocumentAdapter.WriteResultCallback::class.java) .dexCache(dexCacheDir) .handler(invocationHandler) .build() }
Android 将webView中的内容生成到PDF文件中
猜你喜欢
转载自blog.csdn.net/DengDongQi/article/details/80497402
今日推荐
周排行