技术标签: Android之应用实战 android
android项目中在webview中打开pdf。
关于android打开pdf文件方法有多种,下面的文章有详细说明:
总结一下:
1、WebView 中调用 GoogleDocs
这个方案要翻墙!!!
2、调起第三方支持 PDF 阅读的应用
建议使用这种方法,扩展性兼容性强,可以扩展为支持其他的文件格式。但是如果用户手机没有安装PDF的应用,就比较尴尬了。
3、集成第三方 PDF SDK,在 Native 页面中阅读
第三方包很大,APK体积会增大20M左右,不介意APK体积的可以采用。
4、将 PDF 文件转换成 HTML 或者图片等格式文件
这种方案是比较low,但是能解决部分问题
5、集成第三方JS:pdf.js
这种方案有两种方式集成:服务端和客户端,因为准备在android端实现所以介绍客户端集成的方案。
客户端集成也有两种方式,
①将pdf.js和相关的文件全部下载下来并拷贝的工程中的assets目录。pdf.js和相关文件体积也比较大(5M左右),同样会增加APK体积,但是这种方式更快,全部都是本地资源,不需要每次都联网加载pdf.js文件。
②就是使用CDN的方式。在asset目录想编写html文件和js文件,加载网络中的pdf.js的相关资源。但是相对第一中方法比较慢,如果而且文件过大,会报错。具体实现参考文章 Android中显示PDF的问题解决(安卓端使用pdf.js CDN模式)
我使用的是集成第三方的pdf.js,并且把所有资源下载到本地。
核心方法
1、pdf.js资源到android项目的asset目录 下载地址 http://mozilla.github.io/pdf.js/getting_started/#download
2、使用webview加载viewer.html界面
mWebView.loadUrl(file:///android_asset/pdf/web/viewer.html?file=PDFURl)
(其中PDFURL为pdf文件路径,可以是网络路径也可以是本地文件)
超级简单!!
但是实际操作中遇到很多的问题
1、webView 打失败,报错 unexpected server response (0) while retrieving PDF
webview的权限设置有问题,需要设置:
webSettings.setJavaScriptEnabled(true);//支持js
webSettings.setAllowFileAccess(true);;//否允许访问文件,默认允许访问
webSettings.setAllowFileAccessFromFileURLs(true);//一个文件被允许访问其他文件中的内容
webSettings.setAllowUniversalAccessFromFileURLs(true);//可以是否访问任何原始起点内容
2、打开失败, file origin does not match viewer's
处理方法:需要在web/viewer.js(1793行)中注释的代码如下:
// if (origin !== viewerOrigin && protocol !== 'blob:') {
// throw new Error('file origin does not match viewer\'s');
// }
3、低版本android手机(5.0)打开失败,
检查之后发现是低版本android浏览器不支持es6语法。
最简单的处理方法,下载es5版本的pdf.js。但是这个版本比es6版本大,有11M
在网上有文章提到 4.4及以下版本,有兼容问题,需要使用低版本的pdf.js。我们项目不支持4.4及以下版本,所有没有测试。处理方法是判断android系统版本, 4.4及以下版本使用低版本的pdf.js(文章使用的1.4版本的),高版本系统,使用当前最新的pdf.js。
4、屏蔽下载按钮
实现使用中发现,工具栏用些功能在android手机上是不能使用的,比如下载、打印。
解决方案:隐藏工具栏中的按钮,web/viewer.html找到 id="secondaryDownload",在button标签添加 style="display:none"。
注意,在文件中还有id="download"的按钮,隐藏该按钮并没有使界面中下载按钮消失
android 4.4 报错,
使用低版本的psdjs
pdfjs-1.9.426下载地址 https://pan.baidu.com/s/1wW6P-fdHpiEHD_zME0pIXQ
这个亲测可用。
但是相关的功能比新版的要少一些
开发中需要碰到的场景,需要将现有的一套系统提供给另外一个项目组进行使用,但是服务器还是用我们现有的,只是多配置两个数据库进行数据隔离,因此需要用到多数据源进行数据切换。配置多数据源两种方法,我目前的场景需要用到第一种进行配置通过aop在请求中定义标识符,告诉spring该注入哪个数据源,请求对应的数据库通过mybatis-plus进行配置httpshttpshttps。......
微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言,如果对您有所帮助:欢迎赞赏。少量代码设计一个登录界面 - .NET CORE(C#) WPF开发阅读导航本文背景代码实现本文参考源码1. 本文背景继续 MaterialDesignThemes 开源控件库学习,本文简单使用输入控件的水印附加属性:materialDesign:HintAs...
1.如果命题p为真、命题q为假,则下述哪个复合命题为真命题(B) A.p且q B.如果q则p C.非p D.如果p则q 2.p和q均是原子命题,“如果p那么q”是由p和q组合得到的复合命题。下面对“如果p那么q”这一复合命题描述不正确的是( A) A.无法用真值表来判断“如果p那么q”的真假 B....
css选择器标签选择器:针对一类标签(如:body,div,p,ul,li)ID选择器:针对某一个特定的标签使用(如:id=“demo”)类选择器:针对你想要的所有标签使用(如:class=“demo”)通用选择器(通配符):针对所有的标签都适用(如:*号)后代选择器(继承选择器):用空格隔开(如:div p,注意两选择器用空格键分开)交集选择器(组合选择器):(如:.head .head_logo,注意两选择器用空格键分开)。并集选择器:(群组选择器):用逗号隔开伪类选择器:(如:就是链
这两天在做项目的 时候遇到了这个问题,发现网上也有人提出了这个问题,但是根本没有人去解决,可能是问题太简单了。我在这里贴上我的代码,以往对大家有帮助。首先,实现的效果,希望是这样的。网上也给出了一些解决方案,但是根本没有实现动态的下拉呀。(下面贴出网上解决方案的截图)接下来再来描述一下问题。我要实现的是listview的headerview 一开
本文出处:https://www.cnblogs.com/goodhacker/p/3355660.html#undefined python的标准库里的日志系统从Python2.3开始支持。只要import logging这个模块即可使用。如果你想开发一个日志系统, 既要把日志输出到控制台, 还要写入日志文件,只要这样使用: 1 import logging 2 ...
https://blog.csdn.net/lwsas1/article/details/79556945 1.1 MinGWMinGW 是一个可自由使用和自由发布的Windows特定头文件和使用GNU工具集导入库的集合,允许你生成本地的Windows程序而不需要第三方C运行时库。简单说,MinGW是一...
单星号参数函数中的单星号参数代表此处接受任意多个非关键字参数,这些参数将以数组形式保存,例如:def foo(a, *b): print bfoo(1, 2, 3, 4, 5)执行结果为:(2, 3, 4, 5)多星号参数函数中的多星号参数代表此处接受任意多个关键字参数,这些参数以字典形式保存,例如:def foo(a, **b): print bfoo(a=1, b=2, c=3, d=4, e=5)执行结果为:{'c': 3, 'b'
先看例子,后面有对用到的知识点的总结效果图:实现代码如下:组件练习组件1菜单2//注册组件let list1 = ["北京","上海","深圳","郑州","南阳"];let list2 = ["胡歌","陈默","陶亚东","刘同"];Vue.component("custom-select",{data:function(){return {selectShow:false,val:""}},...
人工智能、机器学习泛滥。以前搜不出来,现在搜出来的太多。找自己想看的都得费半天劲。这当然是好的,有资料总比没有强。但是搞这个方向,适合自己的才是好材料。太简单,你觉得不过瘾,太深奥,你看不懂,所以文章,刚好讲到你的困惑点,对你来说才是好文章。我自己觉得,反向传播方法,UFLDL里的讲解比较适合我,通篇没有废话,简单直接,写的非常好,所以Mark一下,免得下次忘了UFLDL这个关键词,又费半...
游标中的更新和删除 在PL/SQL中依然可以使用UPDATE和DELETE语句更新或删除数据行。显式游标只有在需要获得多行数据的情况下使用。PL/SQL提供了仅仅使用游标就可以执行删除或更新记录的方法。 UPDATE或DELETE语句中的WHERE CURRENT OF子串专门处理要执行UPDATE或DELETE操作的表中取出的最近的数据。要使用这个方法,在声明游标时必须使用FOR
最简单的方法是用pgrep 获取进程号,然后kill掉