| Scott Main | 5cdf5fd | 2010-05-11 14:21:53 -0700 | [diff] [blame] | 1 | page.title=App Install Location |
| 2 | @jd:body |
| 3 | |
| 4 | |
| 5 | <div id="qv-wrapper"> |
| 6 | <div id="qv"> |
| 7 | |
| 8 | <h2>Quickview</h2> |
| 9 | <ul> |
| 10 | <li>You can allow your application to install on the device's external storage.</li> |
| 11 | <li>Some types of applications should <strong>not</strong> allow installation on the external |
| 12 | storage.</li> |
| 13 | <li>Installing on the external storage is ideal for large applications that are not tightly |
| 14 | integrated with the system (most commonly, games).</li> |
| 15 | </ul> |
| 16 | |
| 17 | <h2>In this document</h2> |
| 18 | <ol> |
| 19 | <li><a href="#Compatiblity">Backward Compatibility</a></li> |
| 20 | <li><a href="#ShouldNot">Applications That Should NOT Install on External Storage</a></li> |
| 21 | <li><a href="#Should">Applications That Should Install on External Storage</a></li> |
| 22 | </ol> |
| 23 | |
| 24 | <h2>See also</h2> |
| 25 | <ol> |
| 26 | <li><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"> |
| 27 | <manifest></a></code></li> |
| 28 | </ol> |
| 29 | |
| 30 | </div> |
| 31 | </div> |
| 32 | |
| 33 | <p>Beginning with API Level 8, you can allow your application to be installed on the |
| 34 | external storage (for example, the device's SD card). This is an optional feature you can declare |
| 35 | for your application with the <a |
| 36 | href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code |
| 37 | android:installLocation}</a> manifest attribute. If you do |
| 38 | <em>not</em> declare this attribute, your application will be installed on the internal storage |
| 39 | only and it cannot be moved to the external storage.</p> |
| 40 | |
| 41 | <p>To allow the system to install your application on the external storage, modify your |
| 42 | manifest file to include the <a |
| 43 | href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code |
| 44 | android:installLocation}</a> attribute in the <code><a |
| 45 | href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code> element, |
| 46 | with a value of either "{@code preferExternal}" or "{@code auto}". For example:</p> |
| 47 | |
| 48 | <pre> |
| 49 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
| 50 | android:installLocation="preferExternal" |
| 51 | ... > |
| 52 | </pre> |
| 53 | |
| 54 | <p>If you declare "{@code preferExternal}", you request that your application be installed on the |
| 55 | external storage, but the system does not guarantee that your application will be installed on |
| 56 | the external storage. If the external storage is full, the system will install it on the internal |
| 57 | storage. The user can also move your application between the two locations.</p> |
| 58 | |
| 59 | <p>If you declare "{@code auto}", you indicate that your application may be installed on the |
| 60 | external storage, but you don't have a preference of install location. The system will |
| 61 | decide where to install your application based on several factors. The user can also move your |
| 62 | application between the two locations.</p> |
| 63 | |
| 64 | <p>When your application is installed on the external storage:</p> |
| 65 | <ul> |
| 66 | <li>There is no effect on the application performance so long |
| 67 | as the external storage is mounted on the device.</li> |
| 68 | <li>The {@code .apk} file is saved on the external storage, but all private user data, |
| 69 | databases, optimized {@code .dex} files, and extracted native code are saved on the |
| 70 | internal device memory.</li> |
| 71 | <li>The unique container in which your application is stored is encrypted with a randomly |
| 72 | generated key that can be decrypted only by the device that originally installed it. Thus, an |
| 73 | application installed on an SD card works for only one device.</li> |
| 74 | <li>The user can move your application to the internal storage through the system settings.</li> |
| 75 | </ul> |
| 76 | |
| 77 | <p class="warning"><strong>Warning:</strong> When the user enables USB mass storage to share files |
| 78 | with a computer or unmounts the SD card via the system settings, the external storage is unmounted |
| 79 | from the device and all applications running on the external storage are immediately killed.</p> |
| 80 | |
| 81 | |
| 82 | |
| 83 | <h2 id="Compatiblity">Backward Compatibility</h2> |
| 84 | |
| 85 | <p>The ability for your application to install on the external storage is a feature available only |
| 86 | on devices running API Level 8 (Android 2.2) or greater. Existing applications that were built prior |
| 87 | to API Level 8 will always install on the internal storage and cannot be moved to the external |
| 88 | storage (even on devices with API Level 8). However, if your application is designed to support an |
| 89 | API Level <em>lower than</em> 8, you can choose to support this feature for devices with API Level 8 |
| 90 | or greater and still be compatible with devices using an API Level lower than 8.</p> |
| 91 | |
| 92 | <p>To allow installation on external storage and remain compatible with versions lower than API |
| 93 | Level 8:</p> |
| 94 | <ol> |
| 95 | <li>Include the {@code android:installLocation} attribute with a value of "{@code auto}" or |
| 96 | "{@code preferExternal}" in the <code><a |
| Scott Main | 5dd0fd5 | 2010-05-12 14:49:38 -0700 | [diff] [blame] | 97 | href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><manifest></a></code> |
| Scott Main | 5cdf5fd | 2010-05-11 14:21:53 -0700 | [diff] [blame] | 98 | element.</li> |
| 99 | <li>Leave your {@code android:minSdkVersion} attribute as is (something <em>less |
| 100 | than</em> "8") and be certain that your application code uses only APIs compatible with that |
| 101 | level.</li> |
| 102 | <li>In order to compile your application, change your build target to API Level 8. This is |
| 103 | necessary because older Android libraries don't understand the {@code android:installLocation} |
| 104 | attribute and will not compile your application when it's present.</li> |
| 105 | </ol> |
| 106 | |
| 107 | <p>When your application is installed on a device with an API Level lower than 8, the {@code |
| 108 | android:installLocation} attribute is ignored and the application is installed on the internal |
| 109 | storage.</p> |
| 110 | |
| 111 | <p class="caution"><strong>Caution:</strong> Although XML markup such as this will be ignored by |
| 112 | older platforms, you must be careful not to use programming APIs introduced in API Level 8 |
| 113 | while your {@code minSdkVersion} is less than "8", unless you perform the work necessary to |
| Scott Main | 5249ad0 | 2010-10-12 17:08:23 -0700 | [diff] [blame] | 114 | provide backward compatibility in your code. For information about building |
| Scott Main | 5cdf5fd | 2010-05-11 14:21:53 -0700 | [diff] [blame] | 115 | backward compatibility in your application code, see the <a |
| 116 | href="{@docRoot}resources/articles/backward-compatibility.html">Backward Compatibility</a> |
| 117 | article.</p> |
| 118 | |
| 119 | |
| 120 | |
| 121 | <h2 id="ShouldNot">Applications That Should NOT Install on External Storage</h2> |
| 122 | |
| 123 | <p>When the user enables USB mass storage to share files with their computer (or otherwise |
| 124 | unmounts or removes the external storage), any application |
| 125 | installed on the external storage and currently running is killed. The system effectively becomes |
| 126 | unaware of the application until mass storage is disabled and the external storage is |
| 127 | remounted on the device. Besides killing the application and making it unavailable to the user, |
| 128 | this can break some types of applications in a more serious way. In order for your application to |
| 129 | consistently behave as expected, you <strong>should not</strong> allow your application to be |
| 130 | installed on the external storage if it uses any of the following features, due to the cited |
| 131 | consequences when the external storage is unmounted:</p> |
| 132 | |
| 133 | <dl> |
| 134 | <dt>Services</dt> |
| 135 | <dd>Your running {@link android.app.Service} will be killed and will not be restarted when |
| 136 | external storage is remounted. You can, however, register for the {@link |
| 137 | android.content.Intent#ACTION_EXTERNAL_APPLICATIONS_AVAILABLE} broadcast Intent, which will notify |
| 138 | your application when applications installed on external storage have become available to the |
| 139 | system again. At which time, you can restart your Service.</dd> |
| 140 | <dt>Alarm Services</dt> |
| 141 | <dd>Your alarms registered with {@link android.app.AlarmManager} will be cancelled. You must |
| 142 | manually re-register any alarms when external storage is remounted.</dd> |
| 143 | <dt>Input Method Engines</dt> |
| 144 | <dd>Your <a href="{@docRoot}resources/articles/on-screen-inputs.html">IME</a> will be |
| 145 | replaced by the default IME. When external storage is remounted, the user can open system settings |
| 146 | to enable your IME again.</dd> |
| 147 | <dt>Live Wallpapers</dt> |
| 148 | <dd>Your running <a href="{@docRoot}resources/articles/live-wallpapers.html">Live Wallpaper</a> |
| 149 | will be replaced by the default Live Wallpaper. When external storage is remounted, the user can |
| 150 | select your Live Wallpaper again.</dd> |
| 151 | <dt>Live Folders</dt> |
| 152 | <dd>Your <a href="{@docRoot}resources/articles/live-folders.html">Live Folder</a> will be |
| 153 | removed from the home screen. When external storage is remounted, the user can add your Live Folder |
| 154 | to the home screen again.</dd> |
| 155 | <dt>App Widgets</dt> |
| 156 | <dd>Your <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widget</a> will be removed |
| 157 | from the home screen. When external storage is remounted, your App Widget will <em>not</em> be |
| 158 | available for the user to select until the system resets the home application (usually not until a |
| 159 | system reboot).</dd> |
| 160 | <dt>Account Managers</dt> |
| 161 | <dd>Your accounts created with {@link android.accounts.AccountManager} will disappear until |
| 162 | external storage is remounted.</dd> |
| 163 | <dt>Sync Adapters</dt> |
| 164 | <dd>Your {@link android.content.AbstractThreadedSyncAdapter} and all its sync functionality will |
| 165 | not work until external storage is remounted.</dd> |
| 166 | <dt>Device Administrators</dt> |
| 167 | <dd>Your {@link android.app.admin.DeviceAdminReceiver} and all its admin capabilities will |
| 168 | be disabled, which can have unforeseeable consequences for the device functionality, which may |
| 169 | persist after external storage is remounted.</dd> |
| Scott Main | 5249ad0 | 2010-10-12 17:08:23 -0700 | [diff] [blame] | 170 | <dt>Broadcast Receivers listening for "boot completed"</dt> |
| 171 | <dd>The system delivers the {@link android.content.Intent#ACTION_BOOT_COMPLETED} broadcast |
| 172 | before the external storage is mounted to the device. If your application is installed on the |
| 173 | external storage, it can never receive this broadcast.</dd> |
| Joe Fernandez | f6d8de6 | 2011-05-12 10:00:25 -0700 | [diff] [blame] | 174 | <dt>Copy Protection</dt> |
| 175 | <dd>Your application cannot be installed to a device's SD card if it uses Android Market's |
| 176 | Copy Protection feature. However, if you use Android Market's |
| 177 | <a href="{@docRoot}guide/publishing/licensing.html">Application Licensing</a> instead, your |
| 178 | application <em>can</em> be installed to internal or external storage, including SD cards.</dd> |
| Scott Main | 5cdf5fd | 2010-05-11 14:21:53 -0700 | [diff] [blame] | 179 | </dl> |
| 180 | |
| 181 | <p>If your application uses any of the features listed above, you <strong>should not</strong> allow |
| 182 | your application to install on external storage. By default, the system <em>will not</em> allow your |
| 183 | application to install on the external storage, so you don't need to worry about your existing |
| 184 | applications. However, if you're certain that your application should never be installed on the |
| 185 | external storage, then you should make this clear by declaring <a |
| 186 | href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code |
| 187 | android:installLocation}</a> with a value of "{@code internalOnly}". Though this does not |
| 188 | change the default behavior, it explicitly states that your application should only be installed |
| 189 | on the internal storage and serves as a reminder to you and other developers that this decision has |
| 190 | been made.</p> |
| 191 | |
| 192 | |
| 193 | <h2 id="Should">Applications That Should Install on External Storage</h2> |
| 194 | |
| 195 | <p>In simple terms, anything that does not use the features listed in the previous section |
| 196 | are safe when installed on external storage. Large games are more commonly the types of |
| 197 | applications that should allow installation on external storage, because games don't typically |
| Scott Main | f0dd587 | 2011-08-26 11:30:56 -0700 | [diff] [blame] | 198 | provide additional services when inactive. When external storage becomes unavailable and a game |
| Scott Main | 5cdf5fd | 2010-05-11 14:21:53 -0700 | [diff] [blame] | 199 | process is killed, there should be no visible effect when the storage becomes available again and |
| 200 | the user restarts the game (assuming that the game properly saved its state during the normal |
| Scott Main | 9bf45a0 | 2011-02-03 18:46:45 -0800 | [diff] [blame] | 201 | <a href="{@docRoot}guide/topics/fundamentals/activities.html#Lifecycle">Activity lifecycle</a>).</p> |
| Scott Main | 5cdf5fd | 2010-05-11 14:21:53 -0700 | [diff] [blame] | 202 | |
| 203 | <p>If your application requires several megabytes for the APK file, you should |
| 204 | carefully consider whether to enable the application to install on the external storage so that |
| 205 | users can preserve space on their internal storage.</p> |
| 206 | |