Device-protected Storage
Device-protected storage (or device encrypted storage) is a storage location available both during Direct Boot mode and after the user has unlocked the device. Device-protected storage contains data encrypted with a key that is only available after a device has performed a successful verified boot (the key is tied to physical device).
Device-protected storage is typically used to access data while Android application is running in Direct Boot mode. Because device-protected data is available without user authentication, you should carefully limit the data you use in this storage.
If the underlying device does not have the ability to store device-protected and credential-protected data using different keys, then both storage areas will become available at the same time. They remain as two distinct storage locations on disk, and only the window of availability changes.
Basic Usages​
Creating Device-protected Storage Context​
For utilizing device-protected storage, we need to create a separate Context
instance through createDeviceProtectedStorageContext()
method:
import android.content.Context
val deviceProtectedContext: Context = context.createDeviceProtectedStorageContext()
Each call to this method returns a new instance of a Context
object; Context
objects are not shared, however common state (ClassLoader, other Resources for the same configuration) may be so the Context
itself can be fairly lightweight.
We can demonstrate the difference between regular Context
instance and a Context
backed by device-protected storage by creating a File in each Context
's internal storage and inspecting their paths:
import android.content.Context
import android.util.Log
import java.io.File
// Create a file in regular Context.
val normalFile = File(context.filesDir, "normal.txt")
Log.i("normalFile", normalFile.absolutePath)
// The above line will log:
// /data/user/0/com.hanmajid.androidnotebook/files/normal.txt
// Create a file in Context backed by device-protected storage.
val deviceProtectedContext: Context = context.createDeviceProtectedStorageContext()
val deviceProtectedFile = File(deviceProtectedContext.filesDir, "device-protected.txt")
Log.i("deviceProtectedFile", deviceProtectedFile.absolutePath)
// The above line will log:
// /data/user_de/0/com.hanmajid.androidnotebook/files/device-protected.txt
Notice that each Context
uses different location: /data/user
and data/user_de
.
Checking If Context Uses Device-protected Storage​
We can check whether a Context
is currently using device-protected storage or not by using isDeviceProtectedStorage()
:
import android.content.Context
val isContextDeviceProtected: Boolean = context.isDeviceProtectedStorage
Moving Shared Preferences Between Contexts​
It is possible to move shared preferences file from one Context
to another with moveSharedPreferencesFrom()
method:
import android.content.Context
val deviceProtectedContext: Context = context.createDeviceProtectedStorageContext()
val isSuccess = deviceProtectedContext.moveSharedPreferencesFrom(context, "test.sp")
Moving Database Between Contexts​
It is possible to move database file from one Context
to another with moveDatabaseFrom()
method:
import android.content.Context
val deviceProtectedContext: Context = context.createDeviceProtectedStorageContext()
val isSuccess = deviceProtectedContext.moveDatabaseFrom(context, "test.db")