[This post is by Suchi Amalapurapu, an engineer who worked on this feature. — Tim Bray]
Android 2.2 supports application installation on external storage devices like the SD card. This should give users room for many more apps, and will also benefit certain categories, like games, that need huge assets.
(Note that not all of the contents of an “SD-card-resident” APK are actually on the card; the dex files, private data directories, and native shared libraries remain in internal storage.)
The “Manage Applications” screen in the Settings app now has an “On SD Card” tab. The sizes listed in Manage Applications only include the space taken by the application on internal storage.
The Application Info screen now has either a “move to SD card” or “move to phone” button, but this is often disabled. Copy-protected apps and updates to system apps can’t be moved to the SD card, nor can those which are don’t specify that they work on the SD card.
Controlling Installation Preference
SD-card installation is an optional feature on Android 2.2, is under the control of the developer not the user, and will not affect any applications built prior to Android 2.2.
Application developers can set the field android:installLocation
in the root manifest element to one of these values:
internalOnly
: Install the application on internal storage only. This will result in storage errors if the device runs low on internal storage.preferExternal
: The android system tries to install the application on external storage. If that is full, the application is installed on internal storage.auto
: Let the Android system decide the best install location for the application. The default system policy is to install the application on internal storage first. If the system is running low on storage, the application is then installed on external storage.
If the installLocation
is not specified (as is the case for all applications prior to Android 2.2), the application is installed on internal storage. Application updates will by default try to retain their install location, but application developers may change the installLocation field in an update. Installing an application with this new attribute on older devices will not break compatibility and these applications will be installed on internal storage only.
Application developers can also explicitly install under-development code on external storage via adb install flags, which override the installLocation field: -f for internal storage, and -s for external storage. They can also override the default install location to verify and test application installation on SD card with an adb shell pm command:
adb shell pm setInstallLocation
option
Where option is one of:
0 [auto] Let the system decide.
1 [internal only]
2 [external]
The current install location can be retrieved viaadb shell pm getInstallLocation
Note that changing this default can cause applications to misbehave if they’re not prepared to live on the SD card.
USB Mass Storage interactions
The Android system stores the SD-card-resident applications’ APKs in a secure application-specific container. A new flag FLAG_EXTERNAL_STORAGE
in ApplicationInfo object indicates that an application is currently installed on the SD card. This storage is removed when an SD-card-resident app is uninstalled.
When an Android device’s SD card is unmounted, applications installed on it are no longer available. Their internal storage is still there and such apps can be uninstalled without replacing the SD card.
The Android framework provides several broadcast intents to support the (small) class of applications, such as launchers, that access other applications’ resources:
When the SD card is unmounted,
ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE
with a list of the disabled applications and a list of corresponding application uid’s via extra attributes in the broadcast intent.When the SD card is mounted,
ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
with a list of enabled applications and a list of corresponding application uid’s via extra attributes in the broadcast intent.
Applications that handle broadcast intents like ACTION_PACKAGE_ADDED
, ACTION_PACKAGE_REMOVED
may also want to handle these additional notifications.
When an application gets moved between internal to external storage and vice versa, the application is disabled first (which includes broadcasting intent ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE
), the asset resources are copied, and then the application is enabled (which includes broadcasting intent ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
).
Security and Performance Implications
Applications on SD card are mounted via Linux’s loopback interface and encrypted via a device-specific key, so they cannot be decrypted on any other device. Note that this is security measure and does not provide copy protection; the apps are world readable just like the resources of normal applications installed on the device’s internal storage. Copy-protected applications cannot be installed on external media. In the interests of stability, updates to system applications also cannot be installed on the external media. The application resources stored on external storage are read-only and hence there are no performance issues with loading or launching applications on SD card.
Swapping or Transferring SD Card Contents
It has always been the case that when you swap SD cards on an Android device, if you physically copy the contents of the old card to the new one, the system will use the data on the new card as if nothing had changed. This is also true of apps which have been installed on the SD card.
When not to install on SD card?
The advantage of installing on SD card is easy to understand: contention for storage space is reduced. There are costs, the most obvious being that your app is disabled when the SD card is either removed or in USB Mass Storage mode; this includes running Services, not just interactive Activities. Aside from this, device removal disables an application’s Widgets, Input methods, Account Managers, Device administrators, Live wallpapers, and Live folders, and may require explicit user action to re-enable them.