> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/android/open-save-document/open.md).

# Open a document

Learn how to open a document in an Activity, fragment or view with PDFViewCTRL using Apryse's Android SDK. Follow Material design guidelines for a seamless experience. The Apryse Android SDK streamlin

You have a few options to open a document such as with an activity, fragment, or view. Check out the [diagram of the overall view hierarchy](/android/viewer/viewer-overview.md) for more.

{% tabs %}
{% tab title="Activity" %}

## Show a document in an Activity

Apryse's Android SDK ships with [`DocumentActivity`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/controls/DocumentActivity.html), an all-in-one document reader and PDF editor. In addition to PDF files, it also supports [viewing other file formats](/android/ms-office/non-pdf.md) such as `.docx`, `.doc`, `.pptx`, `.xlsx`, `.md`, `.cbz` and various image formats. In this activity you can also read, annotate, sign, fill in PDF forms and more.

`DocumentActivity` extends Android's [`AppCompatActivity`](https://developer.android.com/reference/androidx/appcompat/app/AppCompatActivity/) and follows [Material design guidelines](https://material.io/guidelines/).

![](https://226546913-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0QItsdFBmuuL9ezHimHy%2Fuploads%2Fgit-blob-ffa3eaa183402c0184a8845cef4ef7492205fd4b%2F1ed8a2fb5f4d6204964ec7788bb1094df6d78c7e-600x1200.gif?alt=media)

## Prerequisites

* [Integrated Apryse into your project](/android/get-started/get-started.md) and added the `com.pdftron:tools` package into your project.
* Minimum API: 21 (using AndroidX)
* Compile API: 35
* Recommended target API: 35

{% hint style="info" %}
**No trial license key required.**

The trial of Apryse Mobile SDK does not require a trial key. A commercial license key is required for use in a production environment. Please [contact sales](https://apryse.com/form/contact-sales) to purchase a commercial key or if you need any other license key assistance.
{% endhint %}

{% hint style="warning" %}
**Keep your license keys confidential.**

License keys are uniquely generated. Please make sure that it is not publicly available (e.g. in your public GitHub).
{% endhint %}

## Step 1: Update AndroidManifest.xml

1. In order to support all the features in `DocumentActivity`, we will need to add the Android permissions listed in [this table](/android/learn-more/permissions.md#android-permissions-list). However if you would like to disable certain features and customize your document viewer, you should leave out unnecessary permissions.

{% hint style="warning" %}
**Storage permission**

Please note that from Android 6.0 (API 23) and up, applications need to request storage permission at runtime before accessing any files on device.
{% endhint %}

1. Enable `largeHeap` and set `android:name` in the `<application>` tag to MultiDexApplication:

{% code lineNumbers="true" %}

```xml
<!-- Include existing attributes in application -->
<application android:name="androidx.multidex.MultiDexApplication" android:largeHeap="true" android:usesCleartextTraffic="false">
</application>
```

{% endcode %}

{% hint style="warning" %}
**If your app is targeting Android SDK version 28 or higher, you will need to add the android:usesCleartextTraffic="true" attribute in your application tag to open HTTP files in the viewer. If you are only working with HTTPS files, this is not required.**
{% endhint %}

1. If you have not done so already, add the `<meta-data>` tag containing a reference to your license key in the `AndroidManifest.xml` file. Also, declare `DocumentActivity` in the same file. The final `AndroidManifest.xml` file should look something like this:

{% code lineNumbers="true" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Include existing attributes in application -->
<manifest>
    <!-- Required permissions are added here -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO" />

    <!-- Add multidex support, enable largeHeap -->
    <!-- Include existing attributes in application -->
    <application android:name="androidx.multidex.MultiDexApplication" android:largeHeap="true" android:usesCleartextTraffic="false">    

        <!-- Add license key in meta-data tag here. This should be inside the application tag. -->
        <meta-data android:name="pdftron_license_key" android:value="${pdftronLicenseKey}"/>
            
        <!-- Document viewer activity declaration-->
        <activity android:name="com.pdftron.pdf.controls.DocumentActivity" android:configChanges="keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize" android:windowSoftInputMode="adjustPan" android:theme="@style/PDFTronAppTheme"/>
    </application>
</manifest>
```

{% endcode %}

## Step 2: Launch the viewer

Launch `DocumentActivity` by specifiying a local file path, an HTTP/HTTPS url, or a Content Uri:

{% tabs %}
{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
import android.net.Uri;
import java.io.File;
import com.pdftron.pdf.controls.DocumentActivity;

// Set the cache location using the config to store the cache file
ViewerConfig config = new ViewerConfig.Builder().openUrlCachePath(this.getCacheDir().getAbsolutePath()).build();

// from internal storage
final Uri uri = Uri.fromFile(new File("myLocalFilePath"));
// from content uri
final Uri uri = Uri.parse("myContentUri");
// from http/https
final Uri uri = Uri.parse("myFileLink");
// from assets
final Uri uri = Uri.parse("file:///android_asset/my_file.pdf");

// intent builder
Intent intent = DocumentActivity.IntentBuilder.fromActivityClass(this, DocumentActivity.class)
        .withUri(uri)
        .usingConfig(config)
        .usingTheme(R.style.PDFTronAppTheme)
        .build();
startActivity(intent);
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
import android.net.Uri
import java.io.File
import com.pdftron.pdf.controls.DocumentActivity

// Set the cache location using the config to store the cache file
val config = ViewerConfig.Builder().openUrlCachePath(this.getCacheDir().getAbsolutePath()).build();

// from internal storage
val uri = Uri.fromFile(new File("myLocalFilePath"))
// from content uri
val uri = Uri.parse("myContentUri")
// from http/https
val uri = Uri.parse("myFileLink")
// from assets
val uri = Uri.parse("file:///android_asset/my_file.pdf")

// intent builder
val intent: Intent = DocumentActivity.IntentBuilder.fromActivityClass(this, DocumentActivity::class.java)
        .withUri(uri)
        .usingConfig(config)
        .usingTheme(R.style.PDFTronAppTheme)
        .build()
startActivity(intent)
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Step 3: (Optional) Customize the viewer

* If you would like to customize the appearance of the viewer activity, define `PDFTronAppTheme` in `res/values/styles.xml`:You can learn more about this in the [customize the viewer's theme guide ](/android/ui-customization/custom-theme-a.md).

{% code lineNumbers="true" %}

```xml
<style name="PDFTronAppTheme" parent="PDFTronAppThemeBase"> <item name="colorPrimary">@color/app_color_primary_day</item> <item name="colorPrimaryDark">@color/app_color_primary_dark_day</item> <item name="colorAccent">@color/app_color_accent</item> <!-- Action bar --> <item name="actionModeBackground">?attr/colorPrimary</item> <item name="windowActionModeOverlay">true</item> </style>
```

{% endcode %}

{% hint style="info" %}
`DocumentActivity` uses the `AppCompat` theme for material colors. Make sure that the value of `android:theme` in your `activity` tag also extends the `AppCompat` theme.
{% endhint %}

* Also, if you would like to customize the UI components in `DocumentActivity`, you can use [`ViewerConfig.Builder`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/config/ViewerConfig.Builder.html). For example:For details on customizing the UI and using `ViewerConfig.Builder`, check out the [configuration tutorial ](/android/viewer/fragment-config.md).

{% tabs %}
{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
import com.pdftron.pdf.config.ViewerConfig;

ViewerConfig.Builder builder = new ViewerConfig.Builder();
ViewerConfig config = builder
    .fullscreenModeEnabled(true)
    .multiTabEnabled(true)
    .documentEditingEnabled(true)
    .longPressQuickMenuEnabled(true)
    .toolbarTitle("Simple Reader")
    .showSearchView(true)
    .build();
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
import com.pdftron.pdf.config.ViewerConfig

val builder = ViewerConfig.Builder()
val config = builder
  .fullscreenModeEnabled(true)
  .multiTabEnabled(true)
  .documentEditingEnabled(true)
  .longPressQuickMenuEnabled(true)
  .toolbarTitle("Simple Reader")
  .showSearchView(true)
  .build()
```

{% endcode %}
{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="Fragment" %}

## Display document in fragment on Android

All actions related to the PDF viewer are handled through the [`PdfViewCtrlTabHostFragment2`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/controls/PdfViewCtrlTabHostFragment2.html). This fragment extends [`androidx.fragment.app.Fragment`](https://developer.android.com/reference/kotlin/androidx/fragment/app/Fragment.html) and is responsible for showing documents in tabs.

![](https://226546913-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0QItsdFBmuuL9ezHimHy%2Fuploads%2Fgit-blob-ffa3eaa183402c0184a8845cef4ef7492205fd4b%2F1ed8a2fb5f4d6204964ec7788bb1094df6d78c7e-600x1200.gif?alt=media)

## Prerequisites

* [Integrated Apryse into your project](/android/get-started/get-started.md) and added the `com.pdftron:tools` package into your project.
* Minimum API: 21 (using AndroidX)
* Compile API: 35
* Recommended target API: 35

{% hint style="info" %}
**No trial license key required.**

The trial of Apryse Mobile SDK does not require a trial key. A commercial license key is required for use in a production environment. Please [contact sales](https://apryse.com/form/contact-sales) to purchase a commercial key or if you need any other license key assistance.
{% endhint %}

{% hint style="warning" %}
**Keep your license keys confidential.**

License keys are uniquely generated. Please make sure that it is not publicly available (e.g. in your public GitHub).
{% endhint %}

## Step 1: Update AndroidManifest.xml

1. In order to support all the features in `PdfViewCtrlTabHostFragment2`, we will need to add the Android permissions listed in [this table](/android/learn-more/permissions.md#android-permissions-list). However if you would like to disable certain features and customize your document viewer, you should leave out unnecessary permissions.

{% hint style="warning" %}
**Storage permission**

Please note that from Android 6.0 (API 23) and up, applications need to request storage permission at runtime before accessing any files on device.
{% endhint %}

1. Enable `largeHeap`, `usesClearTextTraffic`, and set `android:name` in the `<application>` tag to MultiDexApplication:

{% code lineNumbers="true" %}

```xml
<!-- Include existing attributes in application -->
<application android:name="androidx.multidex.MultiDexApplication" android:largeHeap="true" android:usesCleartextTraffic="true">
</application>
```

{% endcode %}

{% hint style="warning" %}
**If your app is targeting Android SDK version 28 or higher, you will need to add the android:usesCleartextTraffic="true" attribute in your application tag to open HTTP files in the viewer. If you are only working with HTTPS files, this is not required.**
{% endhint %}

1. Declare your activity in the manifest file:

{% code lineNumbers="true" %}

```xml
<!-- Include existing attributes in application -->
<application>
    <!-- Declare your activity that will use PdfViewCtrlTabHostFragment2 -->
    <!-- Include existing attributes in activity -->
    <activity android:theme="@style/PDFTronAppTheme" android:windowSoftInputMode="adjustPan" />
</application>
```

{% endcode %}

Note that your activity must extend [`AppCompatActivity`](https://developer.android.com/reference/androidx/appcompat/app/AppCompatActivity/).

1. If you have not done so already, add the `<meta-data>` tag containing a reference to your license key in the `AndroidManifest.xml` file. The final `AndroidManifest.xml` file should look something like this:

{% code lineNumbers="true" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Include existing attributes in manifest -->
<manifest>
    <!-- Required permissions are added here -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO" />

    <!-- Add multidex support, enable largeHeap, and enable usesCleartextTraffic -->
    <!-- Include existing attributes in application -->
    <application android:name="androidx.multidex.MultiDexApplication" android:largeHeap="true" android:usesCleartextTraffic="true">    

        <!-- Add license key in meta-data tag here. This should be inside the application tag. -->
        <meta-data android:name="pdftron_license_key" android:value="${pdftronLicenseKey}"/>
            
        <!-- Document viewer activity declaration-->
        <!-- Include existing attributes in activity -->
        <activity android:theme="@style/PDFTronAppTheme" android:windowSoftInputMode="adjustPan"/>
    </application>
</manifest>
```

{% endcode %}

## Step 2: Launch the viewer

Use `ViewerBuilder2` to create an instance of `PdfViewCtrlTabHostFragment2`, and add it to your activity layout. To add a document viewer fragment for a given password-protected file, call the following method in your activity:

{% tabs %}
{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
// Add a viewer fragment to the layout container in the specified 
// activity, and returns the added fragment
public PdfViewCtrlTabHostFragment2 addViewerFragment(@IdRes int fragmentContainer, 
        @NonNull AppCompatActivity activity, @NonNull Uri fileUri, @Nullable String password) {
    
    // Create the viewer fragment
    PdfViewCtrlTabHostFragment2 fragment =
            ViewerBuilder2.withUri(fileUri, password).build(activity);

    // Add the fragment to the layout fragment container
    activity.getSupportFragmentManager().beginTransaction()
            .replace(fragmentContainer, fragment)
            .commit();

    return fragment;
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
// Add a viewer fragment to the layout container in the specified
// activity, and returns the added fragment
fun addViewerFragment(
        @IdRes fragmentContainer: Int,
        activity: AppCompatActivity,
        fileUri: Uri, password: String?
): PdfViewCtrlTabHostFragment2 {

    // Create the viewer fragment
    val fragment = ViewerBuilder2.withUri(fileUri, password).build(activity)

    // Add the fragment to the layout fragment container
    activity.supportFragmentManager.beginTransaction()
            .replace(fragmentContainer, fragment)
            .commit()

    return fragment
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

where `fragmentContainer` is the resource id of a layout in your activity that will contain your fragment:

**For example:**

{% code lineNumbers="true" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<!-- This FrameLayout will contain our viewer fragment-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent"/>
```

{% endcode %}

Alternatively if you have extended [`PdfViewCtrlTabFragment2`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/controls/PdfViewCtrlTabFragment2.html) or `PdfViewCtrlTabHostFragment2`, you can specify your custom classes using the `ViewerBuilder2.usingTabClass()` method and the `ViewerBuilder2.build()` method as follows:

{% tabs %}
{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
// Add a viewer fragment to the layout container in the specified
// activity, and returns the added fragment
public MyCustomTabHostFragment addViewerFragment(@IdRes int fragmentContainer,
        @NonNull AppCompatActivity activity, @NonNull Uri fileUri, @Nullable String password) {

    // Create the viewer fragment with a custom 
    // PdfViewCtrlTabFragment2 and PdfViewCtrlTabHostFragment2
    PdfViewCtrlTabHostFragment2 fragment =
            ViewerBuilder2.withUri(fileUri, password)
                    .usingTabClass(MyCustomTabFragment.class)
                    .build(activity, MyCustomTabHostFragment.class);

    // Add the fragment to the layout fragment container
    activity.getSupportFragmentManager().beginTransaction()
            .replace(fragmentContainer, fragment)
            .commit();

    return fragment;
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
// Add a viewer fragment to the layout container in the specified
// activity, and returns the added fragment
fun addViewerFragment(
        @IdRes fragmentContainer: Int,
        activity: AppCompatActivity,
        fileUri: Uri, password: String?
): MyCustomTabHostFragment {

    // Create the viewer fragment with a custom 
    // PdfViewCtrlTabFragment2 and PdfViewCtrlTabHostFragment2
    val fragment = ViewerBuilder2.withUri(fileUri, password)
            .usingTabClass(MyCustomTabFragment::class.java)
            .build(activity, MyCustomTabHostFragment::class.java)

    // Add the fragment to the layout fragment container
    activity.supportFragmentManager.beginTransaction()
            .replace(fragmentContainer, fragment)
            .commit()

    return fragment
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Since Apryse uses the Fragment class from the Support Library, your activity must extend [`AppCompatActivity`](https://developer.android.com/reference/androidx/appcompat/app/AppCompatActivity/)and call [`getSupportFragmentManager()`](https://developer.android.com/reference/androidx/fragment/app/FragmentActivity.html#getSupportFragmentManager\(\)) to get the [`FragmentManager`](https://developer.android.com/reference/androidx/fragment/app/FragmentManager.html).
{% endhint %}

## Step 3: Customize the viewer

### Customize document viewer style

* If you would like to customize the appearance of the viewer activity, define `PDFTronAppTheme` in `styles.xml`:You can learn more about this in the [customize the viewer's theme guide ](/android/ui-customization/custom-theme-a.md).

{% code lineNumbers="true" %}

```xml
<style name="PDFTronAppTheme" parent="PDFTronAppThemeBase"> <item name="colorPrimary">@color/app_color_primary_day</item> <item name="colorPrimaryDark">@color/app_color_primary_dark_day</item> <item name="colorAccent">@color/app_color_accent</item> <!-- Action bar --> <item name="actionModeBackground">?attr/colorPrimary</item> <item name="windowActionModeOverlay">true</item> </style>
```

{% endcode %}

{% hint style="info" %}
`PdfViewCtrlTabHostFragment2` uses the `AppCompat` theme for material colors. Make sure that the value of `android:theme` in your `activity` tag also extends the `AppCompat` theme.
{% endhint %}

### Customize using ViewerConfig

* If you would like to customize certain viewer settings or the UI of `PdfViewCtrlTabHostFragment2`, you can use [`ViewerConfig.Builder`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/config/ViewerConfig.Builder.html). For example:

{% tabs %}
{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
// Pass a custom ViewerConfig object to initialize your viewer fragment 
public PdfViewCtrlTabHostFragment2 createUsingViewerConfig(@NonNull Context context,
        @NonNull Uri fileUri, @Nullable String password) {

    // Create a ViewerConfig object with custom settings
    ViewerConfig config = new ViewerConfig.Builder()
            .fullscreenModeEnabled(true)
            .multiTabEnabled(true)
            .documentEditingEnabled(true)
            .longPressQuickMenuEnabled(true)
            .toolbarTitle("Host Fragment")
            .showSearchView(true)
            .build();

    // Pass in the ViewerConfig object into the ViewerBuilder2
    return ViewerBuilder2.withUri(fileUri, password)
            .usingConfig(config)
            .build(context);
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
// Pass a custom ViewerConfig object to initialize your viewer fragment
fun createUsingViewerConfig(
        context: Context,
        fileUri: Uri, 
        password: String?
): PdfViewCtrlTabHostFragment2? {

    // Create a ViewerConfig object with custom settings
    val config = ViewerConfig.Builder()
            .fullscreenModeEnabled(true)
            .multiTabEnabled(true)
            .documentEditingEnabled(true)
            .longPressQuickMenuEnabled(true)
            .toolbarTitle("Host Fragment")
            .showSearchView(true)
            .build()

    // Pass in the ViewerConfig object into the ViewerBuilder2
    return ViewerBuilder2.withUri(fileUri, password)
            .usingConfig(config)
            .build(context)
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
For details on customizing the UI and using `ViewerConfig.Builder`, check out the [configuration tutorial ](/android/viewer/fragment-config.md).
{% endhint %}

### Customize the options toolbar

![](https://226546913-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0QItsdFBmuuL9ezHimHy%2Fuploads%2Fgit-blob-e41c35c02fc53c34c2bf69c4166af168c6a60fb9%2Fd44a9a43437d8c0ca7cf7134f08651f73852f248-423x58.jpg?alt=media)

The default toolbar menu consists of the following buttons on phones:

* App navigation
* Toolbar switcher
* Tab switcher
* Overflow menu

![](https://226546913-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0QItsdFBmuuL9ezHimHy%2Fuploads%2Fgit-blob-a321ec29780e9218dae808e1f8ebb95c6e3d7858%2Fd06f2cc6f6ab14ecc3d8b698d354f6ea6a625fb1-643x44.jpg?alt=media)

The default toolbar menu consists of the following buttons on tablets:

* App navigation
* Toolbar switcher
* Document text search
* View mode configuration
* Thumbnails browser
* List container
* Overflow menu

You can fully customize the toolbar menu and the navigation icon by calling the following in `ViewerBuilder2`, with custom menu resource and drawable resource files:

{% tabs %}
{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
public PdfViewCtrlTabHostFragment2 createUsingCustomToolbar(@NonNull Context context,
        @NonNull Uri fileUri, @DrawableRes int navIcon, @MenuRes int[] menuRes) {
    return ViewerBuilder2.withUri(fileUri)
            .usingCustomToolbar(menuRes)// Specify a custom toolbar
            .usingNavIcon(navIcon)      // Specify a custom navigation component
            .build(context);
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
fun createUsingCustomToolbar(
        context: Context,
        fileUri: Uri,
        @DrawableRes navIcon: Int,
        @MenuRes menuRes: IntArray
): PdfViewCtrlTabHostFragment2? {
    return ViewerBuilder2.withUri(fileUri)
            .usingCustomToolbar(menuRes)// Specify a custom toolbar
            .usingNavIcon(navIcon)      // Specify a custom navigation component
            .build(context)
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

To change the icon color and overflow icon color, in `styles.xml`:

{% code lineNumbers="true" %}

```xml
<style name="ToolbarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar"> <item name="colorControlNormal">@color/red</item> <item name="iconTint">@color/red</item> </style>
```

{% endcode %}

To change the navigation icon color, in `styles.xml` (assume `MyTheme` is used as the app theme):

{% code lineNumbers="true" %}

```xml
<style name="MyTheme" parent="PDFTronAppTheme"> <item name="toolbarNavigationButtonStyle">@style/ToolbarButtonNavigationStyle</item> </style>

<style name="ToolbarButtonNavigationStyle" parent="Widget.AppCompat.Toolbar.Button.Navigation"> <item name="android:tint">@color/red</item> </style>
```

{% endcode %}

{% hint style="info" %}

## Step 4: Interact with the fragment

{% endhint %}

If you would like to interact with the host fragment you can call [`addHostListener(TabHostListener)`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/controls/PdfViewCtrlTabHostFragment2.html#addHostListener\(com.pdftron.pdf.controls.PdfViewCtrlTabHostFragment2.TabHostListener\)) and override the methods that you are interested in. For example, you may want to override [`onToolbarOptionsItemSelected(MenuItem)`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/controls/PdfViewCtrlTabHostFragment2.TabHostListener.html#onToolbarOptionsItemSelected\(android.view.MenuItem\)) when you add a new menu item, so when the item is clicked you can get a callback. As another example, you can get the callback when the navigation icon is clicked if you override [`onNavButtonPressed()`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/controls/PdfViewCtrlTabHostFragment2.TabHostListener.html#onNavButtonPressed\(\)).

Here's an example that replaces the default navigation icon and uses a custom toolbar:

{% tabs %}
{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
public class CustomToolbarActivity extends AppCompatActivity implements PdfViewCtrlTabHostFragment2.TabHostListener {

@Nullable
private PdfViewCtrlTabHostFragment2 mPdfViewCtrlTabHostFragment;

// Method used to initialize the viewer fragment with a custom toolbar.
public void createCustomToolbarFragment(@NonNull Uri fileUri) {
    mPdfViewCtrlTabHostFragment = ViewerBuilder2.withUri(fileUri)
            // Specify a custom toolbar
            .usingCustomToolbar(new int[] {R.menu.my_custom_toolbar})
            // Specify a custom navigation component
            .usingNavIcon(R.drawable.ic_arrow_back_white_24dp)      
            .build(this);
}

@Override
public boolean onToolbarOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.action_show_toast) {
        Toast.makeText(this, "Show toast is clicked!", Toast.LENGTH_SHORT).show();
    }
    return false;
}

@Override
public void onNavButtonPressed() {
    // called when navigation button has been clicked
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (mPdfViewCtrlTabHostFragment != null) {
        mPdfViewCtrlTabHostFragment.removeHostListener(this);
    }
}

// ...
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
class CustomToolbarActivity : AppCompatActivity(), PdfViewCtrlTabHostFragment2.TabHostListener {

    private var mPdfViewCtrlTabHostFragment: PdfViewCtrlTabHostFragment2? = null

    // Method used to initialize the viewer fragment with a custom toolbar.
    fun createCustomToolbarFragment(fileUri: Uri) {
        mPdfViewCtrlTabHostFragment = ViewerBuilder2.withUri(fileUri)
                // Specify a custom toolbar
                .usingCustomToolbar(intArrayOf(R.menu.my_custom_toolbar))
                // Specify a custom navigation component
                .usingNavIcon(R.drawable.ic_arrow_back_white_24dp)      
                .build(this)
    }

    override fun onToolbarOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == R.id.action_show_toast) {
            Toast.makeText(this, "Show toast is clicked!", Toast.LENGTH_SHORT).show()
        }
        return false
    }

    override fun onNavButtonPressed() {
        // called when navigation button has been clicked
    }

    override fun onDestroy() {
        super.onDestroy()
        if (mPdfViewCtrlTabHostFragment != null) {
            mPdfViewCtrlTabHostFragment!!.removeHostListener(this)
        }
    }

    // ...
```

{% endcode %}
{% endtab %}
{% endtabs %}

where `ic_arrow_back_white_24dp.xml` is a drawable resource file for a back arrow icon, and `my_custom_toolbar.xml` is a menu resource file that contains:

{% code lineNumbers="true" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
     <item android:id="@+id/action_settings" android:icon="@drawable/ic_settings" android:title="@string/action_settings" app:showAsAction="ifRoom"/>
    <item android:id="@+id/action_show_toast" android:title="Show toast" app:showAsAction="never" />
</menu>
```

{% endcode %}

This sample replaces the navigation icon, removes all toolbar buttons except the annotation toolbar button, and adds a new `Show Toast` button:

![](https://226546913-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0QItsdFBmuuL9ezHimHy%2Fuploads%2Fgit-blob-93ca039c7f05b7bf6d2e1002faafe358b11256d4%2F2bf0bfd4720aa2ad30e5539cce26f5ce425dd7df-422x816.gif?alt=media)
{% endtab %}

{% tab title="View" %}

## Display PDF using PDFViewCTRL in Android

{% hint style="info" %}
If you are looking for a quick start on displaying documents in your application, please first take a look at [Show a document in an Activity](/android/open-save-document/open/activity.md) or [Show a document in a Fragment](/android/open-save-document/open/fragment.md) as they are easier to setup and ready to launch from any activity or fragment. Continue reading this article if you are looking to embed [`PDFViewCtrl`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/PDFViewCtrl.html) in your own layout.
{% endhint %}

{% hint style="info" %}
**Before beginning, make sure the Apryse library is initialized prior to inflating the layout or calling setContentView in your activity.**
{% endhint %}

[`PDFViewCtrl`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/PDFViewCtrl.html) is a [`ViewGroup`](https://developer.android.com/reference/android/view/ViewGroup.html) that can be embedded in any layout. It encapsulates a rich set of functionalities for interactive viewing of PDF documents, including multi-threaded rendering, PDF rendering settings, scrolling, zooming, page navigation, different page viewing modes, coordinates conversion, text selection, text search, etc.

## View documents using PDFViewCtrl

In this tutorial you will display a PDF file in your activity by using [`PDFViewCtrl`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/PDFViewCtrl.html).

1. In your `AndroidManifest.xml`, make sure you enable `largeHeap` in the `<application>` tag. Also, add a custom theme and set the `android:windowSoftInputMode:"adjustPan"` attribute in the `<activity>` tag as follow:

{% code lineNumbers="true" %}

```xml
<!-- Include existing attributes in application -->
<application android:name="androidx.multidex.MultiDexApplication" android:largeHeap="true" android:usesCleartextTraffic="false">
    <!-- Include existing attributes in activity -->
    <activity android:windowSoftInputMode="adjustPan" android:theme="@style/PDFTronAppTheme"/>
</application>
```

{% endcode %}

{% hint style="warning" %}
**If your app is targeting Android SDK version 28 or higher, please also set the android:usesCleartextTraffic="true" attribute in your application tag to open HTTP files in the viewer. If you are only working with HTTPS files, this is not required.**
{% endhint %}

1. If you would like to customize the appearance of the viewer activity, define `PDFTronAppTheme` for your activity in `res/values/styles.xml`:You can learn more about this in the [customize the viewer's theme guide](/android/ui-customization/custom-theme-a.md).

{% code lineNumbers="true" %}

```xml
<resources>
<style name="PDFTronAppTheme" parent="PDFTronAppThemeBase"> <item name="colorPrimary">#3F51B5</item> <item name="colorPrimaryDark">#303F9F</item> <item name="colorAccent">#FF4081</item> <!-- Action bar --> <item name="actionModeBackground">?attr/colorPrimary</item> <item name="windowActionModeOverlay">true</item> </style>
</resources>
```

{% endcode %}

{% hint style="info" %}
`PDFViewCtrl` uses the `AppCompat` theme for material colors. Make sure that the value of `android:theme` in your `<activity>` tag also extends the `AppCompat` theme.
{% endhint %}

1. Now, add [`PDFViewCtrl`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/PDFViewCtrl.html) to your activity's XML layout. For example:

{% code lineNumbers="true" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">

    <com.pdftron.pdf.PDFViewCtrl android:id="@+id/pdfviewctrl" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical|horizontal"/>

</FrameLayout>
```

{% endcode %}

1. In your activity, get a reference to [`PDFViewCtrl`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/PDFViewCtrl.html) after inflating the layout and call [`AppUtils.setupPDFViewCtrl`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/utils/AppUtils.html#setupPDFViewCtrl\(PDFViewCtrl\)).

{% tabs %}
{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
private PDFViewCtrl mPdfViewCtrl;
// ...
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.my_activity_layout);
    
    mPdfViewCtrl = findViewById(R.id.pdfviewctrl);
    try {
        AppUtils.setupPDFViewCtrl(mPdfViewCtrl);
    } catch (PDFNetException e) {
        // Handle exception
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
private var mPdfViewCtrl: PDFViewCtrl? = null
// ...
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.my_activity_layout)

    mPdfViewCtrl = findViewById(R.id.pdfviewctrl)
    AppUtils.setupPDFViewCtrl(mPdfViewCtrl!!)
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

1. Next, choose a document to display by using the following options:Add a sample PDF to `src/main/res/raw` folder, then call:

### View from resource

{% tabs %}
{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
import com.pdftron.pdf.utils.Utils;
// ...
private PDFDoc mPdfDoc;
// ...
public void viewFromResource(int resourceId, String fileName) throws PDFNetException {
    File file = Utils.copyResourceToLocal(this, resourceId, fileName, ".pdf");
    mPdfDoc = new PDFDoc(file.getAbsolutePath());
    mPdfViewCtrl.setDoc(mPdfDoc);
    // Alternatively, you can open the document using Uri:
    // Uri fileUri = Uri.fromFile(file);
    // mPdfDoc = mPdfViewCtrl.openPDFUri(fileUri, null);
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
import com.pdftron.pdf.utils.Utils
// ...
private var mPdfDoc: PDFDoc? = null
// ...
fun viewFromResource(resourceId: Int, fileName: String) {
    val file = Utils.copyResourceToLocal(this, resourceId, fileName, ".pdf")
    mPdfDoc = PDFDoc(file.absolutePath)
    mPdfViewCtrl?.doc = mPdfDoc
    // Alternatively, you can open the document using Uri:
    // val fileUri = Uri.fromFile(file)
    // mPdfDoc = mPdfViewCtrl?.openPDFUri(fileUri, null)
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### View from local device storage

{% hint style="warning" %}
**Storage Permission**

Please follow the latest Android best practices and guidelines outlined [here](https://developer.android.com/training/permissions/usage-notes/)
{% endhint %}

## Managing lifecycle

It is extremely important that you follow the Android activity/fragment lifecycle and clean up [`PDFViewCtrl`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/PDFViewCtrl.html) and [`PDFDoc`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/PDFDoc.html) properly. Make sure you have the following in lifecycle callbacks:

{% tabs %}
{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
// ...
@Override
public void onPause() {
    super.onPause();
    if (mPdfViewCtrl != null) {
        mPdfViewCtrl.pause();
        mPdfViewCtrl.purgeMemory();
    }
}

@Override
public void onResume() {
    super.onResume();
    if (mPdfViewCtrl != null) {
        mPdfViewCtrl.resume();
    }
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (mPdfViewCtrl != null) {
        mPdfViewCtrl.destroy();
        mPdfViewCtrl = null;
    }

    if (mPdfDoc != null) {
        try {
            mPdfDoc.close();
        } catch (Exception e) {
            // handle exception
        } finally {
            mPdfDoc = null;
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
// ...
override fun onPause() {
  super.onPause()
  mPdfViewCtrl?.pause()
  mPdfViewCtrl?.purgeMemory()
}

override fun onResume() {
  super.onResume()
  mPdfViewCtrl?.resume()
}

override fun onDestroy() {
  super.onDestroy()
  mPdfViewCtrl?.destroy()
  mPdfViewCtrl = null
  mPdfDoc?.close()
  mPdfDoc = null
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Next steps

* Want to annotate on PDF files in [`PDFViewCtrl`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/PDFViewCtrl.html)? Check out the [Setup ToolManager](/android/annotation/toolmanager-config.md) guide.
* Want to display non-PDF files in [`PDFViewCtrl`](https://sdk.apryse.com/api/android/javadoc/reference/com/pdftron/pdf/PDFViewCtrl.html)? Check out the [viewing other document types](/android/ms-office/non-pdf.md) guide.
  {% endtab %}
  {% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/android/open-save-document/open.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
