Extract selected text from PDFs on Android
Nutrient’s document viewing UI has built-in support for text selection, which was designed to exactly match the text selection behavior in stock Android components. The text selection UI includes full support for standard touch- and cursor-based text selection gestures, as well as a built-in contextual menu for quick access to operations such as copying and highlighting.
In addition to the bundled UI behaviors, it’s also possible to build additional operations on the selected text by leveraging the provided API hooks. This guide covers two convenient options.
Text selection listener
You can implement your own TextSelectionManager
listeners to react to both text selection changes and text selection mode changes (entering and exiting text selection mode):
class MyActivity : PdfActivity(), TextSelectionManager.OnTextSelectionChangeListener, TextSelectionManager.OnTextSelectionModeChangeListener { const val TAG = "MyActivity.TextSelection" override fun onCreate(savedInstanceState: Bundle?) { PdfFragment.addOnTextSelectionModeChangeListener(this) PdfFragment.addOnTextSelectionChangeListener(this) } override fun onDestroy(savedInstanceState: Bundle?) { PdfFragment.removeOnTextSelectionModeChangeListener(this) PdfFragment.removeOnTextSelectionChangeListener(this) } override fun onEnterTextSelectionMode(controller: TextSelectionController) { Log.i(TAG, "Text selection mode has started.") } override fun onExitTextSelectionMode(controller: TextSelectionController) { Log.i(TAG, "Text selection mode has ended.") } override fun onTextSelectionChange(newTextSelection: TextSelection?, currentTextSelection: TextSelection?): Boolean { if (newTextSelection != null) { Log.i(TAG, "Selected text was: ${newTextSelection.text}") } else { Log.i(TAG, "Text selection is cleared.") } // You can also return `false` to prevent changes to the current selection state. return true } }
public class MyActivity extends PdfActivity implements TextSelectionManager.OnTextSelectionChangeListener, TextSelectionManager.OnTextSelectionModeChangeListener{ private static final String TAG = "MyActivity.TextSelection"; @Override protected void onCreate(Bundle savedInstanceState) { getPdfFragment().addOnTextSelectionModeChangeListener(this); getPdfFragment().addOnTextSelectionChangeListener(this); } @Override protected void onDestroy(Bundle savedInstanceState) { getPdfFragment().removeOnTextSelectionModeChangeListener(this); getPdfFragment().removeOnTextSelectionChangeListener(this); } @Override public void onEnterTextSelectionMode(@NonNull TextSelectionController controller) { Log.i(TAG, "Text selection mode has started."); } @Override public void onExitTextSelectionMode(@NonNull TextSelectionController controller) { Log.i(TAG, "Text selection mode has ended."); } @Override public boolean onTextSelectionChange(@Nullable TextSelection newTextSelection, @Nullable TextSelection currentTextSelection) { if (newTextSelection != null) { Log.i(TAG, String.format("Selected text was: %s", newTextSelection.text)); } else { Log.i(TAG, "Text selection is cleared."); } // You can also return `false` to prevent changes to the current selection state. return true; } }
This won’t override the default behavior. Rather, it’ll register more listeners. If you’d like to have a completely different behavior than showing the toolbar when text selection starts, you need to use PdfFragment
inside a custom activity and bind the UI with the provided TextSelectionController
.
Selecting and extracting text programmatically
You can select text programmatically by calling PdfFragment#enterTextSelectionMode
and providing the text range to be selected. You can retrieve the text of the current page by calling PdfDocument#getPageText
.
For example, select the first occurrence of a random string on the page:
// Search for the position of text that should be selected. val textToSelect = "text to select" val textIndexOnPage = document.getPageText(pageIndex).indexOf(textToSelect) if (textIndexOnPage >= 0) { // Select the text. fragment.enterTextSelectionMode(pageIndex, Range(textIndexOnPage, textToSelect.length)) }
// Search for the position of text that should be selected. String textToSelect = "text to select"; int textIndexOnPage = document.getPageText(pageIndex).indexOf(textToSelect); if (textIndexOnPage >= 0) { // Select the text. fragment.enterTextSelectionMode(pageIndex, new Range(textIndexOnPage, textToSelect.length())); }
Once the text is selected, the TextSelectionManager
listeners can be used to extract the selected text.