The Android Developer Challenge is back! Submit your idea before December 2.

アプリのインストール場所

API レベル 8 以降では、アプリを外部ストレージ(端末の SD カードなど)にインストールできます。これは、android:installLocation マニフェスト属性を使用してアプリに対して宣言できるオプション機能です。この属性を宣言しない場合、アプリは内部ストレージにのみインストールされ、外部ストレージに移動することはできません。

システムがアプリを外部ストレージにインストールできるようにするには、マニフェスト ファイルを修正して <manifest> エレメントに android:installLocation 属性を追加し "preferExternal" または "auto" のいずれかの値を指定します。次に例を示します。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:installLocation="preferExternal"
    ... >

"preferExternal" を宣言した場合、アプリを外部ストレージにインストールする要求は行われますが、アプリが外部ストレージにインストールされる保証はありません。外部ストレージがいっぱいのときは、内部ストレージにインストールされます。ユーザーは外部ストレージと内部ストレージの間でアプリを移動させることもできます。

"auto" を宣言した場合、アプリを外部ストレージにインストールしてもよいと指定するものの、優先的なインストール場所は設定しません。いくつかの要因に基づいて、システムがアプリをインストールする場所を決定します。ユーザーは外部ストレージと内部ストレージの間でアプリを移動させることもできます。

アプリが外部ストレージにインストールされているときは、次のようになります。

  • 外部ストレージが端末にマウントされている限り、アプリのパフォーマンスに影響はありません。
  • .apk ファイルは外部ストレージに保存されますが、すべてのプライベート ユーザーデータ、データベース、最適化された .dex ファイル、および抽出されたネイティブ コードは、内部デバイスメモリに保存されます。
  • アプリが格納される一意のコンテナは、ランダムに生成された鍵で暗号化され、最初にアプリをインストールした端末によってのみ復号化できます。そのため、SD カードにインストールされたアプリは、1 つの端末に対してのみ動作します。
  • ユーザーは、システム設定によりアプリを内部ストレージに移動できます。

警告:ユーザーがコンピュータとファイル共有するために USB マスストレージを有効にするか、システム設定で SD カードのマウントを解除すると、外部ストレージは端末からマウント解除され、外部ストレージで実行されているすべてのアプリは直ちに強制終了されます。

下位互換性

アプリを外部ストレージにインストールできる機能は、API レベル 8(Android 2.2)以上が実行されている端末でのみ使用できます。API レベル 8 より前にビルドされた既存のアプリは必ず内部ストレージにインストールされ、(API レベル 8 が動作している端末であっても)外部ストレージに移動することはできません。しかし、アプリが 8 より低い API レベルをサポートするように設計されている場合は、API レベル 8 以上の端末ではこの機能をサポートするように選択でき、かつ 8 より低い API レベルを使用する端末との互換性も維持されます。

外部ストレージへのインストールを許可し、API レベル 8 よりも低いバージョンとの互換性を維持するには、次の手順を行います。

  1. <manifest> 要素に android:installLocation 属性を含め、これに "auto" または "preferExternal" の値を指定します。
  2. android:minSdkVersion 属性はそのまま(「8」よりも小さい値)にしておき、アプリコードではそのレベルと互換性のある API のみが使用されるようにします。
  3. アプリをコンパイルするために、ビルド ターゲットを API レベル 8 に変更します。古い Android ライブラリは android:installLocation 属性を認識せず、この属性があるとアプリがコンパイルされないので、このように変更することが必要です。

アプリが 8 よりも低い API レベルの端末にインストールされる場合、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:installLocationinternalOnly を指定して宣言して、そのことを明確にする必要があります。この設定によってデフォルトの動作が変更されることはありませんが、アプリを内部ストレージにのみインストールしなければならないことが明示的に記述され、関係するデベロッパーにこの決定がなされたことを知らせるものになります。

外部ストレージにインストールすべきアプリ

簡単に言うと、前のセクションで列挙した機能を使用しないアプリであれば、外部ストレージにインストールしても安全です。サイズの大きいゲームは一般に外部ストレージへのインストールを可能にすべきアプリです。なぜなら、通常、ゲームは動作時以外に追加サービスを提供することがないからです。外部ストレージが使用できなくなってゲームプロセスが強制終了しても、外部ストレージが再び利用可能になりユーザーがゲームを再起動した場合(通常の Activity ライフサイクルでゲームの状態が適切に保存されたと仮定して)、見た目の影響は何もないはずです。

アプリの APK ファイルが数メガバイトのサイズである場合は、内部ストレージ上のスペースを消費しないようにユーザーがアプリを外部ストレージにインストールできるようにするかどうか慎重に検討する必要があります。

その他の関連情報については、<manifest> をご覧ください。