ממשקי API של eUICC

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

מידע על eUICC

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

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

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

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

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

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

שימוש ב-EuiccManager

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

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

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

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

ממשקי API

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

קבלת מכונה (ציבורי)

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

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

האפשרות 'מופעל (ציבורי)' מסומנת

בודקת אם המינוי המוטמע מופעל. צריך לסמן את התיבה הזו לפני שניגשים לממשקי LPA API. פרטים נוספים זמינים במאמר 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)

(זמין מגרסה 13 של Android) מחזירה את הערך true אם אינדקס היציאה להעברת נתונים זמין, אחרת מחזירה את הערך false. אפשר לבצע ניוד אם לא מופעלת מנוי או אם לאפליקציית השיחות יש הרשאה של ספק הסלולר לגבי המנוי שמותקן ביציאה שנבחרה. פרטים נוספים זמינים במאמר 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);

מחיקת כל המינויים (ממשק 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);

Constants

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