Technical Data Questionnaire - novoda/storage-path-finder GitHub Wiki

Overview of the project. What are its technical capabilities compared to the industry standard?

Develop a library that performs the heavy lifting when it comes to finding accessible storage paths for an android application. Depending on the version of android a different flow needs to be adhered to when finding a storage path. There are additional challenges also from manufacturers not setting some device parameters related to storage devices, which this library also wraps.

What platforms and tools were used to make it?

No additional platforms and tools. This is a pure, base Android Library that uses only truth and mockito for testing what was created.

Technical challenges faced (specifically what development required more than routine techniques) and what was engineered to overcome them?


There are quite a few challenges associated with creating a library that wraps all of the complexity with finding storage path locations and the associated metadata. Here are some of the snippets taken from discussions by the developers and PRs in this library:

  1. API 18 is required for block size calculations, this is used for getting the used/available/total storage. We can do this for Primary storage on all supported API levels via another method (the Environment calls), b this is only Primary. For Secondary, we need to the StatFS functions with a path parameter, and this is only available for API 18 +.

  2. For the Storage states such as mount, removable and emulated, API 21 is required to collect them for Secondary storage. The states are collected via the Environment.get...( calls, and these are available for all supported API levels for the Primary path, but the version of these calls that allows you to pass a Path as a parameter was only introduced in API 21. And this is the way we need for getting the states for secondary storage.

  3. FileUtils.sizeOfDirectory explicitly crashes when a file does not exist. Rather than crash, we roll our own so that in the scenario where a file is missing we can call File.length. This File.length will check for a valid file, if invalid then return 0 as the size, rather than crashing.

  4. ContextCompat.getExternalFilesDirs(context, null)[0]; calls down to new File[] { context.getExternalFilesDir(type) }; which can be null when the shared storage is not available. Confusingly it seems that on earlier versions of android this shared storage is flagged as SD card storage even when there might not be an SD card involved. Rather than allowing a NPE to occur we deal with the error and return an empty list to display to the user.

  5. Not all manufacturers set a system variable for system.getEnv("SECONDARY_STORAGE"); so we have several different approaches for retrieving secondary storage locations, which we then filter to remove duplicates.