ב-Android 9, ממשקי API לניהול פרופילים (ציבוריים וגם
@SystemApi) זמינים דרך המחלקה EuiccManager
. תקשורת eUICC
ממשקי API (@SystemApi בלבד) זמינים דרך המחלקה EuiccCardManager
.
מידע על eUICC
ספקים יכולים ליצור אפליקציות ספק באמצעות EuiccManager כדי לנהל פרופילים, כפי שמוצג באיור 1. אפליקציות ספק לא חייבות להיות אפליקציות מערכת, אבל צריך להיות להן ספק הרשאות שהוענקו על ידי פרופילי eUICC. אפליקציית LPA (LUI ו-LPA) הקצה העורפי) צריך להיות אפליקציית מערכת (כלומר, כלולה בתמונת המערכת) כדי להפעיל @SystemApi.
איור 1. טלפונים עם Android עם אפליקציית ספק ו-OEM LPA
מלבד הלוגיקה של קריאה ל-EuiccCardManager
ושיחות עם eUICC, אפליקציות LPA
חייבים להטמיע את הדברים הבאים:
- לקוח SM-DP+ מדבר עם שרת SM-DP+ כדי לבצע אימות הורדת פרופילים
- [אופציונלי] SM-DS כדי לקבל עוד פרופילים אפשריים להורדה
- הטיפול בהתראות לשליחת התראות לשרת אל עדכון מצב הפרופיל
- [אופציונלי] ניהול יחידות קיבולת (Slot), כולל מעבר בין לוגיקת eSIM ללוגיקת pSIM. הפעולה הזו אופציונלית אם בטלפון יש רק שבב eSIM.
- eSIM OTA
בטלפון Android יכול להיות שיש יותר מאפליקציית LPA אחת, אבל רק אפליקציית LPA אחת יכולה להיות
להיות ה-LPA העבודה בפועל על סמך העדיפות שהוגדרה
את הקובץ AndroidManifest.xml
של כל אפליקציה.
שימוש ב-EuiccManager
ממשקי ה-API של LPA גלויים לכולם דרך EuiccManager
(במסגרת החבילה)
android.telephony.euicc
). אפליקציית ספק יכולה לקבל את המופע של EuiccManager
,
ולקרוא ל-methods ב-EuiccManager
כדי לקבל את המידע של ה-eUICC ולנהל
מנויים (שנקראים גם פרופילים במסמכי GSMA RSP) בתור
מכונות subscriptionInfo.
כדי להפעיל ממשקי API ציבוריים, כולל הורדה, החלפה ומחיקה של מינוי פעולות, לאפליקציית הספק צריכות להיות ההרשאות הנדרשות. ספק ההרשאות מתווספות על ידי ספק הסלולר במטא-נתונים של הפרופיל. ה-eUICC API אוכף את כללי ההרשאות של הספק בהתאם.
פלטפורמת Android לא מטפלת בכללי מדיניות הפרופיל. אם כלל מדיניות מצוין במטא-נתונים של הפרופיל, ה-LPA יכול לבחור איך לטפל תהליך ההורדה וההתקנה של הפרופיל. לדוגמה, ייתכן שמודל ה-LPA של ה-OEM של הצד השלישי לטיפול בכללי מדיניות באמצעות קוד שגיאה מיוחד (השגיאה הקוד מועבר מה-OEM LPA לפלטפורמה, ואז הפלטפורמה מעבירה את ל-OEM (LUI)).
למידע על ממשקי 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
עדיין לא מוכן. לפונקציית קריאה חוזרת (caller) צריכה להיות הרשאת ספק או
ההרשאה 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);
החלפת מינוי (ציבורי)
מעבר אל המינוי הנתון (הפעלתו). לפונקציית קריאה חוזרת (caller) צריך להיות
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);
מחיקת כל המינויים (ממשק API של המערכת)
מחיקה של כל המינויים במכשיר. הפעלה ב-Android
11, עליך לספק EuiccCardManager#ResetOption
טיפוסים בני מנייה (enum) כדי לציין אם למחוק את כל סוגי הבדיקה, התפעול או שני הסוגים
למינויים. למבצע הקריאה החוזרת צריכה להיות הרשאת 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
, אפשר לעיין
קבועים.