應用程式安裝位置

自 API 級別 8 起,即可在外部儲存空間 (例如裝置的 SD 卡) 安裝應用程式。這是一項選用功能,您可以使用 android:installLocation 資訊清單屬性針對應用程式進行宣告。如果您「未」宣告此屬性,應用程式只會安裝在內部儲存空間中,且無法移至外部儲存空間。

如要允許系統在外部儲存空間上安裝應用程式,請修改資訊清單檔案,將 android:installLocation 屬性加入 <manifest> 元素,該屬性的值為「preferExternal」或「auto」。例如:

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

如果您宣告「preferExternal」,就表示您要求將應用程式安裝在外部儲存空間,但系統無法保證您的應用程式會安裝在外部儲存空間。如果外部儲存空間已滿,系統將安裝在內部儲存空間。使用者還可以在兩個位置之間移動應用程式。

如果您宣告「auto」,就表示應用程式可以安裝在外部儲存空間,但您沒有偏好的安裝位置。系統將根據多項因素來決定應用程式的安裝位置。使用者還可以在兩個位置之間移動應用程式。

應用程式安裝在外部儲存空間時:

  • 只要外部儲存空間掛接在裝置上,就不會對應用程式效能造成任何影響。
  • .apk 檔案會儲存在外部儲存空間,但所有私人使用者資料、資料庫、最佳化的 .dex 檔案與擷取的原生程式碼都會儲存在內部裝置記憶體中。
  • 儲存應用程式的唯一容器使用隨機產生的金鑰加密,這個金鑰只能由原先進行安裝的裝置解密。因此,安裝在 SD 卡上的應用程式只適用於一部裝置。
  • 使用者可以透過系統設定將應用程式移至內部儲存空間。

警告:當使用者允許 USB 高容量儲存裝置與電腦共用檔案,或是透過系統設定卸載 SD 卡,外部檔案將從裝置卸載,且在外部儲存空間上執行的所有應用程式會立即中止。

向下相容性

只有在搭載 API 級別 8 (Android 2.2) 以上版本的裝置上,應用程式才能安裝在外部儲存空間。在 API 級別 8 之前建構的現有應用程式,一律安裝於內部儲存空間,且無法移至外部儲存空間 (即使 API 級別 8 的裝置也是如此)。不過,如果您的應用程式是專為支援API 級別 8 以下而設計,您可以選擇讓 API 級別 8 以上的裝置支援這項功能,同時仍與使用 API 級別 8 以下的裝置相容。

如要允許在外部儲存空間上安裝,並與 API 級別 8 以下的版本相容,請按照以下步驟操作:

  1. <manifest> 元素中加入值為「auto」或「preferExternal」的 android:installLocation 屬性。
  2. 保持 android:minSdkVersion 屬性不變「(小於「8」),並確定應用程式程式碼僅使用與該級別相容的 API。
  3. 如要編譯應用程式,請將建構目標變更為 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 廣播。如果您將應用程式安裝在外部儲存空間,則一律無法接收這個廣播。

如果您的應用程式使用上述任何功能,不應允許應用程式安裝在外部儲存空間。根據預設,系統不會允許應用程式安裝到外部儲存空間,因此您無需擔心現有的應用程式。不過,如果您確定應用程式絕對不該安裝在外部儲存空間,則應宣告 值為「internalOnly」的 android:installLocation來清楚聲明這一點。雖然此操作不會變更預設行為,但能明確指出應用程式只應安裝在內部儲存空間中,而且可以提醒您和其他開發人員已做出這項決定。

應安裝在外部儲存空間的應用程式

簡單來說,只要不使用前一節列出的功能,安裝在外部儲存空間就安全無虞。大型遊戲是應允許安裝在外部儲存空間的常見應用程式類型,因為遊戲在非使用中時通常無法提供額外服務。如果外部儲存空間無法使用,且遊戲處理程序被終止,當儲存空間再次可供使用,且使用者重新啟動遊戲時 (假設遊戲在正常活動生命週期中正確儲存狀態),應該不會有明顯的影響。

如果您的應用程式需要好幾 MB 供 APK 檔案使用,您應謹慎考慮是否要讓應用程式安裝在外部儲存空間,以便使用者可以保留內部儲存空間。

如需其他相關資訊,請參閱: <manifest>