Android 6.0 以上版本提供權限應用程式可為平台提供特定電信業者的設定。這項功能是以 Android 5.1 (Lollipop MR1) 中推出的 UICC 電信業者特權為基礎,可將電信業者設定移出靜態設定覆蓋層,並讓電信業者和原始設備製造商 (OEM) 透過定義的介面,動態地將電信業者設定提供給平台。
經過適當簽署的電信業者應用程式可預先載入至系統映像檔、自動安裝,或透過應用程式商店手動安裝。平台會查詢應用程式,為設定提供設定,包括:
- 漫遊/非漫遊網路
- 視覺化語音信箱
- 簡訊/多媒體訊息網路設定
- VoLTE/IMS 設定
決定要傳回哪些值完全取決於電信業者應用程式,且可根據透過平台傳遞至應用程式的詳細資訊,以動態方式傳回。
這種方法的主要優點如下:
- 動態設定:支援非 MCCMNC 衍生設定的概念,例如行動虛擬網路營運商 (MVNO) 或客戶選擇加入額外服務。
- 支援透過任何管道販售的裝置:舉例來說,您可以讓開放市場的手機從應用程式商店下載應用程式,自動使用正確的設定進行設定。
- 安全性:提供這項設定的權限僅適用於由電信業者簽署的應用程式。
- Defined API:之前這項設定主要儲存在架構的內部 XML 疊加層中,而非透過公用 API。Android 6.0 中的電信業者設定 API 為公開且定義明確。
運作方式
載入設定
這項功能提供的電信業者設定是一組鍵/值組合,可變更平台中的各種電話相關行為。
特定裝置的一組值是由依序查詢下列元件決定:
- 電信業者應用程式 (這是選用項目,但建議您在這個位置設定 Android 開放原始碼計畫 (AOSP) 以外的額外設定)
- 系統映像檔隨附的平台設定應用程式
- 預設值,已硬式編碼至架構中 (等同於 Android 6.0 之前的行為)
平台設定應用程式
系統映像檔會隨附通用平台設定檔應用程式。這個應用程式可為一般電信業者應用程式無法提供的任何變數提供值。您可以在 Android 6.0 中找到平台設定應用程式:packages/apps/CarrierConfig
這個應用程式的目的是在未安裝電信業者應用程式時,提供一些個別網路設定,電信業者/原始設備製造商應只在自家映像檔中對其進行最少的變更。相反地,電信業者應提供獨立的電信業者應用程式,以便進行電信業者自訂,並透過應用程式商店等管道發布更新。
如何授予電信業者應用程式特殊權限
驗證的電信業者應用程式必須使用 SIM 卡上的憑證簽署,如 UICC 電信業者權限一文所述。
傳送至電信業者應用程式的資訊
電信業者應用程式提供下列值,以便動態決定要傳回哪些值:
- MCC
- MNC
- SPN
- IMSI
- GID1
- GID2
- 電信業者 ID
如要進一步瞭解如何整合電信業者 ID,請參閱「 整合電信業者 ID 與 CarrierConfig」。
載入電信業者設定時
建立鍵/值組合清單的時間點如下:
- 載入 SIM 卡時 (啟動或 SIM 卡熱插拔)
- 當電信業者應用程式手動觸發重新載入作業時
- 電信業者應用程式更新時
詳情請參閱 android.service.carrier.CarrierService#onLoadConfig()
參考資料。
使用設定
建構設定時,系統會使用其中的值來設定系統設定的各種值,包括:
- 內部架構電話設定
- SDK 傳回的設定值,例如在 SmsManager 中
- 應用程式設定,例如撥號應用程式中的 VVM 連線值
設定鍵
鍵清單是 android.telephony.CarrierConfigManager
中公開 SDK 的一部分,無法在相同 API 級別中變更。請參閱下表,瞭解按鍵的摘要。
建構應用程式
建立應用程式
應用程式必須指定 Android 6.0 API 級別 (23)。
宣告覆寫 android.service.carrier.CarrierService 的類別
- 覆寫
onLoadConfig
,根據傳遞的service.carrier.CarrierIdentifier
物件傳回您要提供的值。 - 在可能隨時間變更的電信業者設定情況下 (例如使用者在帳戶中新增額外服務),請新增邏輯來呼叫
notifyConfigChangedForSubId
。
範例如下:
public class SampleCarrierConfigService extends CarrierService { private static final String TAG = "SampleCarrierConfigService"; public SampleCarrierConfigService() { Log.d(TAG, "Service created"); } @Override public PersistableBundle onLoadConfig(CarrierIdentifier id) { Log.d(TAG, "Config being fetched"); PersistableBundle config = new PersistableBundle(); config.putBoolean( CarrierConfigManager.KEY_CARRIER_VOLTE_AVAILABLE_BOOL, true); config.putBoolean( CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, false); config.putInt(CarrierConfigManager.KEY_VOLTE_REPLACEMENT_RAT_INT, 6); // Check CarrierIdentifier and add more config if needed… return config; } }
詳情請參閱 android.service.carrier.CarrierService
參考資料。
在資訊清單中命名類別
範例如下:
<service android:name=".SampleCarrierConfigService" android:label="@string/service_name" android:permission="android.permission.BIND_CARRIER_SERVICES"> <intent-filter> <action android:name="android.service.carrier.CarrierService"/></intent-filter> </service>
使用 SIM 卡上的相同憑證簽署應用程式
如要瞭解相關規定,請參閱 UICC 電信業者權限。
透過電信業者應用程式新增 APN
如要透過程式輔助方式從電信業者應用程式新增 APN (例如在 SIM 卡啟用期間),請使用 ContentResolver
API 將 APN 項目新增至由 URI android.provider.Telephony.Carriers.CONTENT_URI
識別的內容供應器。如要進一步瞭解內容 URI 的資料表結構,請參閱
Telephony.Carriers
。
詳情請參閱「APN 和 CarrierConfig」。
測試應用程式
建構設定應用程式後,您可以使用以下方式測試程式碼:
- 內含有效憑證簽名的 SIM 卡
- 搭載 Android 6.0 以上版本的裝置,例如 Android 裝置
設定電信業者服務功能
在 Android 中,電信業者服務功能會說明裝置是否支援語音、訊息和資料服務。電信業者可以在裝置層級和訂閱層級 (Android 15 以上版本) 指定裝置的電信業者服務功能。
裝置層級服務功能
裝置層級服務功能會在裝置製造時設定 (製造後無法變更)。電信業者可以透過下列系統資源覆寫指定裝置層級功能:
應用程式可透過下列 API 查詢裝置層級服務功能:
訂閱項目層級服務功能
對於搭載 Android 15 以上版本的裝置,電信業者可以在訂閱層級指定裝置的服務功能。如要指定訂閱層級服務功能,請使用
CarrierConfigManager.KEY_CELLULAR_SERVICE_CAPABILITIES_INT_ARRAY
API。舉例來說,如要指定訂閱項目只有資料,請將值設為
SubscriptionManager#SERVICE_CAPABILITY_DATA
。
應用程式 (預先載入的系統應用程式和第三方應用程式) 可以透過
SubscriptionInfo.getServiceCapabilities()
方法查詢指定訂閱項目的電信業者服務功能。這可讓應用程式開發人員根據訂閱項目的可用功能,自訂應用程式的使用者體驗。舉例來說,如果使用者訂閱的是數據專用的訂閱項目,應用程式開發人員可以確保撥號應用程式不允許撥打電話。
已淘汰的服務功能 API
從 Android 15 開始,Android 會同時提供裝置層級和訂閱層級的服務功能。因此,我們重新命名現有的裝置層級功能 API,以便讀者更容易理解。下表列出在 Android 15 中引入且已淘汰的 API 和重新命名的 API:
已淘汰 (Android 14 以下版本) | 對等 (Android 15 以上版本) |
---|---|
TelephonyManager.isVoiceCapable() |
TelephonyManager.isDeviceVoiceCapable() |
TelephonyManager.isSmsCapable() |
TelephonyManager.isDeviceSmsCapable() |