This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/android/open-a-document/from-local-storage.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Open a local PDF file on Android app | Nutrient SDK

Nutrient Android SDK opens PDFs and PNG, JPEG, or TIFF images from local storage. The following examples open PDF documents.

Never hardcode absolute paths

Storage paths can differ across devices and app restarts, and moving an app to adopted storage can also change its paths. Use Context(opens in a new tab) methods to locate your app’s directories:

Store only relative file paths in databases or settings.

Accessing the external storage

Android supports shared external storage on removable devices, such as SD cards and USB drives, or non-removable internal storage. Handle cases where external storage becomes unavailable.

Storage Access Framework

Use the Storage Access Framework(opens in a new tab) to enable users to browse and open documents from device storage.

The Catalog app’s ExternalDocumentExample demonstrates file access through the Storage Access Framework.

Permissions to external storage

Request READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE permissions on Android versions that require them. These permissions have version-specific limits:

  • WRITE_EXTERNAL_STORAGE has no effect for apps targeting Android 11 (API 30) or higher.
  • READ_EXTERNAL_STORAGE has no effect on Android 13 (API 33) or higher.

Declare the required permissions in your manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.app.package">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>

For apps targeting Android 6.0 or higher, Android doesn’t grant these permissions automatically after installation. Request the permissions(opens in a new tab) in your activity:

companion object {
private const val REQUEST_ASK_FOR_PERMISSION = 1
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Request permission here.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_ASK_FOR_PERMISSION)
}
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQUEST_ASK_FOR_PERMISSION) {
if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission has been granted.
} else {
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// User denied permission.
} else {
// User asked to "Never ask again" when denying permission.
}
}
}
}

Your app doesn’t need these permissions to access its own files in Context#getExternalFilesDir(null)(opens in a new tab).

Scoped directory access

On Android 9 and lower, READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE grant access to all public directories on external storage.

For access to one directory, use Intent.ACTION_OPEN_DOCUMENT_TREE(opens in a new tab) from the Storage Access Framework. Its permissions UI identifies the directory your app requests.

Opening a document from local storage

Use PdfActivityIntentBuilder.fromUri()(opens in a new tab) to open a local PDF. The following examples cover internal storage, external storage, and the system file picker.

Opening from internal storage

The following example opens a document from your app’s internal storage directory:

// Get a file from internal storage.
val filesDir = context.filesDir
val documentFile = File(filesDir, "document.pdf")
val documentUri = Uri.fromFile(documentFile)
// Open the document.
val intent = PdfActivityIntentBuilder.fromUri(context, documentUri)
.build()
context.startActivity(intent)

Opening from external storage

The following example opens a document from your app’s external storage directory without storage permissions:

// Get a file from external storage.
val externalFilesDir = context.getExternalFilesDir(null)
val documentFile = File(externalFilesDir, "document.pdf")
val documentUri = Uri.fromFile(documentFile)
// Open the document.
val intent = PdfActivityIntentBuilder.fromUri(context, documentUri)
.build()
context.startActivity(intent)

Opening with Storage Access Framework

Use the system file picker to enable users to select a document:

// Request code for the file picker.
companion object {
private const val REQUEST_OPEN_DOCUMENT = 100
}
// Launch the file picker.
fun openDocumentPicker() {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/pdf"
}
startActivityForResult(intent, REQUEST_OPEN_DOCUMENT)
}
// Handle the selected document.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_OPEN_DOCUMENT && resultCode == Activity.RESULT_OK) {
data?.data?.let { uri ->
// Open the selected document.
val intent = PdfActivityIntentBuilder.fromUri(this, uri)
.build()
startActivity(intent)
}
}
}

With Intent.ACTION_OPEN_DOCUMENT, Android grants temporary read and write access through the returned URI, so your app doesn’t need storage permissions for this approach.