Nutrient supports opening files from the local file system of your device. This article provides best practices for working with local files in your apps.

## Never hardcode absolute paths

Directories where your app stores files are not guaranteed to be stable between different devices or even between app restarts, and paths to your app’s files may change over time if the app is moved to an adopted storage device. We recommend using methods from [`Context`](https://developer.android.com/reference/android/content/Context.html) to access different special file system directories. More specifically:

- Use [`Context#getFilesDir`](https://developer.android.com/reference/android/content/Context.html#getFilesDir()) to get the path to the file system directory where your internal files are stored. Use this path instead of hardcoding the device-dependent path `/data/data/<application_package/files`.

- Use [`Context#getExternalFilesDir(null)`](https://developer.android.com/reference/android/content/Context.html#getExternalFilesDir(java.lang.String)) to get the path to the primary shared/external storage device where your application can place the persistent files it owns. Use this path instead of hardcoding the device-dependent path `/storage/emulated/0/`.

If you need to persist paths to files (for example, in a database or in settings), only relative paths should be persisted.

## Accessing the external storage

Android devices support shared “external storage” that can be used for storing files. These can be removable (for example, SD cards or USB hard drives) or non-removable (internal). External storage can become unavailable for multiple reasons and does not enforce any security restrictions for accessing your files. Make sure that your application handles these situations correctly.

### Storage Access Framework

Use the [Storage Access Framework](https://developer.android.com/guide/topics/providers/document-provider.html) if you are running on Android 4.4+ and you want to allow users to browse and open documents from device storage.

You can find a complete example of how to access files through the Storage Access Framework inside `ExternalDocumentExample` of the Catalog app.

### Permissions to external storage

In order to read or write files on the external storage, your app must acquire `READ_EXTERNAL_STORAGE` or `WRITE_EXTERNAL_STORAGE` permissions. To acquire these permissions, add them to your manifest:

```xml

<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>

```

If your app targets Android 6.0+, these permissions are not granted to your app automatically after installation. You need to [explicitly ask for them](https://developer.android.com/training/permissions/requesting.html) in your activity:

### KOTLIN

```kotlin

override fun onCreate(savedInstanceState: Bundle?) {...
    // Request permission here.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(activity, 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) {
    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.
            }
        }
    }
}

```

### JAVA

```java

@Override
protected void onCreate(Bundle savedInstanceState) {...
    // Request permission here.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_ASK_FOR_PERMISSION);
        }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQUEST_ASK_FOR_PERMISSION) {
        if (grantResults.length > 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.
            }
        }
    }
}

```

Since Android 4.4+, these permissions have no longer been required when accessing external files of your app (stored in the [`Context#getExternalFilesDir(null)`](https://developer.android.com/reference/android/content/Context.html#getExternalFilesDir\(java.lang.String\)) directory).

## Scoped directory access

Note that `READ_EXTERNAL_STORAGE` and `WRITE_EXTERNAL_STORAGE` permissions allow access to all public directories on the external storage, which could make your users worried or suspicious.

Use [scoped directory access](https://developer.android.com/training/articles/scoped-directory-access.html) if you are running on Android 7.0+ and you only need to access a specific directory on the external storage. This provides a simple permissions UI that clearly states which directory your application is requesting access to.
---

## Related pages

- [About Memory Usage](/guides/android/memory-and-storage/about-memory-usage.md)
- [Customizing The Page Number](/guides/android/customizing-pdf-pages/customizing-the-page-number.md)
- [Managing data storage and privacy in Android](/guides/android/best-practices/data-storage-and-privacy.md)
- [Framework Size](/guides/android/faq/framework-size.md)
- [Check For Compatibility](/guides/android/faq/check-for-compatibility.md)
- [Remove all Android logging calls that should be ignored in release builds to prevent logs in Logcat.](/guides/android/features/logging.md)
- [Nightly Builds](/guides/android/advanced-integration/nightly-builds.md)
- [Permissions](/guides/android/advanced-integration/permissions.md)
- [Optimize Pdf Documents For Mobile Rendering](/guides/android/miscellaneous/optimize-pdf-documents-for-mobile-rendering.md)
- [Android PDF SDK security](/guides/android/faq/sdk-security.md)
- [Manual Library Integration](/guides/android/advanced-integration/manual-library-integration.md)
- [Third Party Compatibility](/guides/android/miscellaneous/third-party-compatibility.md)
- [Subscription Validation](/guides/android/announcements/subscription-validation.md)
- [Powered By Nutrient](/guides/android/miscellaneous/powered-by-nutrient.md)
- [Unsupported Internal Symbols](/guides/android/announcements/unsupported-internal-symbols.md)

