API レベル 8 以降では、外部ストレージ(デバイスの SD カードなど)へのアプリのインストールを許可できます。これは、アプリに対して android:installLocation
マニフェスト属性で宣言できるオプションの機能です。この属性を宣言しなければ、アプリは内部ストレージのみにインストールされ、外部ストレージには移動できません。
外部ストレージへのアプリのインストールをシステムに許可するには、マニフェスト ファイルを変更して <manifest>
要素に android:installLocation
属性を追加し、値を preferExternal
または auto
に設定します。次に例を示します。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" ... >
preferExternal
を宣言した場合は、外部ストレージへのアプリのインストールをリクエストしたことを意味しますが、システムが外部ストレージにアプリをインストールする保証はありません。外部ストレージに空き領域がなければ、内部ストレージにインストールされます。また、ユーザーは 2 つの場所の間でアプリを移動できます。
auto
を宣言した場合は、アプリを外部ストレージにインストールしてもよいがインストール場所は指定しないことを意味します。システムは、さまざまな要因に基づいて、アプリをインストールする場所を決定します。また、ユーザーは 2 つの場所の間でアプリを移動できます。
アプリが外部ストレージにインストールされた場合、次のようになります。
- 外部ストレージがデバイスにマウントされている限り、アプリのパフォーマンスは影響を受けません。
.apk
ファイルは外部ストレージに保存されますが、すべてのプライベート ユーザーデータ、データベース、最適化された.dex
ファイル、抽出されたネイティブ コードは内部デバイスメモリに保存されます。- アプリが格納される一意のコンテナは、ランダムに生成された鍵で暗号化されます。この鍵を復号できるのは、アプリが最初にインストールされたデバイスだけです。したがって、SD カードにインストールされたアプリは 1 つのデバイスでのみ動作します。
- ユーザーは、システム設定を介してアプリを内部ストレージに移動できます。
警告: ユーザーが USB マスストレージを有効にしてパソコンとファイルを共有したときや、システム設定を介して SD カードのマウントを解除したときは、外部ストレージがデバイスからマウント解除され、外部ストレージで実行されているすべてのアプリは直ちに強制終了されます。
下位互換性
外部ストレージにアプリをインストールする機能は、API レベル 8(Android 2.2)以上を搭載したデバイスでのみ利用できます。API レベル 8 より前にビルドされた既存のアプリは、常に内部ストレージにインストールされ、外部ストレージ(API レベル 8 を搭載したデバイスも含む)には移動できません。ただし、アプリが API レベル 8 未満をサポートするように設計されている場合、API レベル 8 以上を搭載したデバイスでこの機能をサポートしつつ、API レベル 8 未満を使用するデバイスとの互換性を維持することを選択できます。
外部ストレージへのインストールを許可し、API レベル 8 未満のバージョンとの互換性を維持するには:
<manifest>
要素にandroid:installLocation
属性を含め、値としてauto
またはpreferExternal
を指定します。android:minSdkVersion
属性をそのまま(8 未満の数値)にして、アプリコードではそのレベルと互換性のある API のみを使用するようにします。- アプリをコンパイルするため、ビルド ターゲットを API レベル 8 に変更します。古い Android ライブラリは
android:installLocation
属性を理解せず、この属性があるとアプリがコンパイルされないので、この変更が必要です。
API レベル 8 未満を搭載したデバイスにアプリをインストールすると、android:installLocation
属性は無視され、アプリは内部ストレージにインストールされます。
注意: このような XML マークアップは古いプラットフォームでは無視されますが、minSdkVersion
が 8 未満のときは API レベル 8 で導入されたプログラミング API を使用しないように注意してください。ただし、コード内で下位互換性を維持するために必要な作業を実施する場合は別です。
外部ストレージにインストールすべきでないアプリ
ユーザーが USB マスストレージを有効にしてパソコンとファイルを共有したとき(または外部ストレージのマウントを解除したか取り外したとき)、外部ストレージにインストールされた現在実行中のアプリはすべて強制終了されます。マスストレージを無効にして外部ストレージをデバイスに再度マウントするまで、システムは事実上アプリを認識しません。つまり、アプリが強制終了されてユーザーが利用できなくなるだけでなく、アプリのタイプによっては深刻な障害が発生するおそれがあります。アプリを常に想定どおりに動作させるためには、アプリが次の機能のいずれかを使用する場合、外部ストレージへのアプリのインストールを許可すべきではありません。外部ストレージのマウントが解除されたときに、次のような結果が生じるからです。
- サービス
- 実行中の
Service
は強制終了され、外部ストレージを再度マウントしても再起動しません。このサービスにバインドされているアプリは、ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
ブロードキャスト インテントを登録できます。このインテントは、外部ストレージにインストールされているアプリをシステムが再び利用できるようになったとき、外部ストレージにインストールされていないすべてのアプリにそのことを通知します。アプリはこのブロードキャストを受信した後、サービスへのバインドを試みることができます。 - アラーム サービス
AlarmManager
で登録されたアラームはキャンセルされます。外部ストレージを再度マウントするときに、手動でアラームを再登録する必要があります。- インプット メソッド エンジン
- ユーザーが使用している IME は、デフォルトの IME に置き換えられます。外部ストレージを再度マウントしたとき、ユーザーはシステム設定を開いて自分が使用する IME を再度有効にできます。
- ライブ壁紙
- ユーザーが実行しているライブ壁紙は、デフォルトのライブ壁紙に置き換えられます。外部ストレージを再度マウントしたとき、ユーザーは自分が実行するライブ壁紙を再度選択できます。
- アプリ ウィジェット
- ユーザーが使用しているアプリ ウィジェットは、ホーム画面から削除されます。外部ストレージを再度マウントしても、システムがホームアプリをリセットするまで(通常はシステムを再起動するまで)、ユーザーは外部ストレージにあるアプリ ウィジェットを選択できません。
- アカウント マネージャー
AccountManager
で作成されたアカウントは、外部ストレージが再度マウントされるまで表示されません。- 同期アダプター
- ユーザーが使用している
AbstractThreadedSyncAdapter
とそのすべての同期機能は、外部ストレージが再度マウントされるまで機能しません。 - デバイス管理
- ユーザーが使用している
DeviceAdminReceiver
とそのすべての管理機能は無効になり、それによってデバイスの機能に予測不能な影響が生じる可能性があります。その影響は外部ストレージを再度マウントした後も続く場合があります。 - 「起動の完了」をリッスンするブロードキャスト レシーバ
- 外部ストレージがデバイスにマウントされる前に、システムは
ACTION_BOOT_COMPLETED
ブロードキャストを配信します。外部ストレージにインストールされているアプリは、このブロードキャストを受信できません。
アプリが上記の機能のいずれかを使用する場合は、外部ストレージへのアプリのインストールを許可すべきではありません。デフォルトでは、システムは外部ストレージへのアプリのインストールを許可しません。したがって、既存のアプリに関する心配は不要です。しかし、アプリを外部ストレージにインストールすべきでないという確信がある場合は、android:installLocation
に値 internalOnly
を指定して宣言することにより、そのことを明確に示す必要があります。この宣言によってデフォルトの動作が変更されることはありませんが、アプリが内部ストレージにのみインストールされるべきであると明示的に表明し、この決定がなされたことを自分自身と他のデベロッパーにリマインダーとして知らせることができます。
外部ストレージにインストールすべきアプリ
簡単に言うと、前のセクションで挙げた機能を使用しないアプリやサービスは、外部ストレージにインストールしても安全です。一般的に、サイズの大きいゲームは外部ストレージへのインストールを許可すべきタイプのアプリです。通常、ゲームはアクティブでないときは追加のサービスを提供しないからです。外部ストレージが利用できなくなりゲームプロセスが強制終了された場合、ストレージが再び利用可能になってユーザーがゲームを再起動したとき、(通常のアクティビティ ライフサイクルでゲームの状態が正常に保存されていれば)目に見える影響は何もないはずです。
APK ファイル用に数メガバイトを必要とするアプリについては、ユーザーが内部ストレージの空き容量を確保できるように、外部ストレージにアプリをインストールできるかどうかを慎重に検討すべきです。
その他の関連情報については、<manifest> をご覧ください。