Android webview转PDF的方法示例
时间:2019-04-13
本文章向大家介绍Android webview转PDF的方法示例,主要包括Android webview转PDF的方法示例使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1.网上找了好多没有显示出来效果不错,后来看到调用手机打印预览,看了效果还不错,就打算使用系统打印服务预览下载
2.‘webView.createPrintDocumentAdapter()'得到打印的PrintDocumentAdapter有了该类就可以使用onWrite方法写入制定的文件,但是这个方法需要传入回调这个悲剧的是这个回调方法是hiden的我们没办法调用
3,字怎么解决呢,有连个方法
3.1 使用此开源库替换自己的sdk 中的android.jar文件,就可以使用了
https://github.com/anggrayudi/android-hidden-api
3.2 使用dexmaker生成动态代理代理PrintDocumentAdapter.WriteResultCallback和PrintDocumentAdapter.LayoutResultCallback方法依赖地址
compile 'org.droidparts.dexmaker:dexmaker-mockito:1.5'
4.完整代码如下:
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM + "/PDFTest.pdf"); File dexCacheFile; // 获取需要打印的webview适配器 PrintDocumentAdapter printAdapter; PageRange[] ranges; ParcelFileDescriptor descriptor; /** a* @param webView */ private void 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文件,pdfFilePath为自行指定的PDF文件路径 if (file.exists()) { file.delete(); } file.createNewFile(); descriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE); // 设置打印参数 PrintAttributes attributes = new PrintAttributes.Builder() .setMediaSize(PrintAttributes.MediaSize.ISO_A4) .setResolution(new PrintAttributes.Resolution("id", Context.PRINT_SERVICE, 300, 300)) .setColorMode(PrintAttributes.COLOR_MODE_COLOR) .setMinMargins(PrintAttributes.Margins.NO_MARGINS) .build(); //打印所有界面 ranges = new PageRange[]{PageRange.ALL_PAGES}; printAdapter = webView.createPrintDocumentAdapter(); // 开始打印 printAdapter.onStart(); printAdapter.onLayout(attributes, attributes, new CancellationSignal(), getLayoutResultCallback(new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("onLayoutFinished")) { // 监听到内部调用了onLayoutFinished()方法,即打印成功 onLayoutSuccess(); } else { // 监听到打印失败或者取消了打印 } return null; } }, dexCacheFile.getAbsoluteFile()), new Bundle()); } catch (IOException e) { e.printStackTrace(); } } } /** * @throws IOException */ private void onLayoutSuccess() throws IOException { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { PrintDocumentAdapter.WriteResultCallback callback = getWriteResultCallback(new InvocationHandler() { @Override public Object invoke(Object o, Method method, Object[] objects) throws Throwable { if (method.getName().equals("onWriteFinished")) { Toast.makeText(MainActivity.this,"Success",Toast.LENGTH_SHORT).show(); // PDF文件写入本地完成,导出成功 Log.e("onLayoutSuccess","onLayoutSuccess"); } else { Toast.makeText(MainActivity.this,"导出失败",Toast.LENGTH_SHORT).show(); } return null; } }, dexCacheFile.getAbsoluteFile()); //写入文件到本地 printAdapter.onWrite(ranges, descriptor, new CancellationSignal(), callback); }else { Toast.makeText(MainActivity.this,"不支持4.4.以下",Toast.LENGTH_SHORT).show(); } } @SuppressLint("NewApi") public static PrintDocumentAdapter.LayoutResultCallback getLayoutResultCallback(InvocationHandler invocationHandler, File dexCacheDir) throws IOException { return ProxyBuilder.forClass(PrintDocumentAdapter.LayoutResultCallback.class) .dexCache(dexCacheDir) .handler(invocationHandler) .build(); } @SuppressLint("NewApi") public static PrintDocumentAdapter.WriteResultCallback getWriteResultCallback(InvocationHandler invocationHandler, File dexCacheDir) throws IOException { return ProxyBuilder.forClass(PrintDocumentAdapter.WriteResultCallback.class) .dexCache(dexCacheDir) .handler(invocationHandler) .build(); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
- 人人公司收购Trucker Path 称或入局无人车领域
- nginx+tomcat单个域名及多个域名配置
- bootstrap源码分析之tab(选项卡)
- bootstrap源码分析之scrollspy(滚动侦听)
- volatile
- 用最简单的图文带你看懂区块链
- 微信小游戏正式上线!小程序的一个类目,即点即玩!
- CentOS7安装GitLab、汉化、邮箱配置及使用
- Bootstrap源码分析之transition、affix
- Redis从单机到集群,一步步教你环境部署以及使用
- C++内存管理学习堆和栈
- 人人公司宣布收购美国卡车社区平台Trucker Path
- Mysql字符串截取总结:left()、right()、substring()、substring_index()
- c++程序的内存格局
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- [译]在Solidity中创建无限制列表
- java安全编码指南之:声明和初始化
- java安全编码指南之:表达式规则
- java安全编码指南之:Number操作
- 如何提高代码质量
- 小姐姐非要问我:spring编程式事务是啥?
- 阿里3面:Spring声明式事务连环炮,让我措手不及。。
- 旷视科技|商用端侧Raw图像降噪方案
- Python | 时间戳转换
- Stata | 2020年国家社科基金立项名单分析
- 还在用Guava Cache?它才是Java本地缓存之王
- 死信队列的消息处理方案
- 【Ceph】Rook 中使用 External Cluster 的方式管理外部集群
- Redis排行榜的设计与实现
- 血的教训 | 一次订单号重复的事故差点被开除