開始使用 Android OBB 擴充程式檔(APK Expansion Files)
iOS 與 Android 目前針對體積較大的 App 程式(常見在遊戲)採用不一樣的限制性。iOS 直接開放了產品上限到 4GB 大小,但如果封裝容量超過 150MB ,便會強制只能在 wifi 環境中下載,此限制有可能會降低下載率,因此也是有相當多的遊戲採用了先安裝,再進行資源檔案下載的做法(順便偷渡 Hot-Fix)。而在 Android 中,如果透過 Google Play 商店來進行上架,則條件相對性的較為限制,主程式 APK 必須在 100MB 以下,若超過則必須先進行擴充程式檔的分裝,才能進行上架。
OBB の 廬山真面目
Android 擴充程式檔使用 OBB 為副檔名(Opaque Binary Blob)。官方提供了 jobb 工具可進行加密的封裝,但並無強制限制其格式。
Android 官方設計的擴充程式檔分為 Main 與 Patch 兩個檔案,每個推出的程式版本除了 APK 主程式之外,都能設定一個對應的 Main 以及一個 Patch 擴充程式檔。
Main 為主要的擴充程式檔,用來存放不易變動的資源;Patch 則是擴充修補程式檔,用來進行較有變動性的資源更新。雙檔案的設計,能有效降低更新程式時耗費的流量與系統負荷。兩個檔案各有 2GB 的大小限制。
[main|patch].<expansion-version>.<package-name>.obb
在命名時,以 main 或是 patch 開頭。後續接上 expansion-version,package name 與副檔名。expansion-version 為擴充程式檔的版本號,預設與程式的 versionCode 為對應,但是由於 Google Play 在上架新版本程式時,可選用舊版本的程式擴充檔延續使用,可降低更新的負擔,但卻有可能會造成程式 versionCode 是 N 但是擴充程式檔版本號卻是 <N 的狀況,需特別注意。
主程式如何牽手擴充程式檔
在 Google Play 商店中,當您準備提交新版本時,在上傳主程式 apk 檔案之後、送出提交之前,可於點擊右邊的 + 號來管理這個版本的資源檔。可選擇上傳新檔案,或是用現行版本的程式擴充檔。
在權限管理員面前,沒有自己人
在 Android 6.0 以上,引入了動態的權限管理架構,對於預設存放在外部空間(External Storage)的擴充程式檔案相當不友善,當然在預設的 Android implementation 中(4.4 以上),其實是有 bypass 讀取擴充程式檔需要權限的窘境,但是部分手機製造商基於各種不可描述的理由,支援度並不一致,導致部分手機又需要先取得權限才能讀取。
因此保險起見,在取用擴充程式檔時(通常是一開始),建議還是進行權限需求的判斷,或是直接進行取得 READ_EXTERNAL_STORAGE 權限的步驟:
- 在 manifest 中宣告權限使用
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- 確認是否有權限
ContextCompat.checkSelfPermission(AppActivity.getContext(),
Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED
- 嘗試取得權限
ActivityCompat.requestPermissions(AppActivity.getActivity(),
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_READ_EXTERNAL_STORAGE)
- onRequestPermissionsResult 判斷是否給予權限
if (requestCode == SystemHandler.REQUEST_READ_EXTERNAL_STORAGE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 取得
} else {
// 未取得
}
return;
}
醒醒吧,不一定會有擴充程式檔
沒錯,即使完成了 Play Store 完整的上架手續,使用者點擊按鈕下載了程式,Play Store 也不保證使用者會能夠將程式與擴充程式檔都下載下來,有時候只會下載了主程式(推測可能是當手機空間不充裕或是網路狀況較差時)。另外,由於擴充程式檔位於 External Storage,所以也可能被使用者或其他 APP 有意無意的刪除。因此透過程式判斷擴充程式檔是否存在,甚至進一步確認完整性,變成了一個必要的程序。
預設的資源檔案位置存放在以下位置:
<shared-storage>/Android/obb/<package-name>/
您可以透過 getExternalStorageDirectory() 來取得外部儲存位址,進而得知完整的路徑;或是直接以 getObbDir() 取得路徑。然後便可在路徑中存取程式擴充檔。
當擴充程式檔和妹妹一樣不存在
當擴充程式檔不存在時,您必須讓程式也能正常的啟動,並進行下載擴充檔的程序,這部分通常需要特別設計一個簡單的介面來進行。
如果您確定您的程式只會透過 Google Play 來發行,那您可以透過 Google Play Application Licensing 來向 Play Store 取得臨時的資源檔案下載鏈結。但是,如果您的程式會透過 APK 散播,或是上架到不支援 Google Play 的國家(你懂的),那則建議您將自行 Hosting 程式擴充檔。
實作下載器可以參考各遊戲引擎,或是參考原生 Android 的官方範例。
完整的起手式
當您使用了程式擴充檔,開啟程式時將會需要一套完整的確認和處理程序,包含了讀取權限確認與獲得、OBB 檔案存在確認、OBB 檔案完整性確認、寫入權限確認與獲得、OBB 下載器…等等。
老闆拖欠工資的起手式
相對於完整的起手式,在所有的確認與準備程序中,可先精簡到最少程序來進行測試開發:
- 省略權限的需求確認,統一都進行請求
- OBB 檔案存在確認,省略下載器,缺失檔案時直接引導使用者重新下載
- 直接省略完整性檢查
警告!這樣的做法非常不適合使用在能賺錢的上線產品中!當然,如果加班費沒發則另當別論。
超級好康,限時免費,歡迎下載 ~
《呆呆童書 — 我的家》衝到兒童榜第一名了!
感謝大家一起來支持台灣本土的原創內容
《呆呆童書 — 我的家》限時免費中!
慶祝雙平台上架,5/21~5/25 限時免費(原價90元),
之後還有更多故事會陸續更新,
快把好消息分享給親朋好友吧!
iOS 版本:https://bit.ly/DaiHomeA
Android 版本:https://bit.ly/DaiHomeG