当前位置:   article > 正文

Foxit MobilePDF SDK_如何快速创建一个功能丰富的PDF 阅读器_福昕阅读器插件开发教程

福昕阅读器插件开发教程

一直以来,我都比较关注福昕的PDF SDK套件,这几天稍微有时间看了下最新发布的4.0版本,然后呢,然后呢,我就被深深的震惊到了,为甚么? 因为这个版本可以很轻松很容易的创建一个功能超级丰富的PDF阅读器,而且可以通过一个配置文件就能实现功能定制。

还是附上下载的链接: 有兴趣的同学们可以下载试用下: https://www.foxitsoftware.com/products/sdk/register.php?product=MobilePDFSDK

话不多说,我们来看下福昕新发布的MobilePDF SDK是如何做到快速创建一个功能丰富的PDF阅读器的。

新建Android工程,导入Foxit的SDK库

创建一个Android 工程,这里我命名为PDFViewer, 然后导入Foxit的SDK库,这两步可以看我之前的文章Foxit Mobile PDF SDK for Android_渲染PDF文档(2) 中准备工作的第一点和第二点。

附上配置后的app下的build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.foxit.pdfviewer"
        minSdkVersion 16
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}

repositories {
    flatDir {
        dirs 'libs'
    }
}

dependencies {
    compile name: 'FoxitRDKUIExtensions', ext: 'aar'
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7'
    compile 'com.android.support:recyclerview-v7:25.3.1'
    testCompile 'junit:junit:4.12'
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

Unlock SDK 库

// load "librdk.so" library.
static {
    System.loadLibrary("rdk");
}
….
String sn = " ";
String key = " ";

try {
    // initialize the library.
    Library.init(sn, key);
} catch (PDFException e) {
    e.printStackTrace();
    return;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

note: sn和key是一串比较长的字符串,大家可以到libs目录下的rdk_sn.txt和rdk_key.txt文件中copy过来,或者从demo中copy。

编写JSON配置文件

如下所示:(这里我命名为:config.json)

{
    "defaultReader": true,
    "modules": {
        "readingbookmark": true,
        "outline": true,
        "annotations": true,
        "thumbnail" : true,
        "attachment": true,
        "signature": true,
        "search": true,
        "pageNavigation": true,
        "form": true,
        "selection": true,
        "encryption" : true
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

然后将编写好的JSON文件放到”PDFViewer\app\src\main\res\raw” 目录下(需要自己创建”raw”目录).

Note:配置文件中的 “defaultReader”在默认情况下是false的,也就是和4.0版本之前的SDK是兼容的。以前的SDK是没有这么智能化的,如果你想实现一个功能丰富的PDF Reader app, 你需要自己设计app的界面,以及调用福昕SDK来实现你想要的功能。这是一个比较复杂的过程,你需要对福昕的SDK有一定的了解才能做好这个app。而SDK 4.0 将很多基础的UI都封装到了一个PDFReader的类中,而且通过简单的配置文件可以自由的定制你想要的功能。

初始化UIExtensionsManager和PDFReader

关于UIExtensionsManager可以查看Foxit Mobile PDF SDK for Android_渲染PDF文档(2)中的介绍。
这里使用JSON配置文件来初始化UIExtensionsManager, 以及获取当前的PDFReader,代码如下:

private PDFViewCtrl pdfViewCtrl = null;
private UIExtensionsManager uiextensionsManager = null;
private PDFReader mPDFReader = null;
...
// Instantiate a PDFViewCtrl object.
pdfViewCtrl = new PDFViewCtrl(this.getApplicationContext());

// Get the config file, and set it to UIExtensionsManager.
InputStream stream = this.getApplicationContext().getResources().openRawResource(R.raw.uiextensions_config);
UIExtensionsManager.Config config = new UIExtensionsManager.Config(stream);

// Instantiate a UIExtensionsManager object and set it to PDFViewCtrl.
uiextensionsManager = new UIExtensionsManager(this.getApplicationContext(), null, pdfViewCtrl, config); 
uiextensionsManager.setAttachedActivity(this);
pdfViewCtrl.setUIExtensionsManager(uiextensionsManager);

// Get current PDFReader, and set it to PDFViewCtrl.
mPDFReader = (PDFReader) uiextensionsManager.getPDFReader();
mPDFReader.onCreate(this, pdfViewCtrl, savedInstanceState);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

Activity生命周期处理

需要加入Activity生命周期的处理,不然有些功能使用会出现问题。
更新MainActivity.java 如下:

package com.foxit.pdfreader;

import android.content.Intent;
import android.content.res.Configuration;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.WindowManager;

import com.foxit.sdk.PDFViewCtrl;
import com.foxit.sdk.common.Library;
import com.foxit.sdk.common.PDFException;
import com.foxit.uiextensions.UIExtensionsManager;
import com.foxit.uiextensions.home.IHomeModule;
import com.foxit.uiextensions.pdfreader.impl.MainFrame;
import com.foxit.uiextensions.pdfreader.impl.PDFReader;
import com.foxit.uiextensions.utils.AppFileUtil;

import java.io.InputStream;

public class MainActivity extends AppCompatActivity {

    private PDFViewCtrl pdfViewCtrl = null;
    private UIExtensionsManager uiextensionsManager = null;
    private PDFReader mPDFReader = null;
    // Load "librdk.so" library.
    static {
        System.loadLibrary("rdk");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // The value of "sn" can be found in the “rdk_sn.txt”.
        // The value of "key" can be found in the “rdk_key.txt”.
        String sn = " ";
        String key = " ";

        try {
            // initialize the library.
            Library.init(sn, key);
        } catch (PDFException e) {
            e.printStackTrace();
            return;
        }

        // Instantiate a PDFViewCtrl object.
        pdfViewCtrl = new PDFViewCtrl(this.getApplicationContext());

        // Get the config file, and set it to UIExtensionsManager.
        InputStream stream = this.getApplicationContext().getResources().openRawResource(R.raw.uiextensions_config);
        UIExtensionsManager.Config config = new UIExtensionsManager.Config(stream);

        // Instantiate a UIExtensionsManager object and set it to PDFViewCtrl.
        uiextensionsManager = new UIExtensionsManager(this.getApplicationContext(), null, pdfViewCtrl, config);
        uiextensionsManager.setAttachedActivity(this);
        pdfViewCtrl.setUIExtensionsManager(uiextensionsManager);

        // Get current PDFReader, and set it to PDFViewCtrl.
        mPDFReader = (PDFReader) uiextensionsManager.getPDFReader();
        mPDFReader.onCreate(this, pdfViewCtrl, savedInstanceState);

        // load a document
        String path = "mnt/sdcard/pdf/Sample.pdf";

        mPDFReader.openDocument(path, null);
        setContentView(mPDFReader.getContentView());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (mPDFReader == null)
            return;
        if (mPDFReader.getMainFrame().getAttachedActivity() != this)
            return;
        setIntent(intent);
        String path = AppFileUtil.getFilePath(this, intent, IHomeModule.FILE_EXTRA);
        if (path != null) {
            mPDFReader.openDocument(path, null);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (mPDFReader == null)
            return;
        mPDFReader.onStart(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mPDFReader == null)
            return;
        mPDFReader.onPause(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mPDFReader == null)
            return;
        mPDFReader.onResume(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mPDFReader == null)
            return;
        mPDFReader.onStop(this);
    }

    @Override
    protected void onDestroy() {
        this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        if (mPDFReader != null)
            mPDFReader.onDestroy(this);
        super.onDestroy();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (mPDFReader != null)
            mPDFReader.onActivityResult(this, requestCode, resultCode, data);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (mPDFReader == null)
            return;
        ((MainFrame) mPDFReader.getMainFrame()).updateSettingBar();
        mPDFReader.onConfigurationChanged(this, newConfig);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (mPDFReader != null && mPDFReader.onKeyDown(this, keyCode, event))
            return true;
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if (mPDFReader != null && !mPDFReader.onPrepareOptionsMenu(this, menu))
            return false;
        return super.onPrepareOptionsMenu(menu);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156

更新 AndroidManifest.xml文件

填写相应的读写权限,以及设置“android:configChanges="keyboardHidden|orientation|screenSize">” 属性(为了在屏幕发生旋转时,只调用onConfigurationChanged()函数,而不用重新执行Activity的生命周期).

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.foxit.pdfviewer">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.CAMERA" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
       android:configChanges="keyboardHidden|orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

运行PDFViewer

我这里使用他们的sample.pdf文件,运行后,可以看到一个功能丰富的PDF viewer就出现了,如下图所示:

主界面

List面板

View面板

Annotation面板

Signature面板

看了这些图,是不是觉得灰常的强大啊,只需要这么点代码就能实现一个如此强大,如此专业的PDF Viewer。 反正我是被震惊到了,所以写了这篇文章来和大家分享。

注:此文主要参考了他们官方的Developer Guide文档,很多代码都直接从里面copy的,有点小偷懒哈。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/243029
推荐阅读
  

闽ICP备14008679号