Android 如何本地加载pdf文件

大部分app打开pdf文件是通过intent调起手机中能打开pdf文件的工具,来查看pdf文件,如果需求是,用户在app内下载好pdf文件后,不通过第三方的工具,本地打开。

这样的需求要怎么实现呢?上网查了一些资料,发现了一个很好用PDF开源库。

使用起来也很简单,首先添加PDFView的引用

compile 'com.github.barteksc:android-pdf-viewer:2.4.0'

布局中引用PdfView

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">

 <include layout="@layout/common_title" />

 <com.github.barteksc.pdfviewer.PDFView
  android:id="@+id/pdf_view"
  android:layout_width="match_parent"
  android:layout_height="match_parent" />
</LinearLayout>

接下来就是下载pdf文件,为了节省用户资源,在每次下载之前检查一下本地是否有该pdf文件,如果有直接打开,没有的话再去下载。

这里我写了一个加载中的对话框,打开过程中和下载过程中用的都是这一个

if (CheckFileExist(title)){
   builderShow = new CustomDialog(ShowPDFActivity.this);
   LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   View view = inflater.inflate(R.layout.dialog_pdf_progress_new, null);
   builderShow.setContentView(view);
   builderShow.show();
   isDownload=false;
   refushUI();
  }else {
   isDownload=true;
   DownLoadPDF.getInstance().downLoadPDF(ShowPDFActivity.this, //下载路径);

  }

如果本地有pdf文件,则开始加载pdf文件,refushUI();

public void refushUI(){
  try {
   pdfView.fromFile(new File(//pdf文件的绝对路径,//标题))
     .defaultPage(1)
     .enableAnnotationRendering(false)
     .onLoad(new OnLoadCompleteListener() {
      @Override
      public void loadComplete(int nbPages) {
       if (isDownload){
        DownLoadPDF.getInstance().closeDilaoig();
       }
       if (builderShow != null&&builderShow.isShowing()) {
        builderShow.dismiss();
       }
      }
     })
     .scrollHandle(null)
     .load();
  }catch (Exception e){
   e.printStackTrace();
  }
 }

PDFView加载pdf文件有两种形式,一种是从文件中读取,还有一种就是从assets目录中读取

private void displayFromAssets(String assetFileName ) {
  pdfView.fromAsset(assetFileName) //设置pdf文件地址
    .defaultPage(6)   //设置默认显示第1页
    .onPageChange(this)  //设置翻页监听
    .onLoad(this)   //设置加载监听
    .onDraw(this)   //绘图监听
    .showMinimap(false)  //pdf放大的时候,是否在屏幕的右上角生成小地图
    .swipeVertical( false ) //pdf文档翻页是否是垂直翻页,默认是左右滑动翻页
    .enableSwipe(true) //是否允许翻页,默认是允许翻页
    // .pages( 2 , 3 , 4 , 5 ) //把2 , 3 , 4 , 5 过滤掉
    .load();
 }

 private void displayFromFile( File file ) {
  pdfView.fromFile(file) //设置pdf文件地址
    .defaultPage(6)   //设置默认显示第1页
    .onPageChange(this)  //设置翻页监听
    .onLoad(this)   //设置加载监听
    .onDraw(this)   //绘图监听
    .showMinimap(false)  //pdf放大的时候,是否在屏幕的右上角生成小地图
    .swipeVertical( false ) //pdf文档翻页是否是垂直翻页,默认是左右滑动翻页
    .enableSwipe(true) //是否允许翻页,默认是允许翻
    // .pages( 2 , 3 , 4 , 5 ) //把2 , 3 , 4 , 5 过滤掉
    .load();
 }

本地没有pdf文件,需要从服务端获取,

 DownLoadPDF.getInstance().downLoadPDF(ShowPDFActivity.this, //下载路径);

public class DownLoadPDF {
 private static Context context;
 private static File file ;
 private static CustomDialog builder = null ;
 private static Handler ddhandle;
 private static DownLoadPDF instance = null;
 public static DownLoadPDF getInstance(){
  if(instance==null){
   synchronized (DownLoadPDF.class){
    if(instance==null){
     instance = new DownLoadPDF();
    }
   }
  }
  return instance;
 }
 public void downLoadPDF(final Context con, final String url, final String title, final Handler ddhandler) {
  ddhandle = ddhandler;
  context = con;
  builder = new CustomDialog(con);
  LayoutInflater inflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  View view = inflater.inflate(R.layout.dialog_pdf_progress_new, null);
  builder.setContentView(view);
  builder.show();

  new Thread() {
   @Override
   public void run() {
    try {
     file = getFileFromServer(url,title);
     sleep(200);
     if (file != null) {
      handler.sendEmptyMessage(2);
     }
    } catch (Exception e) {
     e.printStackTrace();
     builder.dismiss();
     handler.sendEmptyMessage(-1);
    }
   }
  }.start();
 }
 public void closeDilaoig(){
  if (builder != null&&builder.isShowing()) {
   builder.dismiss();
  }
 }public static int length ;
 public static File getFileFromServer(String path,String title)
   throws Exception {
  // 如果相等的话表示当前的sdcard挂载在手机上并且是可用的
  if (Environment.getExternalStorageState().equals(
    Environment.MEDIA_MOUNTED)) {
   URL url = new URL(path);
   HttpURLConnection conn = (HttpURLConnection) url.openConnection();
   conn.setConnectTimeout(5000);
   conn.setDoInput(true);
   conn.connect();
   length = conn.getContentLength();
   InputStream is = conn.getInputStream();
   //将pdf文件存储在指定文件夹下
   File filePath = new File(//指定文件夹路径);
   if (!filePath.exists()){
    filePath.mkdir();
   }
   File file = new File(filePath , title+".pdf");
   FileOutputStream fos = new FileOutputStream(file);
   BufferedInputStream bis = new BufferedInputStream(is);
   byte[] buffer = new byte[1024];
   int len;
   while ((len = bis.read(buffer)) != -1) {
    fos.write(buffer, 0, len);
    handler.sendEmptyMessage(0);
   }
   fos.close();
   bis.close();
   is.close();
   return file;
  } else {
   handler.sendEmptyMessage(-1);
   return null;
  }
 }
 private static Handler handler = new Handler(){
  @Override
  public void handleMessage(Message msg) {
   super.handleMessage(msg);
   switch (msg.what) {
   case 0:
    break;
   case -1:
    //下载失败
    Toast.makeText(context, "下载失败,请稍后再试!", Toast.LENGTH_SHORT).show();
    break;
   case 2:
    ddhandle.sendEmptyMessage(100);
    break;
   default:
    break;
   }
  }

 };
}

大家可以看到,在pdf问价下载成功的时候handler.sendEmptyMessage(2);,当case为2的时候,通过调用该工具类的页面传过来的ddhandle重新发送了一个消息,

调用界面收到消息后会重新调用refushUI();这个方法来打开pdf文件。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • Android 中SwipeRefreshLayout与ViewPager滑动事件冲突解决方法

    Android 中SwipeRefreshLayout与ViewPager滑动事件冲突解决方法 问题描述: 开发中发现,SwipeRefreshLayout的下拉刷新,与ViewPager开发的banner的左右滑动事件有一点冲突,导致banner的左右滑动不够顺畅.很容易在banner的左右滑动的过程中,触发SwipeRefreshLayout的下拉刷新,从而导致banner左右滑动的体验很差. 解决方案: 可以在ViewPager的滑动时候设置SwipeRefreshLayout暂时不可用,

  • Android数据持久化之Preferences机制详解

    本文实例讲述了Android数据持久化之Preferences机制.分享给大家供大家参考,具体如下: 在Android中,实现数据持久化有五种方式:Preferences,文件File,I/O操作.SQLite数据库,ContentProvider组件. 下面逐个做一简单的介绍: 一.Preferences的介绍: Preferences是一种轻量级的数据存储机制,他将一些简单的数据类型的数据,包括boolean类型,int类型,float类型,long类型以及String类型的数据,以键值对的

  • Android利用FlexboxLayout轻松实现流动布局

    前言 相信大家应该都有所体会,在以前我们要实现流动性布局,比较繁琐,Google开源了一个项目叫FlexboxLayout,相信大家都不陌生.下面我们来学习一下FlexboxLayout基础知识,并通过一个案例来加深理解.如果你对FlexboxLayout很熟悉,请忽略本文. 一.什么是 Flexbox 简单来说 Flexbox 是属于web前端领域CSS的一种布局方案,是2009年W3C提出了一种新的布局方案,可以响应式地实现各种页面布局,并且 React Native 也是使用的 Flex

  • android手机端与PC端使用adb forword通信

    PC端与Android手机端使用adb forword通信 服务器端代码如下: import java.io.IOException; import java.io.ObjectOutputStream; import java.net.Socket; import java.net.UnknownHostException; import java.util.Scanner; public class Server { public static final String TAG = "ser

  • Android 7.0行为变更 FileUriExposedException解决方法

    Android 7.0行为变更 FileUriExposedException解决方法 当我们开发关于[在应用间共享文件]相关功能的时候,在Android 7.0上经常会报出此运行时异常,那么Android 7.0以下没问题的代码,为什么跑到Android 7.0+的设备上运行就出问题了呢?,这主要来自于Android 7.0的一项[行为变更]! 对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI

  • Android startActivityForResult实例详解

    Android startActivityForResult实例详解 startActivityForResult用于两个activity之间的数据传递,Activity1传值给Activity2,Activity2再返回值给Activity1. 第一步:Activity1中:startActivityForResult(Intent intent, Int requestCode) Intent intent = new Intent(); intent.setClass(Activity1.

  • Android在Fragment中实现监听触摸事件

    本文给大家介绍的是监听Fragment的触摸事件实现.如果大家有更好的机制,可以留言交流,下面来看看详细的介绍: 大家都知道,我们的activity中有onTouchEvent方法,可以用来实现触摸事件的监听. activity的触摸事件 @Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); } 但是对于Fragment,其中却没有这个方法,如果我们在fragmen

  • Android数据持久化之File机制分析

    本文实例讲述了Android数据持久化之File机制.分享给大家供大家参考,具体如下: 在使用Java SE平台开发C/S结构的软件中,File 的IO输入输出流的使用率是非常高的,通过使用IO输入输出流可以对存储介质上的文件进行读写操作,下面的代码就是实现一个在Android平台上使用File对象操作文件的功能: package com.example.data_file; import java.io.File; import java.io.FileInputStream; import

  • Android 使用FragmentTabhost代替Tabhost

    Android 使用FragmentTabhost代替Tabhost 前言: 现在Fragment使用越来越广了,虽然Fragment寄生在Activity下,但是它的出现对于开发者来说是一件非常幸运的事,使开发的效率更高效了,好了下面就说说 FragmentTabhost的使用,因为Tabhost已经不推荐使用了,现在一般都使用FragmentTabhost!我本身也个菜鸟,就是帮帮新手,因为Fragment是3.0才出现,为了避免3.0以下的使用不了,所以我们要用v4包来支持,不要倒错包哦!

  • Android 如何本地加载pdf文件

    大部分app打开pdf文件是通过intent调起手机中能打开pdf文件的工具,来查看pdf文件,如果需求是,用户在app内下载好pdf文件后,不通过第三方的工具,本地打开. 这样的需求要怎么实现呢?上网查了一些资料,发现了一个很好用PDF开源库. 使用起来也很简单,首先添加PDFView的引用 compile 'com.github.barteksc:android-pdf-viewer:2.4.0' 布局中引用PdfView <LinearLayout xmlns:android="ht

  • Android开发实现加载网络图片并下载至本地SdCard的方法

    本文实例讲述了Android开发实现加载网络图片并下载至本地SdCard的方法.分享给大家供大家参考,具体如下: package com.example.myimagedemo; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; imp

  • android动态加载布局文件示例

    一.布局文件part.xml: 复制代码 代码如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="

  • Android 加载asset文件夹下边的图片

    将asset中的图片文件加载到ImageView中 // load image try { // get input stream InputStream ims = getAssets().open("avatar.jpg"); // load image as Drawable Drawable d = Drawable.createFromStream(ims, null); // set image to ImageView mImage.setImageDrawable(d)

  • Android中Glide加载库的图片缓存配置究极指南

    零.选择Glide 为什么图片加载我首先推荐Glide? 图片加载框架用了不少,从afinal框架的afinalBitmap,Xutils的BitmapUtils,老牌框架universalImageLoader,著名开源组织square的picasso,google推荐的glide到FaceBook推出的fresco.这些我前前后后都体验过,那么面对这么多的框架,该如何选择呢?下面简单分析下我的看法. afinal和Xuils在github上作者已经停止维护了,开源社区最新的框架要属KJFra

  • Android中WebView加载网页设置进度条

    本文实例为大家分享了Android中WebView加载网页设置进度条的具体代码,供大家参考,具体内容如下 效果: xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" a

  • 详解Android GLide图片加载常用几种方法

    目录 缓存浅析 GLide图片加载方法 图片加载周期 图片格式(Bitmap,Gif) 缓存 集成网络框架 权限 占位符 淡入效果 变换 启动页/广告页 banner 固定宽高 圆角 圆形 总结 缓存浅析 为啥要做缓存? android默认给每个应用只分配16M的内存,所以如果加载过多的图片,为了 防止内存溢出 ,应该将图片缓存起来. 图片的三级缓存分别是: 1.内存缓存 2.本地缓存 3.网络缓存 其中,内存缓存应优先加载,它速度最快:本地缓存次优先加载,它速度也快:网络缓存不应该优先加载,它

  • Android开发之加载图片的方法

    本文实例讲述了Android开发之加载图片的方法.分享给大家供大家参考.具体分析如下: 加载网络上的图片需要在manifest中配置访问网络的权限,如下: <uses-permission android:name="android.permission.INTERNET" /> 如果不配置这个权限的话,会报错:unknown host exception. package com.example.loadimgfromweb; import java.io.InputSt

  • Android 中动态加载.jar的实现步骤

    首先第一个是 jar 文件的制作,Java 里面直接把 .class 文件打包到 .jar 文件里面就可以了,但是 Android 的 Dalvik VM 是不认 Java 的 byte code 的,所以不能直接这么打包,而要用 dx 工具转成 Dalvik byte code 才可以.当然,dx 工具转了之后,jar 包里面就不 是 .class 文件了,而是 .dex 文件. 第二个是,Android 里面虽然也提供了 URLClassLoader 的实现,但是并不能用.要动态加载其它类,

  • Android中如何加载数据缓存

    最近app快完工了,但是很多列表加载,新闻咨询等数据一直从网络请求,速度很慢,影响用户体验,所以寻思用缓存来加载一些更新要求不太高的数据 首先做一个保存缓存的工具类 import java.io.File; import java.io.IOException; import android.content.Context; import android.os.Environment; import android.util.Log; /** * 缓存工具类 */ public class Co

随机推荐