在Froyo(android 2.2,API Level:8)中引入了android:installLocation.通過設置該屬性可以使得開發者以及用戶決定程序的安裝位置.
android:installLocation隸屬於AndroidManifest.XML中的manifest節點.如下所示:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="string" android:sharedUserId="string" android:sharedUserLabel="string resource" android:versionCode="integer" android:versionName="string" android:installLocation=["auto" | "internalOnly" | "preferExternal"] > . . . </manifest>
android:installLocation可以設置為"auto"、"internalOnly"、"preferExternal"三個值中的任何一個.
- auto:程序可能被安裝在外部存儲介質上(例如:SD Card),但是默認會被安裝到手機內存中.當手機內存為空時,程序將被安裝到外部存儲介質上.當程序安裝到手機上后, 用戶可以決定把程序放在外部儲介質還是內存中.
- internalOnly:默認值.當設置為該值時,程序只能被安裝在內存中,如果內存為空,則程序將不能成功安裝.
- preferExternal:將程序安裝在外部存儲介質上,但是系統不保證程序一定會被安裝到外部存儲介質上.當外部存儲介質不可以或空時,程序將被安裝到內存中.
程序使用了forward-locking機制時也將被安裝到內存中,因為外部存儲不支持此機制.程序安裝后,用戶可以自由切換程序應該在外部還是內部存儲介質上.
注意:當程序使用了Google Play的Copy Protection特性時,只能安裝到內存中.
當程序被安裝到外部存儲介質時,
① .apk文件將被移動到外部存儲介質上,但是程序的數據仍然會在內存中
② 保存.apk文件的容器將會使用一個隨機生成的密鑰進行加密,這樣只有安裝該程序的設置可以使用存在外部存儲介質上的數據.
警告:當外部存儲介質被卸載時,安裝在該外部存儲介質上的程序將立刻被終止掉!
向后兼容性:
聲明了android:installLocation,但android:minSdkVersion小於8時,我們使用不低於Froyo的AVD進行編譯,這樣在低於Froyo的系統中android:installLocation將被忽略,而不低於Fro yo的系統中將使用我們指定的android:installLocation.
當我們的程序具有如下行為時我們不應該將程序安裝到外部存儲介質上
①Service
正在運行的服務將被終止,當外部存儲介質被重新加載時服務不會被重啟.
②Alarm Service
鬧鍾服務將被取消,開發者必須在外部存儲介質重新加載后重新注冊鬧鍾服務.
③Input Method Engines
輸入法將被換成系統輸入法,當外部存儲介質被重新加載后用戶可以通過系統設置來啟動我們的輸入法
④Live Wallpapers
我們的動態壁紙將被替換為默認的動態壁紙.外部存儲介質重載后,用戶可以更換回來.
⑤Live Folders
我們的動態文件夾將被移出.
⑥App Widgets
我們的小部件將被移出,通常只有系統重啟后我們的小部件才可用.
⑦Account Managers
使用AccountManager創建的賬戶將會消失,直至存儲介質被重新加載.
⑧Sync Adapters
只有外部存儲介質被重新加載時,我們的同步功能才可用
⑨Device Administrators
我們的DeviceAdminReceiver將會失效
⑩監聽開機結束事件
系統會在加載外部存儲介質之前發送ACTION_BOOT_COMPLETED廣播.因此安裝在外部存儲介質的程序將不能接受開機廣播.
通常,只要我們沒有使用上述的特性,我們就可以將我們的程序安裝到外部存儲介質上.例如,大的游戲程序.當我們的APK文件有幾M大時我們應該認真的考慮是否要將程序移動到外部存儲介質上以幫助用戶節省內存.
Google默認的PackageManager,會讀取應用AndroidManifest.xml的對應定義installLocation:
規則如下:
1.如果沒有定義安裝位置,表示安裝在手機內存上;
2. android:installLocation = "auto",先查看手機內存是否足夠,如果夠就安裝在手機內存上,不夠就安裝在T 卡上;
3. android:installLocation = "internalOnly",表示安裝在手機內存上;
4. android:installLocation = "preferExternal" ,表示安裝在 T 卡上;
如何在設置中增加“選取應用安裝位置”的功能,讓用戶選擇默認的安裝位置?
修改如下文件:
frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
做以下修改:
loadSetting(stmt, Global.SET_INSTALL_LOCATION, 0);
改為:
loadSetting(stmt, Secure.SET_INSTALL_LOCATION, 1);
loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 0);
改為:
loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 1);
這樣修改之后,在設置>應用中會出現“選取應用安裝位置”的功能,不過無論在這里選擇什么,對於應用中AndroidManifest.xml文件中聲明
android:installLocation = "internalOnly"
的,該apk 都會安裝到手機上,這樣做的好處是避免程序運行錯誤,因為定義android:installLocation = "internalOnly" 的 apk 一般要安裝到手機內存上才能正常運行。
Ref:
Android修改應用的默認安裝位置
http://www.th7.cn/Program/Android/201411/321349.shtml
android:installLocation簡析 - Lefter - 博客園
http://www.cnblogs.com/Lefter/archive/2012/03/07/2383962.html