運營商配置

Android 6.0 及更高版本包括特權應用程序向平台提供運營商特定配置的功能。此功能基於 Android 5.1 (Lollipop MR1) 中引入的UICC 運營商特權,允許運營商配置遠離靜態配置覆蓋,並使運營商和 OEM 能夠通過定義的接口向平台動態提供運營商配置。

正確簽名的運營商應用可以預加載到系統映像中、自動安裝或通過應用商店手動安裝。平台查詢該應用程序以提供設置配置,包括:

  • 漫遊/非漫遊網絡
  • 可視語音信箱
  • 短信/彩信網絡設置
  • VoLTE/IMS 配置

返回什麼值完全取決於運營商應用程序,並且可以根據通過平台傳遞給應用程序的詳細信息動態確定。

這種方法的主要好處是:

  • 動態配置- 支持非 MCCMNC 派生配置等概念,例如,移動虛擬網絡運營商 (MVNO) 或客戶選擇加入額外服務。
  • 支持通過任何渠道銷售的設備- 例如,公開市場電話可以通過從應用商店下載應用自動配置正確的設置。
  • 安全性 - 提供此配置的權限僅授予由運營商簽名的應用程序。
  • 定義的 API - 以前此配置主要存儲在框架內的內部 XML 覆蓋中,而不是通過公共 API。 Android 6.0 中的運營商配置 API 是公開的且定義明確。

這個怎麼運作

加載配置

此功能提供的運營商配置是一組鍵值對,可更改平台中各種與電話相關的行為。

通過按順序查詢以下組件來確定特定設備的值集:

  1. 運營商應用(這是可選的,但它是 Android 開源項目 (AOSP) 中現有配置之外的其他配置的推薦位置)
  2. 與系統映像捆綁的平台配置應用程序
  3. 默認值,硬編碼到框架中(相當於 Android 6.0 之前的行為)

平台配置應用

通用平台配置應用程序與系統映像捆綁在一起。此應用程序可以為常規運營商應用程序不提供的任何變量提供值。可以在以下位置找到平台配置應用程序(在 Android 6.0 中): packages/apps/CarrierConfig

此應用程序的目的是在未安裝運營商應用程序時提供一些針對每個網絡的配置,並且運營商/OEM 應僅在自己的映像中對其進行少量更改。相反,運營商應該為運營商定制提供單獨的運營商應用程序,允許通過應用程序商店等渠道分發更新。

如何向運營商應用授予特權

相關運營商應用程序必須使用 SIM 卡上的相同證書進行簽名,如UICC 運營商特權中所述。

將哪些信息傳遞給運營商應用程序

運營商應用程序提供了以下值,使其能夠動態決定要返回的值:

  • 中冶
  • 跨國公司
  • SPN
  • IMSI
  • GID1
  • GID2
  • 承運人編號

有關集成運營商 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 的類

  1. 覆蓋onLoadConfig以根據傳遞的service.carrier.CarrierIdentifier對象返回您希望提供的值。
  2. 在運營商配置可能隨時間變化的場景(例如,當用戶向其帳戶添加額外服務時)添加邏輯以調用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 設備