前期准备

Slf4j-android :
http://www.slf4j.org/android/

epublib-core-latest.jar :
https://github.com/downloads/psiegman/epublib/epublib-core-latest.jar (如果不能下载,试试这里)

jsoup(可以可把html标签,解析为对象):

https://github.com/jhy/jsoup

进入正题

如果你是吧 .equb 格式的文件放到 assets 文件下,你可以这样获取book对象。

MainActivity.java

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;import com.example.epubdaemon.utils.StringUtils;
import com.example.epubdaemon.utils.TimeUtils;import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;import butterknife.BindView;
import butterknife.ButterKnife;
import nl.siegmann.epublib.domain.Book;
import nl.siegmann.epublib.domain.Metadata;
import nl.siegmann.epublib.domain.Resource;
import nl.siegmann.epublib.domain.Spine;
import nl.siegmann.epublib.domain.SpineReference;
import nl.siegmann.epublib.epub.EpubReader;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";@BindView(R.id.image)ImageView mImage;@BindView(R.id.tv_text)TextView mTvText;@BindView(R.id.recycler)RecyclerView mRecycler;private Book book;private MyAdatper mAdatper;private List<EpubBean> indexTitleList = new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.bind(this);initView();}private void initView() {mRecycler.setLayoutManager(new LinearLayoutManager(this));mAdatper = new MyAdatper(indexTitleList, this);mRecycler.setAdapter(mAdatper);try {EpubReader reader = new EpubReader();InputStream in = getAssets().open("176116.epub");book = reader.readEpub(in);//获取封面图方法一:/* Bitmap coverImage = BitmapFactory.decodeStream(book.getCoverImage().getInputStream());if (coverImage!=null) {mImageView.setImageBitmap(coverImage);}else {Log.i(TAG, "onCreate: mImageView is null");}*///  获取封面图方法二:/*nl.siegmann.epublib.domain.Resources resources = book.getResources();Resource res = resources.getById("cover");byte[] data = res.getData();Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);mImage.setImageBitmap(bitmap);*/Metadata metadata = book.getMetadata();StringBuffer buffer = new StringBuffer();for (String s : metadata.getDescriptions()) {buffer.append(s + " ");}/*String bookInfo = "作者:" + metadata.getAuthors() +"\n出版社:" + metadata.getPublishers() +"\n出版时间:" + metadata.getDates() +"\n书名:" + metadata.getTitles() +"\n简介:" + metadata.getDescriptions() +"\n语言:" + metadata.getLanguage() +"\n\n封面图:";*/String bookInfo = "作者:" + metadata.getAuthors().get(0) +"\n出版社:" + metadata.getPublishers().get(0) +"\n出版时间:" + TimeUtils.getStringData(metadata.getDates().get(0).getValue()) +"\n书名:" + metadata.getTitles().get(0) +"\n简介:" + metadata.getDescriptions().get(0) +"\n语言:" + metadata.getLanguage() +"\n\n封面图:";mTvText.setText(bookInfo);// Log.i(TAG, "onCreate: bookInfo=" + bookInfo);// 书籍的阅读顺序,是一个线性的顺序。通过Spine可以知道应该按照怎样的章节,顺序去阅读,// 并且通过Spine可以找到对应章节的内容。Spine spine = book.getSpine();List<SpineReference> spineReferences = spine.getSpineReferences();if (spineReferences != null && spineReferences.size() > 0) {Resource resource = spineReferences.get(1).getResource();//获取带章节信息的那个html页面Log.i(TAG, "initView: ddd=" + resource.getId() + "  " + resource.getTitle() + "  " + resource.getSize() + " ");byte[] data = resource.getData();//和 resource.getInputStream() 返回的都是html格式的文章内容,只不过读取方式不一样String strHtml = StringUtils.bytes2Hex(data);Log.i(TAG, "initView: strHtml= " + strHtml);parseHtmlData(strHtml);/*  InputStream inputStream = resource.getInputStream();String strHtml = StringUtils.convertStreamToString(inputStream);Log.i(TAG, "initView: strHtml=" + strHtml);*/} else {Log.i(TAG, "initView: spineReferences is null");}// 获取所有章节内容。测试发现和 spine.getSpineReferences() 效果差不多/* List<Resource> contents = book.getContents();if (contents != null && contents.size() > 0) {try {Resource resource = contents.get(1);//byte[] data = resource.getData();InputStream inputStream = resource.getInputStream();String dddd = StringUtils.convertStreamToString(inputStream);Log.i(TAG, "onCreate: dddd=" + dddd);//mTextView.setText(Html.fromHtml(dddd));//  mWebView.loadDataWithBaseURL(null, dddd, "text/html", "utf-8", null);} catch (IOException e) {e.printStackTrace();}} else {Log.i(TAG, "onCreate: contents is null");}*/} catch (Exception e) {e.printStackTrace();}}/*** 解析html*/private void parseHtmlData(String strHtml) throws IOException {Document doc = Jsoup.parse(strHtml);Log.i(TAG, "parseHtmlData:  doc.title();=" + doc.title());Elements eles = doc.getElementsByTag("a"); // a标签// 遍历Elements的每个ElementEpubBean epubBean;for (Element link : eles) {String linkHref = link.attr("href"); // a标签的href属性String text = link.text();epubBean = new EpubBean();epubBean.href = linkHref;epubBean.tilte = text;indexTitleList.add(epubBean);//Log.i(TAG, "parseHtmlData: linkHref=" + linkHref + " text=" + text);}}private class MyAdatper extends RecyclerView.Adapter<MyAdatper.ViewHolder> {private final LayoutInflater mInflater;private List<EpubBean> mStrings;public MyAdatper(List<EpubBean> mStrings, Context context) {this.mStrings = mStrings;mInflater = LayoutInflater.from(context);}public class ViewHolder extends RecyclerView.ViewHolder {TextView mTextView;public ViewHolder(View itemView) {super(itemView);mTextView = (TextView) itemView.findViewById(R.id.title);}}@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = mInflater.inflate(R.layout.item, null);ViewHolder holder = new ViewHolder(view);return holder;}@Overridepublic void onBindViewHolder(ViewHolder holder, final int position) {holder.mTextView.setText(mStrings.get(position).tilte);holder.mTextView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//通过href获取String href = mStrings.get(position).href;Intent intent = new Intent(MainActivity.this, ChapterDetailActivity.class);intent.putExtra("href", href);startActivity(intent);}});}@Overridepublic int getItemCount() {return mStrings.size();}}}

布局: R.layout.activity_main :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayout
        android:layout_width="match_parent"android:layout_height="wrap_content"><ImageView
            android:id="@+id/image"android:layout_width="100dp"android:layout_height="150dp"android:src="@mipmap/ic_launcher"/><TextView
            android:id="@+id/tv_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:text="内容描述dddd"/></LinearLayout><android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>

adapter的item布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#fff"android:orientation="vertical"><TextView
        android:id="@+id/title"android:layout_width="match_parent"android:layout_height="40dp"android:background="#fff"android:gravity="center_vertical"android:paddingLeft="10dp"android:text="ddd"/><View
        android:layout_width="match_parent"android:layout_height="1dp"android:background="#eee"/></LinearLayout>

EpubBean.java

public class EpubBean {public String tilte;public String href;}

ChapterDetailActivity.java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.webkit.WebView;import com.example.epubdaemon.utils.StringUtils;import java.io.IOException;
import java.io.InputStream;import butterknife.BindView;
import butterknife.ButterKnife;
import nl.siegmann.epublib.domain.Book;
import nl.siegmann.epublib.domain.Resource;
import nl.siegmann.epublib.epub.EpubReader;public class ChapterDetailActivity extends AppCompatActivity {private static final String TAG = "ChapterDetailActivity";@BindView(R.id.webView)WebView mWebView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_chapter_detail);ButterKnife.bind(this);String href = getIntent().getStringExtra("href");Log.i(TAG, "onCreate: href=" + href);try {EpubReader reader = new EpubReader();InputStream in = getAssets().open("176116.epub");Book book = reader.readEpub(in);Resource byHref = book.getResources().getByHref(href);byte[] data = byHref.getData();   //和 resource.getInputStream() 返回的都是html格式的文章内容,只不过读取方式不一样String strHtml1 = StringUtils.bytes2Hex(data);//Log.i(TAG, "initView: strHtml1111= " + strHtml1);mWebView.getSettings().setJavaScriptEnabled(true);mWebView.loadDataWithBaseURL(null, strHtml1, "text/html", "utf-8", null);} catch (IOException e) {e.printStackTrace();}}
}

布局:R.layout.activity_chapter_detail

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><WebView
        android:id="@+id/webView"android:layout_width="match_parent"android:layout_height="match_parent"></WebView></LinearLayout>

StringUtils.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;/*** Created by yuanpk on 2018/4/26  8:43* <p>* Description:TODO*/public class StringUtils {public static String convertStreamToString(InputStream is) {/** To convert the InputStream to String we use the BufferedReader.readLine()* method. We iterate until the BufferedReader return null which means* there's no more data to read. Each line will appended to a StringBuilder* and returned as String.*/BufferedReader reader = new BufferedReader(new InputStreamReader(is));StringBuilder sb = new StringBuilder();String line = null;try {while ((line = reader.readLine()) != null) {sb.append(line + "\n");}} catch (IOException e) {e.printStackTrace();} finally {try {is.close();} catch (IOException e) {e.printStackTrace();}}return sb.toString();}public static String bytes2Hex(byte[] bs) {if (bs == null || bs.length <= 0) {return null;}Charset charset = Charset.defaultCharset();ByteBuffer buf = ByteBuffer.wrap(bs);CharBuffer cBuf = charset.decode(buf);return cBuf.toString();}
}

最后,176116.epub 的这个文件和相应工具类就不在列出了,可以到下面的 “源码下载” 中去下载。

源码下载


参考博客:

这篇文章写不错:
使用epublib解析epub文件(章节内容、书籍菜单)

android平台解析epub格式的书籍信息

Android Jsoup:实现HTML解析和Epub解析

epublib git地址:
https://github.com/psiegman/epublib

官方网站:
http://www.siegmann.nl/epublib

下面的这两个还没有做了解,先放到这里吧:
epublib解析
epub3reader

android 使用epublib开源框架解析epub文件(章节内容、书籍菜单)相关推荐

  1. Android 学习笔记之Volley开源框架解析(一)

    PS:看完了LGD的六场比赛...让人心酸... 学习内容: 1.Http请求的过程... 2.Volley的简单介绍...   1.Http请求...   这里只是简单的说一下Http请求的过程.. ...

  2. 【Android 逆向】使用 Python 解析 ELF 文件 ( Capstone 反汇编框架 | PyCharm 中导入 Capstone 反汇编框架 )

    文章目录 一.Capstone 反汇编框架 二.PyCharm 中导入 Capstone 反汇编框架 一.Capstone 反汇编框架 Android 的 APK 安装文件中 , 可能存在若干 so ...

  3. GIS开源框架:ArcGIS文件地理数据库(GDB)解析与入库

    对于GIS专业毕业的同学,想必对于ArcGIS软件不会太陌生,对于地理数据库也有一定的了解和使用经验.但是,撇开软件操作层面不谈,作为一个WebGIS/GIS开发人员,我们如何通过GIS开源框架去完成 ...

  4. epublib java_java中使用Epublib解析EPub文件

    Epublib是一个用于处理epub文件的java类库,可以对epub文件进行读写处理:而且提供了一个阅读器,可以直接运行(java -jar 方式),并可以打开epub类型的文件进行阅读:(引用官方 ...

  5. Android常用的开源框架

    在Android的开发过程中,程序员为了提高开发效率,进而缩短开发周期,他们往往会采用各种各样的开源框架,以便于达到可以快速而又简单的实现既定需求功能,下面是常用的开源框架的集合. 1.volley ...

  6. Android 2018优秀开源框架整理收藏

    中级.高级.资深工程师 知其然知其不可然 <框架百大排行榜>里所提到的流行词.流行术语--使用能力.融会贯通其原理.讲解框架能力的高低,将让你不断的在这三个级别徘徊: 会有意识的合并榜单里 ...

  7. android 优秀的开源框架整理

    程序员界有个神奇的网站,那就是github,这个网站集合了一大批优秀的开源框架,极大地节省了开发者开发的时间,在这里我进行了一下整理,这样可以使我们在使用到时快速的查找到,希望对大家有所帮助! 1. ...

  8. 【Android 逆向】使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 完整代码示例 ) ★★★

    文章目录 一.完整代码示例 二.执行结果 三.博客资源 一.完整代码示例 使用 Python 解析 ELF 文件完整代码示例 : # coding=utf-8 # 解析 elf 文件需要导入的依赖库 ...

  9. Android开发常用开源框架:图片处理

    1. 图片加载,缓存,处理 框架名称 功能描述 Android Universal Image Loader 一个强大的加载,缓存,展示图片的库,已过时 Picasso 一个强大的图片下载与缓存的库 ...

最新文章

  1. Linux使用systemctl设置程序开机自启动
  2. element-ui的NavMenu置于顶部(mode=horizontal)时,让菜单可以滚动(overflow-x:auto)(主要用于移动端的菜单显示)...
  3. Depth-first Search深度优先搜索专题2
  4. android 获取当前输入法,关于获取安卓手机系统输入法和设置输入法
  5. 程序员的职业选择,你应该知道的,持续更新ing
  6. gevent开始学习-第一步
  7. 如何解决mysql数据倾斜_什么是数据倾斜?如何解决数据倾斜?
  8. 网易云音乐服务器code521,网易云音乐scode500是怎么回事 网易云音乐scode502怎么解决...
  9. vitamin_baidu
  10. 构建linux图形安装程序,Scientific Linux 5.5 图形安装教程
  11. CNN卷积神经网络结构遐思
  12. scrapy中集成selenium+浏览器池实现selenium的并发爬取LCSC网站中非结构化表格数据+异步存储进mysql+完整代码
  13. 上海电机学院计算机科学与技术专业怎么样,上海电机学院计算机科学与技术专业2016年在上海理科高考录取最低分数线...
  14. 阿米洛 varlimo 机械键盘 cmd (win) 键锁定
  15. 【基础】python-docx包之----设置段落样式(缩进/对齐/间距)
  16. Revit中如何连接消火栓-Revit中快速连接设备
  17. 如何用个人电脑利用ipv6搭建网站
  18. 截至2017年1月59家金融租赁公司
  19. 江西理工大学南昌校区排名赛 F: 单身狗的骑马游戏
  20. SEO-采集站那些年的人和事

热门文章

  1. AD16如何添加禁止区域
  2. Spring boot + maven + jetty9在提交表单的时候出现Form too large
  3. java实现组织架构
  4. 集线器、中继器、网桥、交换机、网关、路由器——今天必把你们区分开
  5. php 购物车 原理及实现,纯干货丨PHP实现购物车的构建
  6. 基于Springboot框架的登录注册页面
  7. 西门子杯企业命题”钞包分拣装箱系统”演示视频
  8. unity实战 手机屏幕适配
  9. 树莓派安装网易云音乐amd64(Exagear)
  10. 数学建模课程设计-住房的合理定价问题