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