Skip to content

Build a Basic PDF Reader (PDFViewCtrl)

This guide explains how to build a basic PDF reader with PDFViewCtrl (display, zoom, page navigation, and other core interactions) without the built-in toolbar and feature modules from UI Extensions.

Prerequisites

Complete Integrate Foxit Android SDK first (project setup, SDK integration, and license initialization).

Step 1: Open and Display a PDF with PDFViewCtrl

In MainActivity.java, create a PDFViewCtrl instance and call PDFViewCtrl.openDoc() to open a document.

Note Ensure Sample.pdf is pushed to the FoxitSDK directory on the device or emulator.

java
package com.foxit.pdfreader;

import android.os.Bundle;
import android.os.Environment;

import androidx.appcompat.app.AppCompatActivity;

import com.foxit.sdk.PDFViewCtrl;
import com.foxit.sdk.common.Constants;
import com.foxit.sdk.common.Library;

public class MainActivity extends AppCompatActivity {

    private PDFViewCtrl pdfViewCtrl = null;

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

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

        // initialize the library.
        int errorCode = Library.initialize(sn, key);
        if (errorCode != Constants.e_ErrSuccess)
            return;

        pdfViewCtrl = new PDFViewCtrl(this);

        setContentView(pdfViewCtrl);
        String path = Environment.getExternalStorageDirectory().getPath() + "/FoxitSDK/Sample.pdf";
        pdfViewCtrl.openDoc(path, null);
    }
}

Tip The package com.foxit.pdfreader above is an example. Replace it with your project package name (consistent with applicationId).

Step 2: Request Runtime Storage Permissions (Sample Code)

If you read files from external storage paths (such as /sdcard/FoxitSDK/...), request the appropriate permissions for your Android version. The following snippet can be added to MainActivity.java where needed.

2.1 Add imports and constants

java
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.annotation.NonNull;

private static final int REQUEST_EXTERNAL_STORAGE = 1;

private static final int REQUEST_ALL_FILES_ACCESS_PERMISSION = 222;

private static final String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};

2.2 Request permissions in onCreate()

java
// Require the authorization of runtime permissions.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    if (!Environment.isExternalStorageManager()) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
        intent.setData(Uri.parse("package:" + getApplicationContext().getPackageName()));
        startActivityForResult(intent, REQUEST_ALL_FILES_ACCESS_PERMISSION);
        return;
    }
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
    int permission = ContextCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (permission != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
        return;
    }
}

2.3 Handle permission callbacks and open the document

java
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQUEST_EXTERNAL_STORAGE && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        // Open and Render a PDF document.
        String path = Environment.getExternalStorageDirectory().getPath() + "/FoxitSDK/Sample.pdf";
        pdfViewCtrl.openDoc(path, null);
    } else {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_ALL_FILES_ACCESS_PERMISSION) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (Environment.isExternalStorageManager()) {
                String path = Environment.getExternalStorageDirectory().getPath() + "/FoxitSDK/Sample.pdf";
                pdfViewCtrl.openDoc(path, null);
            }
        }
    }
}

Reference: MainActivity.java

The following is a complete MainActivity.java example with PDFViewCtrl initialization, runtime permissions, and document opening:

[MainActivity.java]
java
package com.foxit.pdfreader;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.annotation.NonNull;

import com.foxit.sdk.PDFViewCtrl;
import com.foxit.sdk.common.Constants;
import com.foxit.sdk.common.Library;


public class MainActivity extends AppCompatActivity {

    private PDFViewCtrl pdfViewCtrl = null;
    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static final int REQUEST_ALL_FILES_ACCESS_PERMISSION = 222;
    private static final String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

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

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

        // Initialize the library.
        int errorCode = Library.initialize(sn, key);
        if (errorCode != Constants.e_ErrSuccess)
            return;

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

        // Require the authorization of runtime permissions.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (!Environment.isExternalStorageManager()) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                intent.setData(Uri.parse("package:" + getApplicationContext().getPackageName()));
                startActivityForResult(intent, REQUEST_ALL_FILES_ACCESS_PERMISSION);
                return;
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            int permission = ContextCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
            if (permission != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
                return;
            }
        }

        // Open and Render a PDF document.
        String path = Environment.getExternalStorageDirectory().getPath() + "/FoxitSDK/Sample.pdf";
        pdfViewCtrl.openDoc(path, null);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == REQUEST_EXTERNAL_STORAGE && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Open and Render a PDF document.
            String path = Environment.getExternalStorageDirectory().getPath() + "/FoxitSDK/Sample.pdf";
            pdfViewCtrl.openDoc(path, null);
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_ALL_FILES_ACCESS_PERMISSION) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                if (Environment.isExternalStorageManager()) {
                    String path = Environment.getExternalStorageDirectory().getPath() + "/FoxitSDK/Sample.pdf";
                    pdfViewCtrl.openDoc(path, null);
                }
            }
        }
    }
}

Step 3: Update AndroidManifest.xml (Android 10 Compatibility)

When running on Android 10 (API 29) devices or emulators and accessing files via external storage paths, you may need android:requestLegacyExternalStorage="true" in AndroidManifest.xml to request legacy storage mode.

Example (excerpt):

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:requestLegacyExternalStorage="true"
        tools:replace="android:theme"
        android:theme="@style/Theme.PDFReader">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>