ממשקי API של eUICC

ב-Android 9, ממשקי ה-API לניהול פרופילים (ציבוריים ו-@SystemApi) זמינים דרך הכיתה EuiccManager. ממשקי ה-API של תקשורת eUICC זמינים דרך הכיתה EuiccCardManager (רק @SystemApi).

מידע על eUICC

ספקים יכולים ליצור אפליקציות ספקי שירות באמצעות EuiccManager כדי לנהל את הפרופילים, כפי שמוצג באיור 1. אפליקציות של ספקי סלולר לא חייבות להיות אפליקציות מערכת, אבל הן צריכות לקבל הרשאות של ספק הסלולר באמצעות פרופילים של eUICC. אפליקציית LPA (LUI ו-LPA לקצה העורפי) צריכה להיות אפליקציית מערכת (כלומר, כלולה בתמונת המערכת) כדי לקרוא ל-‎ @SystemApi.

טלפון Android עם אפליקציית ספק סלולרי ו-LPA של יצרן ציוד מקורי

איור 1. טלפונים עם Android עם אפליקציית ספק ו-LPA של יצרן ציוד מקורי

בנוסף ללוגיקה של קריאה ל-EuiccCardManager ושיחה עם eUICC, אפליקציות LPA חייבות ליישם את הפעולות הבאות:

  • לקוח SM-DP+‎ שמדבר עם שרת SM-DP+‎ כדי לאמת ולהוריד פרופילים
  • [אופציונלי] SM-DS כדי לקבל פרופילים פוטנציאליים נוספים שניתנים להורדה
  • טיפול בהתראות לשליחת התראות לשרת כדי לעדכן את מצב הפרופיל
  • [אופציונלי] ניהול שטחי אחסון, כולל מעבר בין הלוגיקה של eSIM לבין הלוגיקה של pSIM. האפשרות הזו אופציונלית אם בטלפון יש רק צ'יפ eSIM.
  • eSIM OTA

אפשר להתקין בטלפון Android יותר מאפליקציית LPA אחת, אבל רק אפליקציית LPA אחת יכולה להיות פעילה, על סמך העדיפות שמוגדרת בקובץ AndroidManifest.xml של כל אפליקציה.

שימוש ב-EuiccManager

ממשקי ה-API של LPA גלויים לכולם דרך EuiccManager (בתוך החבילה android.telephony.euicc). אפליקציה של ספק יכולה לקבל את המכונה של EuiccManager ולקרוא לשיטות ב-EuiccManager כדי לקבל את פרטי ה-eUICC ולנהל את המינויים (שנקראים פרופילים במסמכי GSMA RSP) בתור מכונות SubscriptionInfo.

כדי לבצע קריאות לממשקי API ציבוריים, כולל פעולות של הורדה, מעבר ומחיקה של מינויים, לאפליקציית הספק צריכות להיות ההרשאות הנדרשות. ספק הסלולר מוסיף את ההרשאות של הספק למטא-נתונים של הפרופיל. ה-API של eUICC אוכף את כללי ההרשאות של הספק בהתאם.

פלטפורמת Android לא מטפלת בכללי המדיניות של הפרופיל. אם כלל מדיניות מוצהר במטא-נתונים של הפרופיל, ה-LPA יכול לבחור איך לטפל בתהליך ההורדה וההתקנה של הפרופיל. לדוגמה, אפשר לאפשר ל-LPA של OEM של צד שלישי לטפל בכללי מדיניות באמצעות קוד שגיאה מיוחד (קוד השגיאה מועבר מה-LPA של OEM לפלטפורמה, ואז הפלטפורמה מעבירה את הקוד ל-LUI של OEM).

מידע על ממשקי API של כמה פרופילים מופעלים זמין במאמר כמה פרופילים מופעלים.

ממשקי API

ממשקי ה-API הבאים מופיעים במאמרי העזרה של EuiccManager ובEuiccManager.java.

אחזור מכונה (ציבורי)

הפונקציה מקבלת את המופע של EuiccManager דרך Context#getSystemService. פרטים נוספים זמינים במאמר getSystemService.

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

בודקים אם האפשרות מופעלת (גלויה לכולם)

בדיקה אם המינוי המוטמע מופעל. צריך לבדוק את זה לפני שמקבלים גישה לממשקי ה-API של LPA. פרטים נוספים זמינים במאמר isEnabled.

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

אחזור EID (גלוי לכולם)

הפונקציה מקבלת את ה-EID שמזהה את חומרת ה-eUICC. הערך הזה יכול להיות null אם ה-eUICC לא מוכן. למבצע הקריאה החוזרת צריכה להיות הרשאת ספק או ההרשאה READ_PRIVILEGED_PHONE_STATE. פרטים נוספים זמינים במאמר getEid.

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

אחזור EuiccInfo (גלוי לכולם)

קבלת מידע על eUICC. כאן מופיעה גרסת מערכת ההפעלה. פרטים נוספים זמינים במאמר getEuiccInfo.

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

מינוי להורדה (גלוי לכולם)

הורדת המינוי הנתון (שנקרא 'פרופיל' במסמכי GSMA RSP). אפשר ליצור את המינוי באמצעות קוד הפעלה. לדוגמה, אפשר לנתח קוד הפעלה מקוד QR. הורדת המינוי היא פעולה אסינכרונית.

למבצע הקריאה החוזרת צריכה להיות ההרשאה WRITE_EMBEDDED_SUBSCRIPTIONS או הרשאות ספק עבור המינוי היעד. פרטים נוספים זמינים במאמר downloadSubscription.

// 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 או הרשאות ספק למינוי המופעל הנוכחי ולמינוי היעד. פרטים נוספים זמינים במאמר switchToSubscription.

// 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);

החלפת מינוי עם יציאה (גלוי לכולם)

(זמין מ-Android 13) מעבר למינוי הנתון עם מדד היציאה שצוין (הפעלה). למבצע הקריאה החוזרת צריכה להיות ההרשאה WRITE_EMBEDDED_SUBSCRIPTIONS או הרשאות ספק לטלפון נייד עבור המינוי המופעל הנוכחי ומינוי היעד. פרטים נוספים זמינים במאמר switchToSubscription.

// 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 */, 0 /*portIndex*/, callbackIntent);

האם יציאת ה-SIM זמינה (גלויה לכולם)

public boolean isSimPortAvailable(int portIndex)

(זמין מ-Android 13) הפונקציה מחזירה אם אינדקס השקע המעביר זמין. יציאה זמינה אם לא מופעל בה מינוי, או אם לאפליקציה שבה מתבצעת הקריאה יש הרשאת ספק למינוי שמותקן ביציאה שנבחרה. פרטים נוספים זמינים במאמר isSimPortAvailable.

מחיקת מינוי (גלוי לכולם)

מחיקה של מינוי לפי מזהה מינוי. אם המינוי פעיל כרגע, הוא יושבת קודם. למבצע הקריאה החוזרת צריכות להיות הרשאות WRITE_EMBEDDED_SUBSCRIPTIONS או הרשאות ספק עבור המינוי היעד. פרטים נוספים זמינים במאמר deleteSubscription.

// 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);

מחיקה של כל המינויים (System API)

מחיקה של כל המינויים במכשיר. החל מגרסה Android 11, צריך לספק ערך enum של 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);

קבועים

רשימה של הקבועים public ב-EuiccManager מופיעה במאמר קבועים.