I'm triyng to create an epub reader for android, so after a lot of searching I found skyepub library (SDK) . seems it have all features i want.
i followed the tut in the site, but after running the code i got a blank screen and different logcat for different apis, i checked the code again and agian but i can't find what is wrong.
here is my code and logcat, any help would be appreciated.
public void makeLayout()
{
String fileName = new String();
fileName = "AliceinWonderland.epub";
makeSetup(); //making directory in device and copy every thing to it
rv = new ReflowableControl(this); // rv is ReflowableControl. an epub class (view) for showing content
Bitmap pageCenter = BitmapFactory.decodeFile(getFilesDir().getAbsolutePath() + "/images/PagesCenter.png");
Bitmap pageStack = BitmapFactory.decodeFile(getFilesDir().getAbsolutePath() + "/images/PagesStack.png");
rv.setPagesStackImage(pageStack);
rv.setPagesCenterImage(pageCenter);
rv.setBaseDirectory(getFilesDir() + "/books");
rv.setBookName(fileName);
rv.setDoublePagedForLandscape(true);
rv.setFont("TimesRoman", 26);
rv.setLineSpacing(135);
rv.setHorizontalGapRatio(0.15);
rv.setVerticalGapRatio(0.1);
/*
* all listener class are implementation of default class in library with simple override method like
* public void onClick(int x,int y)
* {
* Log.w("EPub","Click Detected at"+x+":"+y);
* }
*/
rv.setHighlightListener(new HighlightDelegate());
rv.setPageMovedListener(new PageMovedDelegate());
rv.setSelectionListener(new SelectionDelegate());
rv.setPagingListener(new PagingDelegate());
rv.setSearchListener(new SearchDelegate());
rv.setStateListener(new StateDelegate());
rv.setClickListener(new ClickDelegate());
rv.setBookmarkListener(new BookmarkDelegate());
ContentHandler cl = new ContentHandler();
rv.setContentListener(cl);
rv.setStartPositionInBook(0.285714f);
rv.setNavigationAreaWidthRatio(0.4f);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
params.width = LayoutParams.MATCH_PARENT;
params.height = LayoutParams.MATCH_PARENT;
rv.setLayoutParams(params);
ePubView = new RelativeLayout(this);
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
ePubView.setLayoutParams(rlp);
ePubView.addView(rv);
setContentView(ePubView);
}
public void makeSetup()
{
if (this.isSetup()) return;
if (!this.makeDirectory("scripts"))
{
debug("faild to make scripts directory");
}
if (!this.makeDirectory("images"))
{
debug("faild to make images directory");
}
if (!this.makeDirectory("covers"))
{
debug("faild to make images directory");
}
copyImageToDevice("PagesCenter.png");
copyImageToDevice("PagesStack.png");
if (!this.makeDirectory("downloads"))
{
debug("faild to make downloads directory");
}
if (!this.makeDirectory("books"))
{
debug("faild to make books directory");
}
if (!this.makeDirectory("books/fonts"))
{
debug("faild to make fonts directory");
}
copyBookToDevice("AliceinWonderland.epub");
copyFontToDevice("arial.ttf");
copyFontToDevice("simpo.ttf");
copyFontToDevice("tahoma.ttf");
copyFontToDevice("times.ttf");
SharedPreferences pref = this.getSharedPreferences("EPubTest",0);
SharedPreferences.Editor edit = pref.edit();
edit.putBoolean("isSetup", true);
edit.commit();
}
private boolean isSetup()
{
SharedPreferences pref = this.getSharedPreferences("EPubTest",0);
return pref.getBoolean("isSetup",false);
}
public boolean makeDirectory(String dirName)
{
boolean res;
String filePath = new String(this.getFilesDir().getAbsolutePath() + "/"+dirName);
debug(filePath);
File file = new File(filePath);
if (!file.exists()) {
res = file.mkdirs();
}else {
res = false;
}
return res;
}
public void copyImageToDevice(String fileName)
{
try
{
String path = this.getFilesDir().getAbsolutePath() + "/images/"+fileName;
File file = new File(path);
if (file.exists()) return;
InputStream localInputStream = this.getAssets().open("images/"+fileName);
FileOutputStream localFileOutputStream = new FileOutputStream(this.getFilesDir().getAbsolutePath() + "/images/"+fileName);
byte[] arrayOfByte = new byte[1024];
int offset;
while ((offset = localInputStream.read(arrayOfByte))>0)
{
localFileOutputStream.write(arrayOfByte, 0, offset);
}
localFileOutputStream.close();
localInputStream.close();
Log.d("EPub", fileName+" copied to phone");
}
catch (IOException localIOException)
{
localIOException.printStackTrace();
Log.d("EPub", "failed to copy");
return;
}
}
public void copyBookToDevice(String fileName)
{
try
{
String path = this.getFilesDir().getAbsolutePath() + "/books/"+fileName;
File file = new File(path);
if (file.exists()) return;
InputStream localInputStream = this.getAssets().open("books/"+fileName);
FileOutputStream localFileOutputStream = new FileOutputStream(this.getFilesDir().getAbsolutePath() + "/books/"+fileName);
byte[] arrayOfByte = new byte[1024];
int offset;
while ((offset = localInputStream.read(arrayOfByte))>0)
{
localFileOutputStream.write(arrayOfByte, 0, offset);
}
localFileOutputStream.close();
localInputStream.close();
Log.d("EPub", fileName+" copied to phone");
}
catch (IOException localIOException)
{
localIOException.printStackTrace();
Log.d("EPub", "failed to copy");
return;
}
}
public void copyFontToDevice(String fileName)
{
try
{
String path = this.getFilesDir().getAbsolutePath() + "/books/fonts/"+fileName;
File file = new File(path);
if (file.exists()) return;
InputStream localInputStream = this.getAssets().open("fonts/"+fileName);
FileOutputStream localFileOutputStream = new FileOutputStream(this.getFilesDir().getAbsolutePath() + "/books/fonts/"+fileName);
byte[] arrayOfByte = new byte[1024];
int offset;
while ((offset = localInputStream.read(arrayOfByte))>0)
{
localFileOutputStream.write(arrayOfByte, 0, offset);
}
localFileOutputStream.close();
localInputStream.close();
Log.d("epub", fileName+" copied to phone");
}
catch (IOException localIOException)
{
localIOException.printStackTrace();
Log.d("epub", "failed to copy");
return;
}
}
class ContentHandler implements ContentListener
{
public long getLength(String baseDirectory,String contentPath)
{
String path = baseDirectory + "/" + contentPath;
File file = new File(path);
if (file.exists())
{
return file.length();
}
else
{
return 0;
}
}
public boolean isExists(String baseDirectory,String contentPath)
{
String path = baseDirectory +"/"+ contentPath;
File file = new File(path);
boolean res = false;
Log.w("EPub",contentPath);
if (file.exists())
{
res = true;
}
else
{
res = false;
}
return res;
}
public long getLastModified(String baseDirectory,String contentPath)
{
String path = baseDirectory + "/" + contentPath;
File file = new File(path);
if (file.exists())
{
return file.lastModified();
}
else
{
return 0;
}
}
public InputStream getInputStream(String baseDirectory,String contentPath)
{
String path = baseDirectory + "/" + contentPath;
File file = new File(path);
try
{
FileInputStream fis = new FileInputStream(file);
return fis;
}
catch(Exception e)
{
return null;
}
}
}
the logcat for android 2.3.5 - HTC Chacha
01-26 08:40:04.180: I/System.out(4980): Absolute Path: /data/data/com.mehdok.epubtest/files
01-26 08:40:04.180: I/System.out(4980): File Dir: /data/data/com.mehdok.epubtest/files
01-26 08:40:04.180: D/EPub(4980): /data/data/com.mehdok.epubtest/files/scripts
01-26 08:40:04.180: D/EPub(4980): /data/data/com.mehdok.epubtest/files/images
01-26 08:40:04.190: D/EPub(4980): /data/data/com.mehdok.epubtest/files/covers
01-26 08:40:04.260: D/EPub(4980): PagesCenter.png copied to phone
01-26 08:40:04.270: D/EPub(4980): PagesStack.png copied to phone
01-26 08:40:04.270: D/EPub(4980): /data/data/com.mehdok.epubtest/files/downloads
01-26 08:40:04.270: D/EPub(4980): /data/data/com.mehdok.epubtest/files/books
01-26 08:40:04.330: D/EPub(4980): /data/data/com.mehdok.epubtest/files/books/fonts
01-26 08:40:04.520: D/EPub(4980): AliceinWonderland.epub copied to phone
01-26 08:40:04.520: D/szipinf(4980): Initializing inflate state
01-26 08:40:04.520: D/szipinf(4980): Initializing zlib to inflate
01-26 08:40:04.991: D/epub(4980): arial.ttf copied to phone
01-26 08:40:04.991: D/szipinf(4980): Initializing inflate state
01-26 08:40:04.991: D/szipinf(4980): Initializing zlib to inflate
01-26 08:40:05.071: D/epub(4980): simpo.ttf copied to phone
01-26 08:40:05.071: D/szipinf(4980): Initializing inflate state
01-26 08:40:05.111: D/szipinf(4980): Initializing zlib to inflate
01-26 08:40:05.321: D/epub(4980): tahoma.ttf copied to phone
01-26 08:40:05.321: D/szipinf(4980): Initializing inflate state
01-26 08:40:05.321: D/szipinf(4980): Initializing zlib to inflate
01-26 08:40:05.701: D/epub(4980): times.ttf copied to phone
01-26 08:40:05.821: I/dalvikvm(4980): Could not find method android.view.Display.getRealMetrics, referenced from method com.skytree.epub.br.getRawHeight
01-26 08:40:05.821: W/dalvikvm(4980): VFY: unable to resolve virtual method 4610: Landroid/view/Display;.getRealMetrics (Landroid/util/DisplayMetrics;)V
01-26 08:40:05.821: D/dalvikvm(4980): VFY: replacing opcode 0x6e at 0x001a
01-26 08:40:05.831: D/dalvikvm(4980): VFY: dead code 0x001d-0020 in Lcom/skytree/epub/br;.getRawHeight ()I
01-26 08:40:05.831: I/dalvikvm(4980): Could not find method android.view.Display.getRealMetrics, referenced from method com.skytree.epub.br.getRawWidth
01-26 08:40:05.831: W/dalvikvm(4980): VFY: unable to resolve virtual method 4610: Landroid/view/Display;.getRealMetrics (Landroid/util/DisplayMetrics;)V
01-26 08:40:05.831: D/dalvikvm(4980): VFY: replacing opcode 0x6e at 0x001a
01-26 08:40:05.831: D/dalvikvm(4980): VFY: dead code 0x001d-0020 in Lcom/skytree/epub/br;.getRawWidth ()I
01-26 08:40:05.911: D/Database(4980): dbopen(): path = /data/data/com.mehdok.epubtest/databases/webview.db, flag = 6, cannot stat file, errno: 2,message: No such file or directory
01-26 08:40:05.911: D/Database(4980): dbopen(): path = /data/data/com.mehdok.epubtest/databases/webview.db, mode: delete, disk free size: 26 M, handle: 0x267730
01-26 08:40:05.982: D/Database(4980): dbopen(): path = /data/data/com.mehdok.epubtest/databases/webviewCache.db, flag = 6, cannot stat file, errno: 2,message: No such file or directory
01-26 08:40:05.982: D/Database(4980): dbopen(): path = /data/data/com.mehdok.epubtest/databases/webviewCache.db, mode: delete, disk free size: 26 M, handle: 0x283068
01-26 08:40:06.072: D/qct(4980): [RequestQueue.ActivePool.ActivePool] >> Enable Shutdown = false
01-26 08:40:06.072: D/qct(4980): [IdleCache.IdleCache] >> IDLE_CACHE_MAX = 40
01-26 08:40:06.112: D/qct(4980): [PreConnectionManager.PreConnectionManager] >> TCP_PRE_CONNECT = false
01-26 08:40:06.172: D/skia(4980): htcFlashPlugin::htcFlashPlugin
01-26 08:40:06.172: D/qct(4980): [WebView.WebView] >> Enable Shutdown = false
01-26 08:40:06.182: D/skia(4980): htcFlashPlugin::htcFlashPlugin
01-26 08:40:06.182: D/qct(4980): [WebView.WebView] >> Enable Shutdown = false
01-26 08:40:06.192: D/skia(4980): htcFlashPlugin::htcFlashPlugin
01-26 08:40:06.192: D/qct(4980): [WebView.WebView] >> Enable Shutdown = false
01-26 08:40:06.262: D/dalvikvm(4980): GC_EXTERNAL_ALLOC freed 177K, 43% free 3156K/5447K, external 0K/0K, paused 51ms
01-26 08:40:06.262: D/qct(4980): [PreConnectionManager.PreConnectionManager] >> TCP_PRE_CONNECT = false
01-26 08:40:06.272: D/qct(4980): [PreConnectionManager.PreConnectionManager] >> TCP_PRE_CONNECT = false
01-26 08:40:06.322: D/dalvikvm(4980): GC_EXTERNAL_ALLOC freed 19K, 42% free 3173K/5447K, external 6K/512K, paused 45ms
01-26 08:40:06.442: D/ATRecorder(4980): com.htc.autotest.dlib.RecordEngine in loader dalvik.system.DexClassLoader@40540e00
01-26 08:40:06.692: D/libEGL(4980): loaded /system/lib/egl/libGLES_android.so
01-26 08:40:06.742: D/libEGL(4980): loaded /system/lib/egl/libEGL_adreno200.so
01-26 08:40:06.832: D/libEGL(4980): loaded /system/lib/egl/libGLESv1_CM_adreno200.so
01-26 08:40:06.832: D/libEGL(4980): loaded /system/lib/egl/libGLESv2_adreno200.so
01-26 08:40:06.872: E/Adreno200-ES20(4980): override1= 0xfffffffe, override2= 0xfff *
logcat for android 4.4 - emulator
01-26 08:47:22.760: I/System.out(1183): Absolute Path: /data/data/com.mehdok.epubtest/files
01-26 08:47:22.760: I/System.out(1183): File Dir: /data/data/com.mehdok.epubtest/files
01-26 08:47:22.770: D/EPub(1183): /data/data/com.mehdok.epubtest/files/scripts
01-26 08:47:22.810: D/EPub(1183): /data/data/com.mehdok.epubtest/files/images
01-26 08:47:22.810: D/EPub(1183): /data/data/com.mehdok.epubtest/files/covers
01-26 08:47:22.900: D/EPub(1183): PagesCenter.png copied to phone
01-26 08:47:22.940: D/EPub(1183): PagesStack.png copied to phone
01-26 08:47:22.940: D/EPub(1183): /data/data/com.mehdok.epubtest/files/downloads
01-26 08:47:22.960: D/EPub(1183): /data/data/com.mehdok.epubtest/files/books
01-26 08:47:22.960: D/EPub(1183): /data/data/com.mehdok.epubtest/files/books/fonts
01-26 08:47:23.090: D/EPub(1183): AliceinWonderland.epub copied to phone
01-26 08:47:23.980: D/epub(1183): arial.ttf copied to phone
01-26 08:47:24.040: D/epub(1183): simpo.ttf copied to phone
01-26 08:47:24.320: D/epub(1183): tahoma.ttf copied to phone
01-26 08:47:24.670: D/epub(1183): times.ttf copied to phone
01-26 08:47:24.850: V/WebViewChromium(1183): Binding Chromium to the background looper Looper{b3d68530}
01-26 08:47:24.860: I/chromium(1183): [INFO:library_loader_hooks.cc(112)] Chromium logging enabled: level = 0, default verbosity = 0
01-26 08:47:24.870: I/BrowserProcessMain(1183): Initializing chromium process, renderers=0
01-26 08:47:25.010: W/chromium(1183): [WARNING:proxy_service.cc(888)] PAC support disabled because there is no system implementation
01-26 08:47:25.020: D/(1183): HostConnection::get() New Host Connection established 0xb7b15d98, tid 1183
01-26 08:47:26.200: D/dalvikvm(1183): GC_FOR_ALLOC freed 126K, 7% free 2893K/3104K, paused 49ms, total 51ms
01-26 08:47:26.210: I/dalvikvm-heap(1183): Grow heap (frag case) to 3.509MB for 635812-byte allocation
01-26 08:47:26.290: D/dalvikvm(1183): GC_FOR_ALLOC freed 1K, 6% free 3512K/3728K, paused 74ms, total 74ms
01-26 08:47:26.510: W/ContentSettingsAdapter(1183): setDefaultZoom not supported, zoom=FAR
01-26 08:47:26.560: W/ContentSettingsAdapter(1183): setDefaultZoom not supported, zoom=FAR
01-26 08:47:26.610: W/ContentSettingsAdapter(1183): setDefaultZoom not supported, zoom=FAR
01-26 08:47:26.820: D/dalvikvm(1183): GC_FOR_ALLOC freed 33K, 4% free 3605K/3728K, paused 33ms, total 34ms
01-26 08:47:26.830: I/dalvikvm-heap(1183): Grow heap (frag case) to 4.107MB for 532496-byte allocation
01-26 08:47:26.910: D/dalvikvm(1183): GC_FOR_ALLOC freed <1K, 3% free 4125K/4252K, paused 73ms, total 74ms
01-26 08:47:27.670: W/EGL_emulation(1183): eglSurfaceAttrib not implemented
01-26 08:47:27.680: D/OpenGLRenderer(1183): Enabling debug mode 0
01-26 08:47:27.970: D/(1183): HostConnection::get() New Host Connection established 0xb7b38c40, tid 1211
01-26 08:47:28.070: W/AwContents(1183): nativeOnDraw failed; clearing to background color.
01-26 08:47:28.100: W/AwContents(1183): nativeOnDraw failed; clearing to background color.
01-26 08:47:28.100: W/AwContents(1183): nativeOnDraw failed; clearing to background color.
01-26 08:47:29.980: W/AwContents(1183): nativeOnDraw failed; clearing to background color.
01-26 08:47:29.990: W/AwContents(1183): nativeOnDraw failed; clearing to background color.
01-26 08:47:29.990: W/AwContents(1183): nativeOnDraw failed; clearing to background color.
01-26 08:47:30.910: I/Choreographer(1183): Skipped 54 frames! The application may be doing too much work on its main thread.
01-26 08:47:30.910: W/AwContents(1183): nativeOnDraw failed; clearing to background color.
01-26 08:47:30.910: W/AwContents(1183): nativeOnDraw failed; clearing to background color.
after clicking back button i got this logcat
01-26 08:41:52.646: D/AndroidRuntime(4980): Shutting down VM
01-26 08:41:52.646: W/dalvikvm(4980): threadid=1: thread exiting with uncaught exception (group=0x400205a0)
01-26 08:41:52.666: E/AndroidRuntime(4980): FATAL EXCEPTION: main
01-26 08:41:52.666: E/AndroidRuntime(4980): java.lang.NullPointerException
01-26 08:41:52.666: E/AndroidRuntime(4980): at com.skytree.epub.ec.b(Unknown Source)
01-26 08:41:52.666: E/AndroidRuntime(4980): at com.skytree.epub.br.m(Unknown Source)
01-26 08:41:52.666: E/AndroidRuntime(4980): at com.skytree.epub.br.onDetachedFromWindow(Unknown Source)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.view.View.dispatchDetachedFromWindow(View.java:6235)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1250)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.view.ViewRoot.dispatchDetachedFromWindow(ViewRoot.java:1862)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.view.ViewRoot.doDie(ViewRoot.java:2940)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.view.ViewRoot.die(ViewRoot.java:2910)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:254)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.view.Window$LocalWindowManager.removeViewImmediate(Window.java:445)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3182)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.app.ActivityThread.access$2100(ActivityThread.java:132)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1071)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.os.Handler.dispatchMessage(Handler.java:99)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.os.Looper.loop(Looper.java:150)
01-26 08:41:52.666: E/AndroidRuntime(4980): at android.app.ActivityThread.main(ActivityThread.java:4293)
01-26 08:41:52.666: E/AndroidRuntime(4980): at java.lang.reflect.Method.invokeNative(Native Method)
01-26 08:41:52.666: E/AndroidRuntime(4980): at java.lang.reflect.Method.invoke(Method.java:507)
01-26 08:41:52.666: E/AndroidRuntime(4980): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-26 08:41:52.666: E/AndroidRuntime(4980): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-26 08:41:52.666: E/AndroidRuntime(4980): at dalvik.system.NativeStart.main(Native Method)
You just need to unzip your epub book at your base directory (in your case its /book/filename). You have to unzip the epub file in books folder as epub file name.
You can see the full demo to below link
http://www.skytree21.com/cgi-bin/download.php?os=android&version=3.9.8&type=core_sample
in Demo,in LocalService class you'll get code for unzip file. In this demo they have downloaded epub file from web and after downloading first it is moved to download folder in phone directory and then its get extracted to base directory books in phone directory and then skyepub SDK will directly take its path by setting setBaseDirectory.
Here is the code for unzip file after moving asset file to download folder to phone directory
public void unzipBook(String fileName) {
String targetDir = new String(getFilesDir().getAbsolutePath() + "/books/" + fileName);
targetDir = SkyUtility.removeExtention(targetDir);
String filePath = new String(getFilesDir().getAbsolutePath() + "/downloads");
Unzip unzip = new Unzip(fileName, filePath, targetDir);
unzip.addObserver(new UnzipHandler());
unzip.unzip();
}
class UnzipHandler implements Observer {
@Override
public void update(Observable observable, Object data) {
//Unzip completed
(new Handler()).postDelayed(new Runnable() {
public void run() {
}
},500);
}
}
In your case you just need to take your asset reference and unzip it.You'll get success.
来源:https://stackoverflow.com/questions/21360383/android-epub-library-skyepub