Google is committed to advancing racial equity for Black communities. See how.
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

eUICC API

在Android 9中,可通過類EuiccManager使用配置文件管理API(公共和@SystemApi)。 eUICC通信API(僅@SystemApi)可通過類EuiccCardManager

關於eUICC

運營商可以使用EuiccManager來管理運營商應用程序來管理配置文件,如圖1所示。運營商應用程序不必是系統應用程序,而是需要具有eUICC配置文件授予的運營商特權。 LPA應用程序(LUI和LPA後端)需要是系統應用程序(即,包含在系統映像中)才能調用@SystemApi。

帶有運營商應用程序和OEM LPA的Android手機

圖1.帶有運營商應用程序和OEM LPA的Android手機

除了調用EuiccCardManager並與EuiccCardManager對話的邏輯外,LPA應用程序還必須實現以下功能:

  • SM-DP +客戶端與SM-DP +服務器對話以認證和下載配置文件
  • [可選] SM-DS獲得更多潛在的可下載配置文件
  • 通知處理,用於將通知發送到服務器以更新配置文件狀態
  • [可選]插槽管理,包括在eSIM和pSIM邏輯之間切換。如果電話僅具有eSIM芯片,則這是可選的。
  • eSIM OTA

儘管An​​droid手機中可以存在多個LPA應用程序,但根據每個應用程序的AndroidManifest.xml文件中定義的優先級,只能選擇一個LPA作為實際的工作LPA。

使用EuiccManager

LPA API通過EuiccManager (在android.telephony.euicc包下)公開。載波應用程序可以得到的實例EuiccManager ,並調用方法EuiccManager得到的eUICC信息和管理訂閱(簡稱GSMA在RSP文件配置文件)作為的SubscriptionInfo實例。

要調用包括下載,切換和刪除​​訂閱操作在內的公共API,運營商應用必須具有所需的特權。運營商特權由移動運營商在配置文件元數據中添加。 eUICC API會相應地實施運營商特權規則。

Android平台不處理配置文件策略規則。如果在配置文件元數據中聲明了策略規則,則LPA可以選擇如何處理配置文件下載和安裝過程。例如,第三方OEM LPA可以使用特殊的錯誤代碼處理策略規則(錯誤代碼從OEM LPA傳遞到平台,然後平台將代碼傳遞給OEM LUI)。

蜜蜂

EuiccManager參考文檔EuiccManager.java可以找到以下API。

獲取實例(公共)

通過Context#getSystemService獲取EuiccManager的實例。

EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);

啟用檢查(公開)

檢查嵌入式訂閱是否已啟用。在訪問LPA API之前,應先進行檢查。

boolean isEnabled = mgr.isEnabled();
if (!isEnabled) {
    return;
}

獲取EID(公開)

獲取標識eUICC硬件的EID。如果eUICC尚未準備就緒,則該值為null。呼叫者必須具有運營商特權或READ_PRIVILEGED_PHONE_STATE權限。

String eid = mgr.getEid();
if (eid == null) {
  // Handle null case.
}

獲取EuiccInfo(公開)

獲取有關eUICC的信息。這包含操作系統版本。

EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();

下載訂閱(公共)

下載給定的訂閱(在GSMA RSP文檔中稱為“配置文件”)。可以從激活碼創建訂閱。例如,可以從QR碼解析激活碼。下載訂閱是異步操作。

調用方必須具有WRITE_EMBEDDED_SUBSCRIPTIONS權限,或者必須具有目標訂閱的運營商特權。

// Register receiver.
String action = "download_subscription";
BroadcastReceiver receiver =
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!action.equals(intent.getAction())) {
                    return;
                }
                resultCode = getResultCode();
                detailedCode = intent.getIntExtra(
                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
                    0 /* defaultValue*/);
                resultIntent = intent;
            }
        };
context.registerReceiver(
        receiver,
        new IntentFilter(action),
        "example.broadcast.permission" /* broadcastPermission*/, null /* handler */);

// Download subscription asynchronously.
DownloadableSubscription sub =
        DownloadableSubscription.forActivationCode(code /* encodedActivationCode*/);
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.downloadSubscription(sub, true /* switchAfterDownload */, callbackIntent);

切換訂閱(公共)

切換到(啟用)給定的訂閱。呼叫者必須具有WRITE_EMBEDDED_SUBSCRIPTIONS或具有當前啟用的訂閱和目標訂閱的運營商特權。

// Register receiver.
String action = "switch_to_subscription";
BroadcastReceiver receiver =
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!action.equals(intent.getAction())) {
                    return;
                }
                resultCode = getResultCode();
                detailedCode = intent.getIntExtra(
                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0 /* defaultValue*/);
                resultIntent = intent;
            }
        };
context.registerReceiver(receiver, new IntentFilter(action),
        "example.broadcast.permission" /* broadcastPermission*/, null /* handler */);

// Switch to a subscription asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.switchToSubscription(1 /* subscriptionId */, callbackIntent);

刪除訂閱(公開)

刪除具有訂閱ID的訂閱。如果訂閱當前處於活動狀態,則首先將其禁用。呼叫者必須對目標訂閱具有WRITE_EMBEDDED_SUBSCRIPTIONS或運營商特權。

// Register receiver.
String action = "delete_subscription";
BroadcastReceiver receiver =
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!action.equals(intent.getAction())) {
                    return;
                }
                resultCode = getResultCode();
                detailedCode = intent.getIntExtra(
                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
                    0 /* defaultValue*/);
                resultIntent = intent;
            }
        };
context.registerReceiver(receiver, new IntentFilter(action),
        "example.broadcast.permission" /* broadcastPermission*/,
        null /* handler */);

// Delete a subscription asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.deleteSubscription(1 /* subscriptionId */, callbackIntent);

清除所有訂閱(系統API)

擦除設備上的所有訂閱。從Android 11開始,您應該提供EuiccCardManager#ResetOption枚舉值,以指定是清除所有測試訂閱,運營訂閱還是兩種訂閱。調用者必須具有WRITE_EMBEDDED_SUBSCRIPTIONS權限。

// Register receiver.
String action = "delete_subscription";
BroadcastReceiver receiver =
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!action.equals(intent.getAction())) {
                    return;
                }
                resultCode = getResultCode();
                detailedCode = intent.getIntExtra(
                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
                    0 /* defaultValue*/);
                resultIntent = intent;
            }
        };
context.registerReceiver(receiver, new IntentFilter(action),
        "example.broadcast.permission" /* broadcastPermission*/,
        null /* handler */);

// Erase all operational subscriptions asynchronously.
Intent intent = new Intent(action);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.eraseSubscriptions(
        EuiccCardManager.RESET_OPTION_DELETE_OPERATIONAL_PROFILES, callbackIntent);

開始解析活動(公開)

啟動一項活動來解決用戶可解決的錯誤。如果操作返回EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR ,則可以調用此方法來提示用戶解決問題。對於特定錯誤,只能調用一次此方法。

...
mgr.startResolutionActivity(getActivity(), 0 /* requestCode */, resultIntent, callbackIntent);

常數

要在EuiccManager中查看public常量的EuiccManager ,請參見常量