转载请注明出处,侵权可耻!可耻!可耻!
公司项目需要用到在线显示PDF格式的文件,但是试了好多方法都达不到需求,无奈只能伪造成在线查看的假象了。
就是先将pdf格式的文件下载到手机本地,再显示,当用户离开查看页面的时候再将下载的文件删掉。
如果遇到手机没内存此方法不可行。
清单文件的权限
<uses-permission android:name="android.permission.INTERNET" />
<!-- 外存储写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 外存储读权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
加入依赖
compile 'com.github.barteksc:android-pdf-viewer:2.8.2'
然后在布局文件中引用
<com.github.barteksc.pdfviewer.PDFView
android:id="@+id/pdfView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
1.文件下载
后台给的接口返回的地址是以“.aspx”结尾的,ios那边直接一个webview就能加载出来(这也是爬了很久的坑之后发现的)。地址放在浏览器上也是可以直接打开的,然后右键另存为就会发现这是一个PDF格式的文件。
这里的文件地址不能直接下载文件,需要浏览器自动重定向到可下载的地址,所以用webview加载,等自动跳转到可下载的地址后再启用下载
直接上代码
webView.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
// 监听下载功能,当用户点击下载链接的时候,直接调用系统的浏览器来下载
downloadBySystem(url, contentDisposition, mimetype);
}
});
@SuppressLint("NewApi")
private void downloadBySystem(String url, String contentDisposition, String mimeType) {
// 指定下载地址
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
// 允许媒体扫描,根据下载的文件类型被加入相册、音乐等媒体库
request.allowScanningByMediaScanner();
// 设置通知的显示类型,下载进行时和完成后显示通知
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
// 设置通知栏的标题,如果不设置,默认使用文件名
// request.setTitle("This is title");
// 设置通知栏的描述
// request.setDescription("This is description");
// 允许在计费流量下下载
request.setAllowedOverMetered(true);
// 允许该记录在下载管理界面可见
request.setVisibleInDownloadsUi(false);
// 允许漫游时下载
request.setAllowedOverRoaming(true);
// 允许下载的网路类型,默认为所有网络都允许
// request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
// request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE);
// 设置下载文件保存的路径和文件名
fileName = UUID.randomUUID().toString() + URLUtil.guessFileName(url, contentDisposition, mimeType);
if (fileName.endsWith("aspx")) {//修改文件后缀名
fileName = fileName.subSequence(0, fileName.length() - 4) + "pdf";
}
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
// 另外可选一下方法,自定义下载路径
// request.setDestinationUri()
// request.setDestinationInExternalFilesDir()
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
// 添加一个下载任务
downloadId = downloadManager.enqueue(request);
Log.e("downloadId:{}", downloadId + "");
DownloadObserver mDownloadObserver = new DownloadObserver(mHandler, MyWebActivity.this, downloadId);
getContentResolver().registerContentObserver(Uri.parse("content://downloads/"), true, mDownloadObserver);
}
2.那我们怎么知道下载什么时候完成呢?
当然是用广播,新建一个广播类
public class DownloadCompleteReceiver extends BroadcastReceiver {
public static String complete = "DownLoadComplete";
@Override
public void onReceive(Context context, Intent intent) {
Log.e("onReceive. intent:{}", intent != null ? intent.toUri(0) : null);
if (intent != null) {
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
//这里执行打开的操作
}
}
}
这样就完了?没有
在webview的那个activity中,定义个全局变量,全局,全局
private DownloadCompleteReceiver receiver;
在onCreate方法中注册广播(destroy方法中要解注册,所以广播类定义成全局),也可在清单文件中静态注册,根据自己需求
/**
* 动态注册广播
*/
private void initBroadCast() {
receiver = new DownloadCompleteReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(receiver, intentFilter);
}
3.下载完成后打开文件
打开PDF文件要在类中implements OnPageChangeListener, OnLoadCompleteListener, OnDrawListener 这些接口,然后实现里面的方法
public void openPdf(String fileName) {
//从文件中读取pdf并显示
String path = "/storage/emulated/0/Download/" + fileName;
if (fileName.endsWith(".pdf")) {
pdfFile = new File(path);
displayFromFile(pdfFile);
}
}
private void displayFromFile(File file) {
if (file != null) {
if (file.exists()) {
//ToastUtil.showToast("加载完成");
pdfView.fromFile(file) //设置pdf文件地址
.defaultPage(0) //设置默认显示第1页
.onPageChange(this) //设置翻页监听
.onLoad(this) //设置加载监听
.onDraw(this) //绘图监听
.enableSwipe(true) //是否允许翻页,默认是允许翻
.load();
} else {
Log.e(TAG, "displayFromFile: 文件不存在");
}
} else {
Log.e(TAG, "displayFromFile: 文件null");
}
}
4.离开页面时删掉文件
在onDestroy方法中删除
if (pdfFile != null && pdfFile.isFile() && isDelete) {
pdfFile.delete();
}
最后,有一点需要说明,接收广播的广播类和要显示文件的页面通常不在一个类中,要实现的方法很多,用接口回调或者EventBus都可以,根据自己情况
到此全部结束,仅供学习参考(如有bug,深表惭愧)