運營商配置

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

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

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

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

這種方法的主要優點是:

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

這個怎麼運作

加載配置

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

通過依次查詢以下組件來確定特定設備的值集:

  1. 運營商應用程序(這是可選的,但建議您在Android開放源代碼項目(AOSP)中進行其他配置,以進行其他配置)
  2. 與系統映像捆綁在一起的Platform config應用程序
  3. 默認值,已硬編碼到框架中(等同於Android 6.0之前的行為)

平台配置應用

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

此應用程序的目的是在未安裝運營商應用程序時提供每個網絡的配置,並且運營商/ OEM應該僅在自己的映像中對其進行最少的更改。取而代之的是,運營商應提供用於運營商自定義的單獨的運營商應用程序,從而允許通過諸如應用程序商店之類的渠道分發更新。

如何授予運營商應用程序特權

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

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

運營商應用提供了以下值,使它可以動態決定要返回的值:

  • 我的客戶中心
  • 跨國公司
  • SPN
  • IMSI
  • GID1
  • GID2
  • 運營商ID

有關集成運營商ID的更多信息,請參閱將運營商ID與CarrierConfig集成

加載運營商配置時

建立鍵值對列表的過程如下:

  • 加載SIM卡後(啟動或SIM卡熱插拔)
  • 當運營商應用手動觸發重新加載時
  • 運營商應用更新時

有關更多詳細信息,請參見android.service.carrier.CarrierService#onLoadConfig()參考。

使用配置

構建配置時,其中包含的值用於設置系統配置的各種值,包括:

  • 內部框架電話設置
  • SDK返回的配置值,例如,在SmsManager中
  • 應用程序設置,例如Dialer中的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設備